VB + Windows API 获取窗体上某控件的句柄
比起上一篇《VB + Windows API 获取窗口的句柄》,可能我们遇到更多的情况是需要获取指定窗体上某个控件的句柄。我自己在这方面经验比较少,昨天查了很多资料,实际上也没有看过什么比较好的解决方法,所以只好简单地说一下自己的大致思路了。
1. 如果我们事先知道该控件的类名或是标题,那么似乎可以使用 API 函数 FindWindow 来得到该控件的句柄。FindWindow 的声明如下(使用 VS 自带的工具 API Viewer可以查到声明代码):
一般我们只会用到其中一个参数,那么另外一个参数写为空字符串 vbNullString 就可以了。
2. 另外一种情况就是对该控件的类名或标题一无所知,或难以得到。对于这种情况,我想了一种比较笨的办法,如果有好的方法请高手不吝赐教:先使用 Spy++ 查看该窗体的结构,找到该控件在所属窗体上的层次和位置,然后在自己的程序中顺着这根藤摸过去。由于在一般的应用程序中,特定的控件在窗体上的位置一般是固定不变的,所以这个方法还是有效的。我在昨天写的程序中即应用了这种方法解决了如何获取特定控件句柄的问题。
至于如何知晓 Spy++ 的树状结构中看到的某控件就是你所要的目标控件,可以同时使用 Spy++ 和我昨天的那个查看鼠标光标处的窗口/控件句柄的小程序做对比,看该控件的句柄是否相同。注意:Spy++ 显示的句柄值为十六进制,可以在 VB 的小程序中使用 Hex 函数将十进制转为十六进制。
那么具体如何得到窗体上目标控件的句柄呢?我们先用一个叫做 GetTopWindow 的 API 函数得到窗体上第一个子窗体(控件也是窗体)的句柄,再按照刚才从 Spy++ 中看到的位置,使用 GetNextWindow 做一个循环就可以了。当然了,如果该控件的父窗体又是该窗体的一个子窗体,这种方法也是可以的。这两个 API 的声明如下:
Public Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, ByVal wFlag As Long) As Long
最后补充一点:只有当 GetNextWindow 函数的第二个参数为 2 时,才能返回下一个窗体的句柄。