捕获窗口控件并修改其属性






4.94/5 (55投票s)
一个类似于 MS Spy++ 的 Spy 工具程序,允许您捕获窗口控件并修改其属性。有助于学习窗口句柄及其属性。
引言
我一直想有一个像 Microsoft Visual Studio 中的 Spy++ 这样的工具,但我希望该工具能够修改窗口控件。例如,有时我们需要在运行时启用程序中的一些无效控件。MS Spy++ 没有任何此类功能,所以我自己做了这个工具。
此程序可用于获取窗口句柄、标题、类名、样式和大小。此外,它还可以方便地在运行时加载时更改目标窗口控件的标题名称、样式和扩展样式。
该应用程序是一个不使用 MFC 的 Win32 项目。它通过 `WindowFromPoint()` user32 API 挂钩目标窗口。它有一个算法,通过巧妙地使用 `GetWindowRect()` 和 `GetWindow()` 在子窗口和父窗口中搜索,以捕获程序内的子窗口。它应用 `GetWindowLong()` 获取窗口属性,并应用 `SetWindowLong()` 修改它们。
挂钩目标窗口
我们可以通过 `WM_MOUSEMOVE` 鼠标事件挂钩目标窗口
case WM_MOUSEMOVE: if (bSeeking) { HWND hWindowUnderTheMouse; //HWND hWindowUnderTheMouseChild; points = MAKEPOINTS(lParam); point.x=points.x; point.y=points.y; ClientToScreen(hDlg,&point); hWindowUnderTheMouse = WindowFromPoint(point); if((hwndMain==hWindowUnderTheMouse)|| (hwndMain==GetParent(hWindowUnderTheMouse))) { break; } //------------------------------ hChildFound=NULL; SeekDumpWindow(hWindowUnderTheMouse,point); if((IsWindow(hChildFound))&&(hChildFound!=NULL)) { hWindowUnderTheMouse=hChildFound; } //------------------------------ if(hWindowUnderTheMouse != hSeekedWindow) { // FrameWindow(hSeekedWindow); hSeekedWindow = hWindowUnderTheMouse; FrameWindow(hSeekedWindow); // update the twin window strcpy(szSeekedWindow,"0x"); _itoa((DWORD)hSeekedWindow,szSeekedWindow+2,16); CharUpperBuff(szSeekedWindow+2,(DWORD)strlen(szSeekedWindow)); SetDlgItemText(hDlg,IDC_WINDOWHANDLE,szSeekedWindow); GetWindowInfo(hSeekedWindow); } } else { points = MAKEPOINTS(lParam); point.x=points.x; point.y=points.y; } break;
它通过搜索其父级和子级来查找正确的窗口目标,方法是使用程序内 `<DumpSeek.h>` 中定义的 `SeekDumpWindow()`。
修改目标窗口
通过其句柄修改目标窗口非常容易。如果您拥有窗口句柄,则可以通过 `GetWindowLong()` 和 `SetWindowLong()` 非常轻松地获取和更改样式,也可以通过使用 `SetWindowText()` 和 `SendDlgItemMessage()` 更改窗口标题。查看程序中的 `UpdateFlags()`,您将找到执行此操作以修改目标窗口的代码。
if(TopMost) { dwExtendedStyle|=WS_EX_TOPMOST; SetWindowPos(hHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); } else { dwExtendedStyle&=~WS_EX_TOPMOST; SetWindowPos(hHandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); } //---------------------------------------------- if(BACKdwID!=dwID) SetWindowLong(hHandle, GWL_ID, dwID); if(BACKdwStyle!=dwStyle)SetWindowLong(hHandle, GWL_STYLE, dwStyle); if(BACKdwExtendedStyle=dwExtendedStyle) SetWindowLong(hHandle, GWL_EXSTYLE, dwExtendedStyle); if(Visible) { ShowWindow(hHandle,SW_HIDE); ShowWindow(hHandle,SW_SHOW); } else { ShowWindow(hHandle,SW_SHOW); ShowWindow(hHandle,SW_HIDE); } UpdateWindow(GetParent(hHandle));
更改标题的代码取决于窗口控件的类型。要更改编辑控件和框控件的标题,必须使用 `SendDlgItemMessage()` 而不是其他窗口控件中的 `SetWindowText()`。
if((strstr(_szClassName,"EDIT")==NULL)&&(strstr(_szClassName,"BOX")==NULL)) { SetWindowText(hHandle,szTitle); } else { HWND hWndParent=GetParent(hHandle); SendDlgItemMessage(hWndParent,dwID,WM_SETTEXT,0,(LPARAM)szTitle); }
结论
我希望这个工具能够帮助刚接触这个领域的人了解窗口类及其操作。这将是制作窗口 Spy 工具和使用句柄的入门介绍。
最后,如果您能抽出时间提出您的想法、建议以及您可能在此程序中发现的任何错误,我将不胜感激。