在Ext中如何使窗体总在最前面(how to set a window always on top in Ext)

如,有如下窗体
var formWin = new Ext.Window({
    title: 'new window'
    ,width: 200
    ,height: 400
    ,html: 'This will be always on top'
});

现要使得这个窗体总是在其他窗体的前面,而且不影响其他窗体的使用(使用modal:true 选项可创建模态窗,但会冻结整个屏幕)。

国际惯例,先在 官方论坛 搜索一下,最快捷、准确的方法是 使用google来搜索。果然google没让人失望,第一页里就找到了 关键帖

他介绍的方法是修改Ext.WindowGroup 类(位于 widgets/WindowManager.js )的私有方法sortWindows(),改为:

    var sortWindows = function(d1, d2){
        return (!d1.alwaysOnTop && (d2.alwaysOnTop || !d1._lastAccess || d1._lastAccess < d2._lastAccess)) ? -1 : 1;
    };

这样就运行在初始化window时可以使用一个新的选项:alwaysOnTop ,如:
var formWin = new Ext.Window({
    title: 'new window'
    ,width: 200
    ,height: 400
    ,html: 'This will be always on top'
    ,alwaysOnTop: true
});

修改做的修改很少,但要hack源码肯定是最差的备选的方案。

而sortWindows 是个私有方法,js是无法从类外覆盖私有方法的,具体可参考
Tutorial:Application Layout for Beginners

因此尝试剑走偏锋,看看有没其他方案。查看 Ext.Window的API ,在 事件中的部分发现有两个事件是相关的:

activate : ( Ext.Window this )
Fires after the window has been visually activated via setActive.

deactivate : ( Ext.Window this )
Fires after the window has been visually deactivated via setActive.

一般来说,要使窗体总在最前方,应该是先触发了deactivate事件,因此在这时再主动设置为active,则可使窗体总保持激活状态也即是最前方了。

尝试如下:
formWin.on('deactivate', function(){
    this.setActive(true);
})

发现无效。阅读setActive的源码后知道原来setActive 只是用来设置是否显示窗体阴影是否显示。
Ext.Window 还有一个公共方法可以利用:
toFront() : Ext.Window
Brings this window to the front of any other visible windows

尝试用来代替setActive:
formWin.on('deactivate', function(){
    this.toFront();
})

发现也无效,查看源码发现Ext.Window.toFront() 实际是调用 Ext.WindowGroup.bringToFront(win),而在 Ext.WindowGroup.bringToFront(win) 里会判断 win 是否是当前窗口,如果是就不做任何操作,而在deactivate 里,当前窗口正是formWin,所以不会对他做任何操作。

在仔细跟读源码,原来决定窗体哪个在前面,是使用Ext.Window.setZIndex() 在设置窗体z轴(垂直于电脑屏幕的轴)的 zIndex值,越高的则越前。

知道底层实现原理就好办了,只要给formWin设置一个较大的zIndex值则可,尝试如:

formWin.on('deactivate', function(){
    this.setZIndex(9999);
})

点击其他窗体,formWin总是显示在最前方了。

但窗体的数量是不确定的,而Ext用来调整各个窗体的前后顺序是动态的,具体实现源码为:
    // private
    var orderWindows = function(){
        var a = accessList, len = a.length;
        if(len > 0){
            a.sort(sortWindows);
            var seed = a[0].manager.zseed;
            for(var i = 0; i < len; i++){
                var win = a[i];
                if(win && !win.hidden){
                    win.setZIndex(seed + (i*10));
                }
            }
        }
        activateLast();
    };

因此,也要根据当前窗体的数量来动态调整zIndex的值,代码改为:
formWin.on('deactivate', function(){
    var i=1;
    this.manager.each(function(){i++});
    this.setZIndex(this.manager.zseed + (i*10));
})

至此,可以说是已经完整实现了需求。

但有时窗体是直接new出来,没有赋值给临时变量,需要能在构造函数中设置。幸好Ext的接口丰富,有提供一个plugin的选项来提供扩展(如何写一个Ext的plugin: Plugins: Writing a Plugin),最终实现代码为:

var formWin = new Ext.Window({
    title: 'new window'
    ,width: 200
    ,height: 400
    ,html: 'This will be alwasy on top'
    ,plugins: new function(){
        this.init = function(win){
             win.on('deactivate', function(){
                    var i=1;
                    this.manager.each(function(){i++});
                    this.setZIndex(this.manager.zseed + (i*10));
                })
        }
    }
});


如果要实现重用,最好把plugin实现代码抽取为一个独立的plugin,如:
Ext.ux.WindowAlwaysOnTop = function(){
    this.init = function(win){
         win.on('deactivate', function(){
            var i=1;
            this.manager.each(function(){i++});
            this.setZIndex(this.manager.zseed + (i*10));
         })
    }
}

以后使用则很方便了:
var formWin = new Ext.Window({
    title: 'new window'
    ,width: 200
    ,height: 400
    ,html: 'This will be always on top'
    ,plugin: new Ext.ux.WindowAlwaysOnTop
});

效果如图
new window active:
new window deactive:
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如何设置让一个窗口总在最前(Exaware OnTop和PushPin)软件下载 Windows打开一个新窗口或切换任务时,原有的活动窗口就会被它所覆盖。不过,像Winamp等软件,却有一个能让自己的操作窗口总在最前的功能,非常实用。其实,只要你安装了像ExaWare OnTop和PushPin这样的免费小软件,也一样可以让任意Windows操作窗口总在前面,不让其他的窗口挡住它! 1.好用的ExaWare OnTop 下载并安装该软件后,双击桌面上的ExaWare OnTop 图标启动程序,我们看不到它的任何窗口界面,但在系统托盘上可以发现它的图标。单击该图标会弹出一个菜单,在这里列出了当前系统所有窗口的标题。要想让某个窗口总在前面,只要将鼠标移到相应的窗口标题项并点击鼠标(左右键均可)即可,如图所示。单击后该窗口标题前面的图标也相应地多了一个方框(如果没有图标则会显示一个对勾),表明该窗口已经设置成功。这时打开该窗口,再打开其他程序窗口,看看它是否一直总在其他窗口前面而不被遮住?怎么样,是不是有种高高在上的感觉?要想取消 OnTop 状态,只要重复一遍上面的操作就可以了。 看到这里你是不是有一个疑问:如果同时将两个窗口设置为总在最前(Always OnTop)的状态,那将会发生什么事情呢?其实也很简单,如果两个(或多个)窗口同时处于总在最前的状态,那说明它们的地位平等,这时先激活谁谁就在最上面(和设置前一样看待)。另外还有一个问题需要注意:如果需要退出该软件,建议点击系统托盘上的软件图标并选择菜单的“Exit and Restore”命令,这样在退出软件的同时可以恢复各个窗口的原始状态,以免给使用带来不便。 2.小巧的PushPin 相对于ExaWare OnTop 来说,PushPin 的体积更为小巧,只有区区的22KB 下载得到的是一个压缩包,由于它是一款绿色软件,我们只要直接将该压缩包解压缩到某个指定的目录下即可运行(主程序文件名为Pushpin.exe),同样看不到主程序窗口,只会发现系统托盘处多了一个图标。要想让某个操作窗口总在前面,只要在其标题栏上(在任务栏按钮上也可)单击鼠标右键并从弹出的菜单选择“Always on top”命令即可。要退出程序只需用鼠标右击系统托盘上的软件图标,并从弹出的菜单选择“Remove”命令即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值