VB 查找遊戲窗口句柄的方法

VB 查找遊戲窗口句柄的方法

信息來源:黑客代碼 編輯:root 瀏覽次數:191 加入時間:2010-3-20 1:40:47 評論(0)



 

[問題一,不能獲得窗口句柄]

一般尋找窗口句柄都是直接FindWindow吧,這樣是不行的,QQ三國在這些函數上做了一些處理.我來給大家說個萬能的方法吧,

對於GetWindowText方法遊戲就管不到了,可以配合使用GetWindow來枚舉所有的窗口,再判斷枚舉的窗口裏面是否含有遊戲窗口標題文字,

最後取其句柄就行了,下面我給段代碼,也給還有疑問的朋友一些幫助,嘻嘻!

Option Explicit
Private Declare Function GetDesktopWindow Lib "USER32" () As Long
Private Declare Function GetWindow Lib "USER32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function GetWindowText Lib "USER32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2

Public Function GetHandle(Title As String) As Long
   Dim tmp As String
   Dim hwnd As Long
   Dim lngProcID As Long
   Dim strTitle As String * 255     '//用來存儲窗口的標題
      '//取得桌面窗口
   hwnd = GetDesktopWindow()
   '//取得桌面窗口的第一個子窗口
   hwnd = GetWindow(hwnd, GW_CHILD)
   '//通過循環來枚舉所有的窗口
   Do While hwnd <> 0
        '//取得下一個窗口的標題,並寫入到列表框中
        GetWindowText hwnd, strTitle, Len(strTitle)
        If left$(strTitle, 1) <> vbNullChar Then
             tmp = left$(strTitle, InStr(1, strTitle, vbNullChar))
             If left(tmp, Len(Title)) = Title Then
                GetHandle=hwnd
             End If
        End If
        '//調用GetWindow函數,來取得下一個窗口
        hwnd = GetWindow(hwnd, GW_HWNDNEXT)
   Loop
End Function

直接調用GetHandle函數,然後傳一個窗口標題進去就可以獲得其窗口句柄了.

[問題二,不能後臺模擬按鍵]

一般發送按鍵消息都是SendMessage吧,也有用PostMessage的,一般人用這兩個函數都不成功,於是就走向硬件級的模擬按鍵,

其實這是錯誤的,這樣反而離目標越來越遠,使用普通的PostMessage就行了,有人問了,不是過濾了麼?

呵呵,讓我們重新來了解下鍵盤按鍵的流程吧,我也是初學的!

我們一般按下鍵盤,鍵盤會發送自身對應的掃描碼,然後傳遞給系統,在系統中由對應的鍵盤驅動來處理此消息,

但是不同的設備掃描碼有可能不一樣,爲了規範統一,於是出現了虛擬碼,驅動將掃描碼轉換成對應的虛擬碼後,

插入應用程序的消息隊列中,等待應用程序處理,這樣一個完整的流程就構成了,現在我們再來看看PostMessage的函數原型吧.

BOOL PostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam );

一個參數是窗口句柄,第一個問題中,我們已經得到.第二個參數是消息的類型,一般的有按鍵按下消息WM_KEYDOWN和按鍵彈起消息WM_KEYUP.

第三個參數和第四個參數的附加的,一般普通的對一個窗口發送按鍵消息就是:

     PostMessage wHandle, WM_KEYDOWN, KeyCode, 0 '按下某鍵

普通的行,但對於QQ三國來說就不行了,再看看上面的代碼有什麼被忽略了呢,細心的朋友發現了,缺少掃描碼,也就是第四個參數.

正常的按鍵都會有對應的掃描碼,如果沒有遊戲自然會認爲是假的,呵呵,因此我們還要構造一個掃描碼,怎麼構造呢,下面我給出完整的代碼:

Option Explicit
Private Declare Function PostMessage Lib "USER32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function MapVirtualKey Lib "USER32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long

Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const WM_CHAR = &H102

'//構造掃描碼
Private Function MakeKeyLparam(ByVal VirtualKey As Long, ByVal flag As Long) As Long
     Dim s As String
     Dim Firstbyte As String     'lparam參數的24-31位
     If flag = WM_KEYDOWN Then   '如果是按下鍵
         Firstbyte = "00"
     Else
         Firstbyte = "C0"        '如果是釋放鍵
     End If
     Dim Scancode As Long
     '獲得鍵的掃描碼
     Scancode = MapVirtualKey(VirtualKey, 0)
     Dim Secondbyte As String    'lparam參數的16-23位,即虛擬鍵掃描碼
     Secondbyte = right("00" & Hex(Scancode), 2)
     s = Firstbyte & Secondbyte & "0001"   '0001爲lparam參數的0-15位,即發送次數和其它擴展信息
     MakeKeyLparam = Val("&H" & s)
End Function

Public Function PostKey(wHandle As Long, KeyCode As Long) '//發送按鍵
     PostMessage wHandle, WM_KEYDOWN, KeyCode, MakeKeyLparam(KeyCode, WM_KEYDOWN) '按下某鍵
     PostMessage wHandle, WM_KEYUP, KeyCode, MakeKeyLparam(KeyCode, WM_KEYUP)    '釋放某鍵
End Function

上面就是一個完整的實現方法了,MakeKeyLparam是構造掃描碼,PostKey是發送按鍵消息,直接調用該函數就行了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章