假设我有一个已编译的二进制程序,它运行并在屏幕上显示一些 GUI。我需要从 Win32 中的另一个程序访问它的工具栏,找到一个按钮并单击它。
我知道如何找到工具栏的 Hwnd,但我真的不知道如何枚举它上面的按钮。任何想法如何在 Win32 调用中做到这一点?
有没有像 Spy++ 这样能够在工具栏下显示按钮句柄的工具?Spy++ 不这样做。
谢谢
假设我有一个已编译的二进制程序,它运行并在屏幕上显示一些 GUI。我需要从 Win32 中的另一个程序访问它的工具栏,找到一个按钮并单击它。
我知道如何找到工具栏的 Hwnd,但我真的不知道如何枚举它上面的按钮。任何想法如何在 Win32 调用中做到这一点?
有没有像 Spy++ 这样能够在工具栏下显示按钮句柄的工具?Spy++ 不这样做。
谢谢
如果它是一个标准的 Win32 工具栏控件,那么您向工具栏发送一条TB_BUTTONCOUNT
消息以确定工具栏上有多少按钮,然后发送一条TB_GETBUTTON
消息以检索有关给定索引处的按钮的信息。
棘手的部分是TBBUTTON
接收按钮信息的结构需要在拥有工具栏的同一进程中分配,因此您必须:
GetWindowThreadProcessId()
以检索工具栏的进程 IDOpenProcess()
给HANDLE
那个过程VirtualAllocEx()
以分配该进程内部的结构TB_GETBUTTON
消息发送到工具栏,指定返回的指针VirtualAllocEx()
ReadProcessMemory()
将结构数据复制回您自己的进程,以便您可以根据需要对其进行处理VirtualFreeEx()
以释放分配的内存。单击该按钮时,它会向主窗口发送一条 WM_COMMAND 消息。模拟单击工具栏按钮不是很实用。更好的方法是使用 Spy++ 来查找 WM_COMMAND 消息及其参数。然后在你的程序中发送同样的 WM_COMMAND 消息。
AFAIR 你可以HWND
通过调用来获得一个工具栏按钮GetDlgItem
。第一个参数是HWND
工具栏的,第二个参数是按钮的 ID(你在它的TBBUTTON
结构中设置的那个)。您需要拥有按钮 ID 才能使用此方法。
=== 编辑 ===
除了@graham.reeds 建议的 EnumChildWindows,您还可以尝试SendInput
. 将目标窗口移动到前台,计算工具栏左上角的屏幕坐标(使用它的 HWND),加上目标按钮中间的 XY 偏移量,然后单击鼠标到该位置。(我成功地使用这种方法点击了在 IE 窗口中呈现的 Flash 和 Silverlight 对象。)