【vb.net】获取窗口控件句柄笔记

近期在做一个【在文件另存为窗口快速输入自定义路径字符串】的功能,一开始基本的思路是:

  • 研究分类各种软件的另存为窗口的控件类型、标题
  • 使用FindWindowFindWindowEx找出路径文本框和保存按钮的句柄
  • 使用SendMessageSendMessageEX将自定义路径字符串输入至上述的文本框,并后台模拟点击保存按钮。

基本的思路是没有问题的,如文本编辑器的另存为窗口,使用如下代码可以获取另存为窗口的文本框句柄:

myhwnd = FindWindow(vbNullString, "另存为")
myhwnd = FindWindowEx(myhwnd, 0&, "DirectUIHWND", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "FloatNotifySink", vbNullString) 
myhwnd = FindWindowEx(myhwnd, 0&, "ComboBox", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "Edit", vbNullString)

但各种各种的另存为窗口,目标文本框和按钮需要清楚父子窗口的控件类名,效率将变得十分低下,而且通用性也不强,例如ps的另存为窗口标题是“存储为”,而不是“另存为”,很多软件的文本框也不是这种非常具体的父子窗口。
因此急需使用另外一种高效的算法来遍历/枚举某一个桌面直接子窗口的所有控件,根据条件(类名标题)找出所需的控件。
【未完待续】
另,使用Spy++参看窗口和控件句柄。
‘--------------以上记录于2020/3/7 23:00--------------

在研究了一晚后,最终使用GetNextWindow遍历全部桌面直接子窗口,再使用EnumChildWindows配合回调函数EnumChildProcCallback实现【遍历桌面全部直接子窗口,再遍历某个子窗口的全部控件】,只要找到目标文本框和保存按钮,已基本实现目标功能【在文件另存为窗口快速输入自定义路径字符串】,而中间遇到几个小问题:

  • 隐藏的子窗口或者控件(Spy++显示为灰色)可以使用GetWindowLongWS_VISIBLE(&H10000000)判断过滤掉,提高效率。
  • 窗口和控件标题本来使用GetWindowText获取,但未知原因常出现获取不到,所以使用SendMessage获得。

至于另外一个子程序,获得最近打开的资源管理器路径,实现过程大致相同,放在下次笔记中。
‘--------------以上记录于2020/3/8 09:30--------------

这段时间主要忙于复工复产,所以没有太多时间更新。

上次讲到获得最近打开的资源管理器路径,由于【最近打开的资源管理器路径】其实是第一个CabinetWClass类窗口,层次关系清楚,所以没有使用上文所述的EnumChildWindows获得,可暴力使用以下代码获得:

myhwnd = FindWindow("CabinetWClass", vbNullString)
fhwnd = myhwnd
myhwnd = FindWindowEx(myhwnd, 0&, "WorkerW", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "ReBarWindow32", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "Address Band Root", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "msctls_progress32", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "Breadcrumb Parent", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "ToolbarWindow32", vbNullString)

如果myhwnd 为0,代表还存在另外一种可能,使用如下代码获得:

myhwnd = FindWindow("CabinetWClass", vbNullString)
fhwnd = myhwnd
myhwnd = FindWindowEx(myhwnd, 0&, "WorkerW", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "ReBarWindow32", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "Address Band Root", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "msctls_progress32", vbNullString)
myhwnd = FindWindowEx(myhwnd, 0&, "ComboBoxEx32", vbNullString)

至此
【在文件另存为窗口快速输入自定义路径字符串】功能得以实现,总结实现过程:

  1. 使用**Spy++**参看窗口和控件句柄,分析其层次关系、类名、标题。
  2. 使用GetNextWindow遍历全部桌面直接子窗口,再使用EnumChildWindows配合回调函数EnumChildProcCallback基本可以找到任何你想取得的控件、窗口句柄。
  3. 合理使用FindWindowFindWindowExSendMessageSendMessageEX等API获得类名、标题,模拟输入。


‘--------------以上记录于2020/3/24 22:49--------------

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
VB.NET获取所有窗口句柄可以使用 Windows API 函数 EnumWindows 和 GetWindowText、GetClassName。 EnumWindows 函数用于枚举所有顶层窗口,示例代码如下: ``` Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnumWindowsCallback, ByVal lParam As IntPtr) As Boolean Private Delegate Function EnumWindowsCallback(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean Private Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean ' 处理枚举到的窗口句柄 Return True ' 返回 True 继续枚举,返回 False 停止枚举 End Function EnumWindows(AddressOf EnumWindowsProc, IntPtr.Zero) ``` GetWindowText 函数用于获取窗口标题,示例代码如下: ``` Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer Dim title As StringBuilder = New StringBuilder(256) GetWindowText(hWnd, title, 256) ``` GetClassName 函数用于获取窗口类名,示例代码如下: ``` Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As IntPtr, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer Dim className As StringBuilder = New StringBuilder(256) GetClassName(hWnd, className, 256) ``` 注意:在使用 EnumWindows 函数枚举窗口时,需要在回调函数中处理枚举到的窗口句柄,可以通过 GetWindowText 和 GetClassName 函数获取窗口标题和类名。同时,需要注意窗口标题和类名可能包含中文字符,需要使用 StringBuilder 对象来存储。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值