当前位置:首页 > 开发教程 > Web前端 >

窗口调整大小和移动

时间:2016-02-22 11:37 来源:互联网 作者:源码搜藏 收藏

在Windows 7中,当我打开WindowsExplorer(不是Internet Explorer)来查看和管理我的文件,在打开一个新的 窗口 ,它会记住上次关闭的窗口的大小,它通常是在屏幕上的位置重叠打开其他的资源管理器窗口: 我想始终打开资源管理器窗口大小相同,从不部分/全部

在Windows 7中,当我打开WindowsExplorer(不是Internet Explorer)来查看和管理我的文件,在打开一个新的窗口,它会记住上次关闭的窗口的大小,它通常是在屏幕上的位置重叠打开其他的资源管理器窗口:

窗口调整大小和移动

我想始终打开资源管理器窗口大小相同,从不部分/全部隐藏其他的资源管理器窗口:

窗口调整大小和移动

搜索(没有运气)的一些Windows7的选项来启用这些功能后,在一个雨夜,周六,我开始开发这个。(顺便说一句:如果你碰巧知道该怎么做同样的事情在一个更好的/更快的方式(即一些窗口设置或一些现有的实用程序),我想知道,谢谢。)

背景

它是使用一个简单的程序:

  • user32.dll中的功能来管理桌面窗口
  • 形式重写的WndProc来管理窗口消息并设置窗口的创建/激活/销毁壳钩(虽然只有创建活动将在这里使用;另一个是“未来用途”)
  • 一个互斥只允许一个运行的应用程序实例
  • 中的XML序列化配置对象,将写入和读取硬盘(在应用程序的同一个文件夹)

使用代码

代码的结构分为4个文件中,本文下面所述,从最不重要的开始:

  • WindowsApi.cs仅包含DllImports到Windows API的,尤其是:user32.dll中 ; 这其中并不需要任何进一步的解释
  • XmlHelper.cs是一个非常简单的裸骨抽象的XML序列化类。通过继承这一块,一个类可以保存为一个XML文件,而无需进一步的努力
  • Config.cs包含读取/写入磁盘配置
  • WindowsHookForm.cs ]是从未示出给用户的形式; 它只是提供给用从公司的WndProc,即可以轻松地勾到Windows外壳程序的事件,因此在打开窗口时做一些事情。

    它提供了三个事件:WindowCreatedEventWindowActivatedEventWindowDestroyedEvent,但在节目只有第一个被实际使用。

    在构造函数中,一个钩子注册:

    
    		
    private readonly int windowMessage_ShellHook;        
    public WindowsHookForm()
        {
        windowMessage_ShellHook = WindowsApi.RegisterWindowMessage("SHELLHOOK");
        WindowsApi.RegisterShellHookWindow(this.Handle);
        }

    然后,在WndProc中,消息被拦截,并且如果邮件ID是我们shellhook,则事件被上升(但仅限于上面提到的三个种):

    
    		
    public event Action<IntPtr> WindowCreatedEvent;  
    public event Action<IntPtr> WindowActivatedEvent;
    public event Action<IntPtr> WindowDestroyedEvent;
    
    protected override void WndProc(ref Message message)
        {
        if(message.Msg == windowMessage_ShellHook)
            {
            WindowsApi.ShellEvents shellEvent = (WindowsApi.ShellEvents)message.WParam.ToInt32();
            IntPtr windowHandle = message.LParam;
    
            switch(shellEvent)
                {
                case WindowsApi.ShellEvents.HSHELL_WINDOWCREATED:
                    if(WindowCreatedEvent != null)
                        WindowCreatedEvent(windowHandle);
                    break;
                case WindowsApi.ShellEvents.HSHELL_WINDOWACTIVATED:
                    if(WindowActivatedEvent != null)
                        WindowActivatedEvent(windowHandle);
                    break;
                case WindowsApi.ShellEvents.HSHELL_WINDOWDESTROYED:
                    if(WindowDestroyedEvent != null)
                        WindowDestroyedEvent(windowHandle);
                    break;
                }
            }
        base.WndProc(ref message);
        }
  • Program.cs中包含的程序的主要逻辑:

一旦启动,互斥允许只运行一个程序的实例,如果一个实例已经在运行,它亲切地询问是否要终止它(在这种情况下,它会调用RemoveAllInstancesFromMemory方法,即获取正在运行的进程与“ WindowsMover ”的名称,并杀死'时间)。

一旦启动,执行三个动作:首先是配置文件(如果存在的话)被读取(如果它不存在,那么它是书面使用默认值,这样你可能会发现它容易编辑)然后,在ArrangeExplorerWindows方法,在桌面上每一个现有的浏览器窗口被布置(即调整大小和移动); 最后驻留部分开始时,在那里WindowsHookFormWindowCreatedEvent在它定义被使用:


WindowsHookForm whf = new WindowsHookForm();
whf.WindowCreatedEvent += (data) => { ArrangeOneWindow(data); };

每当我们打开一个新窗口时,ArrangeOneWindow方法接收手柄刚刚创建的新窗口; 然后它会检查它是否是一个资源管理器窗口:


private static void ArrangeOneWindow(IntPtr newhandle)
    {
    List<windowInfo> wlist = GetActiveExplorerWindowsInfo();
    windowInfo newWindow = (from windowInfo wi in wlist
                            where wi.handle == newhandle
                            select wi).FirstOrDefault();
    if (newWindow != null)

并调整其大小和(可选)移动该窗口,使用WindowsAPI的功能做的工作,并配置数据来了解如何进行。

基本上,打开资源管理器窗口的任何时间,程序搜索的位置把它,开始在桌面的左上角,然后(在一排等)向右移动,直到一个合适的地方被发现; 一旦达到桌面的右侧,将相同的搜索被重复下面的一行。如果有太多的资源管理器窗口在桌面上打开,并没有空地方放新开一个,那么不采取任何措施,并会留在新窗口,在Windows7中决定把它。

配置文件


<width>346</width>
<height>460</height>
<startLeft>0</startLeft>
<startTop>0</startTop>
<left>0</left>
<top>0</top>
<horizontalGap>0</horizontalGap>
<verticalGap>0</verticalGap>
<doResizeOnly>false</doResizeOnly>
<canArrangeFixedPositions>true</canArrangeFixedPositions>
<canAppendToNext>false</canAppendToNext>
<ExcludedWindowsTitles>
  <string>Control Panel\All Control Panel Items\Personalization</string>
  <string>Shut Down Windows</string>
</ExcludedWindowsTitles>
<logFileName>WindowsMover.log</logFileName>
<doLogFile>false</doLogFile>
  • 宽度高度是默认的调整对调整窗口大小的尺寸。你知道,Explorer始终使用上次关闭的窗口大小作为默认为新的,所以在这些价值观的配置文件来覆盖由探险家设置的。
  • 两个间隙值应该是设置窗口之间的距离。
  • doResizeOnly如果不动的窗口。
  • canArrangeFixedPositions允许搜索即使有酒店旁边现有的窗口中没有自由的地方合适的位置(它的窗口映射,如果它被做开始砖startLeft家园理财,与defaut 宽度高度在第一行设置该的配置文件,然后搜索,如果这图块之一是免费的)
  • canAppendToNext如果真的是第一次尝试新的窗口附加到现有的浏览器窗口的右侧。
  • ExcludedWindowsTitles是 浏览器窗口标题的列表,我们不希望被安排
  • doLogFile如果属实,一个LOGFILENAME为每个窗口安排书面(主要用于调试)

就是这样。从结构上看,它是非常简单,它可以给一些有趣的见解新手程序员。

更新

收到一对夫妇的请求后,我已经改变了计划,以便它可以调整大小和移动各种窗口,不仅资源管理器窗口(所以我也改变了文章的标题)。为了让这个功能,我已经添加在配置文件中的一个新领域:


<ProcessesToWatch>
  <string>explorer</string>
</ProcessesToWatch>

这是一个字符串列表,你可以用别的东西代替“资源管理器”,或者只是添加到被监视新进程的名称。

例如,在配置文件中的以下XML:


<ProcessesToWatch> 
  <string>explorer</string> 
  <string>notepad</string> 
</ProcessesToWatch>

将使双方探险家和记事本打开的窗口程序的手表,它会调整大小/移动它们。

如果不确定进程名称列表中的使用,即暂时更改配置文件中的以下行:


<doLogFile>false</doLogFile>

,并且,在启动时,在日志文件中会有所有活动的进 程的名称,其中,所需要的人可以被拾取的列表。


Web前端阅读排行

最新文章