在Windows 7中,当我打开WindowsExplorer(不是Internet Explorer)来查看和管理我的文件,在打开一个新的窗口,它会记住上次关闭的窗口的大小,它通常是在屏幕上的位置重叠打开其他的资源管理器窗口:
我想始终打开资源管理器窗口大小相同,从不部分/全部隐藏其他的资源管理器窗口:
搜索(没有运气)的一些Windows7的选项来启用这些功能后,在一个雨夜,周六,我开始开发这个。(顺便说一句:如果你碰巧知道该怎么做同样的事情在一个更好的/更快的方式(即一些窗口设置或一些现有的实用程序),我想知道,谢谢。)
它是使用一个简单的程序:
的WndProc
来管理窗口消息并设置窗口的创建/激活/销毁壳钩(虽然只有创建活动将在这里使用;另一个是“未来用途”)代码的结构分为4个文件中,本文下面所述,从最不重要的开始:
DllImports
到Windows API的,尤其是:user32.dll中 ; 这其中并不需要任何进一步的解释抽象
的XML序列化类。通过继承这一块,一个类可以保存为一个XML文件,而无需进一步的努力的WndProc
,即可以轻松地勾到Windows外壳程序的事件,因此在打开窗口时做一些事情。
它提供了三个事件:WindowCreatedEvent
,WindowActivatedEvent
和WindowDestroyedEvent
,但在节目只有第一个被实际使用。
在构造函数中,一个钩子注册:
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);
}
一旦启动,互斥允许只运行一个程序的实例,如果一个实例已经在运行,它亲切地询问是否要终止它(在这种情况下,它会调用RemoveAllInstancesFromMemory
方法,即获取正在运行的进程与“ WindowsMover
”的名称,并杀死'时间)。
一旦启动,执行三个动作:首先是配置文件(如果存在的话)被读取(如果它不存在,那么它是书面使用默认值,这样你可能会发现它容易编辑)然后,在ArrangeExplorerWindows
方法,在桌面上每一个现有的浏览器窗口被布置(即调整大小和移动); 最后驻留部分开始时,在那里WindowsHookForm
和WindowCreatedEvent
在它定义被使用:
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>
到真,并且,在启动时,在日志文件中会有所有活动的进 程的名称,其中,所需要的人可以被拾取的列表。
热门源码