分享

VB 查找游戏窗口句柄的方法

 战神之家 2014-05-15

VB 查找游戏窗口句柄的方法

(2012-02-11 10:11:00)
标签:

it

[问题一,不能获得窗口句柄]

一般寻找窗口句柄都是直接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是发送按键消息,直接调用该函数就行了!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多