背景
我目前正在尝试开发一些测试软件,需要在桌面上通知窗口创建和激活事件,响应这些并遍历窗口小部件树,以便读取这些窗口上的所有可用文本。这需要在32位和64位以及理想情况下从XP向上(叹气)工作,但肯定是7以上。
我做得很远
我已经为SetWindowsHookEx()
条消息注册了一个WH_CBT
样式系统挂钩,我专门处理HCBT_ACTIVATE
和HCBT_CREATEWND
个事件。钩子是在DLL中完成的,并且有一个控制它的钩子程序。该程序可用并运行32位和64位(因为HCBT
消息似乎不会被路由回到不同体系结构(32/64位)的挂钩过程,这与键盘消息不同)。该软件全部用非托管C ++代码编写,即不依赖于CLI,该程序是一个控制台应用程序。
当我收到上述两个事件中的任何一个时,我会使用给定的EnumChildWindows()
句柄调用HWND
并在每个窗口调用GetWindowText()
。结果目前根据PID写入单个日志文件。
这一切都按预期工作,但到目前为止......
问题
如果我跑起来说MSVS我可以看到顶级的东西,甚至是`你确定你想要那样做的文本内容'简单的警告对话框,但对于选项对话框,我得到的是OK和Cancel窗口小部件以及一些无标题窗口。
阅读本文我相信原因是我看到了从旧学校Win32 API小部件到WPF控件小部件的转换。
假设/需求
SetWindowsEx()
样式钩子,这必须是非托管代码(即,您可以在一些随机进程内快速启动CLI并使用托管代码)。问题
HWND
句柄转发到另一个进程,比如通过WM_COPYDATA
和一个隐藏窗口,这实际上是一个托管进程,然后可以代表注入DLL,访问Win32小部件,在需要时切换到WPF?我的研究似乎表明这不可能...... 最后我应该说我是背景的Unix / Linux GUI /系统/内核软件工程师,如果上面的内容看起来很基本,请提前道歉,但我无法找到这个特定用例的答案。它也是我的第一个MS-Windows程序!
非常感谢,
约翰。
答案 0 :(得分:0)
如果您只需要获得窗口创建和激活事件的通知 - 最好的方法是使用
SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_DESTROY, 0, WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
并在WinEventProc中查找idObject == OBJID_WINDOW&& idChild == CHILDID_SELF 绝对不依赖于WPF,甚至可以从低完整性流程开始工作。另外 - 你不需要在这里调用EnumChildWindows,因为通知所有窗口的工作。不需要单独的dll 32 / 64bits,不需要注入, 例如
VOID CALLBACK WinEventProc( HWINEVENTHOOK /*hWinEventHook*/, DWORD event,
HWND hwnd, LONG idObject, LONG idChild, DWORD /*dwEventThread*/,
DWORD /*dwmsEventTime*/)
{
if (event == EVENT_OBJECT_CREATE)
{
if (idObject == OBJID_WINDOW && idChild == CHILDID_SELF)//
{
WCHAR sz[256], cn[256];
if (!GetWindowText(hwnd, sz, RTL_NUMBER_OF(sz)))
{
*sz = 0;
}
if (!GetClassNameW(hwnd, cn, RTL_NUMBER_OF(cn)))
{
cn[0]='?', cn[1]=0;
}
DbgPrint("%p <%S>::<%S>\n", hwnd, cn, sz);
}
}
}
从MSVS下一个输出的选项对话框:
0000000000040900 <#32770>::<>
00000000000408FC <tooltips_class32>::<>
00000000000408FE <SysTreeView32>::<>
00000000000408FA <Button>::<Show &all settings>
00000000000408F8 <Button>::<OK>
00000000000408F6 <Button>::<Cancel>
00000000000408F4 <Button>::<&Reset>
00000000000508DC <Button>::<Apply>
00000000000508DA <SysTabControl32>::<>
000000000003090A <#32770>::<>
000000000003090C <Button>::<&Reuse current document window, if saved>
000000000003090E <Button>::<&Detect when file is changed outside the environment>
0000000000030910 <Button>::<Auto-&load changes, if saved>
0000000000030912 <Button>::<Allo&w editing of read-only files; warn when attempt to save>
0000000000030914 <Button>::<&Open file using directory of currently active document>
0000000000030916 <Button>::<Chec&k for consistent line endings on load>
00000000001F08AA <Button>::<Displa&y warning when global undo will modify edited files>
0000000000260336 <Button>::<&Show Miscellaneous files in Solution Explorer>
00000000001D08A6 <Static>::<items saved in the &Miscellaneous files project>
00000000001208A4 <Edit>::<>
00000000001408AE <Button>::<Save documents as &Unicode when data cannot be saved in codepage>