office交流網(wǎng)--QQ交流群號(hào)及微信交流群

Access培訓(xùn)群:792054000         Excel免費(fèi)交流群群:686050929          Outlook交流群:221378704    

Word交流群:218156588             PPT交流群:324131555

微信交流群(請(qǐng)用微信掃碼)

        

VBA調(diào)用API獲取其它程序的窗口的句柄

2017-09-21 08:00:00
網(wǎng)絡(luò)
轉(zhuǎn)貼
18076

一般可以使用Windows API函數(shù) FindWindow


我們需要獲取指定窗體上某個(gè)控件的句柄,思路如下

1. 如果我們事先知道該控件的類名或是標(biāo)題, 可以使用 API 函數(shù) FindWindow 來(lái)得到該控件的句柄。FindWindow 的聲明如下(API Viewer可以查到聲明代碼):
   Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  一般我們只會(huì)用到其中一個(gè)參數(shù),那么另外一個(gè)參數(shù)寫為空字符串 vbNullString 就可以了。

2. 另外一種情況就是對(duì)該控件的類名或標(biāo)題一無(wú)所知,或難以得到。對(duì)于這種情況,我想了一種比較笨的辦法,如果有好的方法請(qǐng)高手不吝賜教:先使用 Spy++ 查看該窗體的結(jié)構(gòu),找到該控件在所屬窗體上的層次和位置,然后在自己的程序中順著這根藤摸過(guò)去。由于在一般的應(yīng)用程序中,特定的控件在窗體上的位置一般是 固定不變的,所以這個(gè)方法還是有效的。我在昨天寫的程序中即應(yīng)用了這種方法解決了如何獲取特定控件句柄的問(wèn)題。

 至于如何知曉 Spy++ 的樹(shù)狀結(jié)構(gòu)中看到的某控件就是你所要的目標(biāo)控件,可以同時(shí)使用 Spy++ 和我昨天的那個(gè)查看鼠標(biāo)光標(biāo)處的窗口/控件句柄的小程序做對(duì)比,看該控件的句柄是否相同。注意:Spy++ 顯示的句柄值為十六進(jìn)制,可以在 VB 的小程序中使用 Hex 函數(shù)將十進(jìn)制轉(zhuǎn)為十六進(jìn)制。

那么具體如何得到窗體上目標(biāo)控件的句柄呢?我們先用一個(gè)叫做 GetTopWindow 的 API 函數(shù)得到窗體上第一個(gè)子窗體(控件也是窗體)的句柄,再按照剛才從 Spy++ 中看到的位置,使用 GetNextWindow 做一個(gè)循環(huán)就可以了。當(dāng)然了,如果該控件的父窗體又是該窗體的一個(gè)子窗體,這種方法也是可以的。這兩個(gè) API 的聲明如下:

Public Declare Function GetTopWindow Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, ByVal wFlag As Long) As Long

最后補(bǔ)充一點(diǎn):只有當(dāng) GetNextWindow 函數(shù)的第二個(gè)參數(shù)為 2 時(shí),才能返回下一個(gè)窗體的句柄。



Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Dim x ‘用 FindWindow 和 FindWindowEx 找到控件窗口。 ’然后用 SendMessage或PostMessage 發(fā)送消息。 Private Sub Command1_Click()
    AppActivate x  '激活其它窗口
    Dim NotepadHwnd As Long, hwnd As Long
    NotepadHwnd = FindWindow("notepad", vbNullString) '查找notepad記事本窗口
    hwnd = FindWindowEx(NotepadHwnd, 0, "Edit", vbNullString)    '得到窗口類名為Edit的窗口句柄 
    a = PostMessage(hwnd, WM_KEYDOWN, &HBB, 0&)  '模擬鍵按下事件
''-- 將Text1中的文本粘貼到記事本
        'VB.Clipboard.SetText Text1.Text
        'SendMessage TemphWnd, WM_PASTE, 0, ByVal 0&
        '把記事本的內(nèi)容設(shè)置為Text1中的文本
        SendMessage hwnd, WM_SETTEXT, 0, ByVal CStr(Text1.Text)
End Sub
分享
文章分類
聯(lián)系我們
聯(lián)系人: 王先生
Email: 18449932@qq.com
QQ: 18449932
微博: officecn01
移動(dòng)訪問(wèn)