高分求教功能设想:
1、捕捉窗體的句柄;
2、捕捉控件的句柄;
3、再向控件發送消息,如果是输入框,还需要自动输入相应数据。难点:
不知如何捕捉控件句柄,并区分它们。某程序启动时有三个步步骤,每个步骤都要输入两项信息,然后选择“下一步”或“上一步”到完成。如何做到自动输入相应数据并按相应按钮?(如何捕捉用户名输入框句柄及口令输入框句柄并区分它们?如何捕捉按钮句柄并区分目标按钮?)盼哥们帮帮忙,不胜感谢。

解决方案 »

  1.   

    1、捕捉窗體的句柄;
    用FindWindow:
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Longdim fHwnd as long
    fHwnd=FindWindow("","窗体标题")2、捕捉控件的句柄;
    用FindWindowEx循环查找:
    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 Long3、再向控件發送消息,如果是输入框,还需要自动输入相应数据。
    向控件發送消息用SendMessage
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long自动输入相应数据用SendMessageByString:
    Private Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As String) As Long
      

  2.   

    首先应该添加以下声明:
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) 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 SendMessageByString Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As String) As LongPrivate Const BM_CLICK = &HF5'然后使用以下代码:对按钮发送BM_Click消息点击;至于传入数据使用SendMessageByString,这个在此不多说了
    Dim hBtn As Long
    Dim hParent As Long
    hParent = FindWindow("按钮父窗口的类名", "按钮的父窗口名称")
    hBtn = FindWindowEx(hParent, Null, Null, "按钮的标题")
    SendMessage hBtn, BM_CLICK, 0, 0
      

  3.   

    "按钮父窗口的类名"  如何定?是与外部软件相关还是与编程工具相关?VB与VC及DELPHI相同吗?
      

  4.   

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) 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 SendMessageByString Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As String) As LongConst WM_LBUTTONDOWN = &H201
    Const WM_LBUTTONUP = &H202Private Sub Command1_Click()
    Dim winHwnd As Long
    Dim RetVal As Long
    winHwnd = FindWindow(vbNullString, "计算器")
    Dim hBtn As Long
    Dim lgNull As Long
    hBtn = FindWindowEx(winHwnd, lgNull, vbNullString, "5")'好像能找到按钮,但按不下。
    SendMessage hBtn, WM_LBUTTONDOWN, 0, 0 '按下
    SendMessage hBtn, WM_LBUTTONUP, 0, 0 '松开
    End Sub
    另:如果有两个输入框,又该如果区分它们呢?
      

  5.   

    //如果有两个输入框,又该如果区分它们呢?这两个输入框的区别可以从如下方面考虑:
    1)其text属性值是否相同(在循环中用findwindowex获取句柄并结合getwindowtext判断)
    2)其位置是否相同(可用api函数WindowFromPoint根据控件位置获取句柄)
    3)控件id肯定不同(可用api函数getdlgitem获取句柄)
      

  6.   

    晚生愚钝,还是不明,请多指教:
    1)好像能找到按钮,但按不下。为何?
    hBtn = FindWindowEx(winHwnd, lgNull, vbNullString, "5")'好像能找到按钮,但按不下。
    SendMessage hBtn, WM_LBUTTONDOWN, 0, 0 '按下
    SendMessage hBtn, WM_LBUTTONUP, 0, 0 '松开
    2)如果有两个输入框,又该如果区分它们呢?>>>这两个输入框的区别可以从如下方面考虑:其位置是否相同(可用api函数WindowFromPoint根据控件位置获取句柄),能否举个例子?
    不胜感谢!
      

  7.   

    简单写了一下,包含了查找窗口,对空间的一些操作,供参考:
    Option Explicit
    'Window Functions
    Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function GetActiveWindow Lib "user32" () As Long
    Private Declare Function GetDesktopWindow Lib "user32" () As Long
    Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, ByVal wFlag As Long) As Long
    Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
    Private Declare Function FlashWindow Lib "user32" (ByVal hwnd As Long, ByVal bInvert As Long) As Long
    Private Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function CloseWindow Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function RedrawWindow Lib "user32" (ByVal hwnd As Long, lprcUpdate As RECT, ByVal hrgnUpdate As Long, ByVal fuRedraw As Long) As Long
    Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
    Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long'Menu Functions
    Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
    Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function SetMenu Lib "user32" (ByVal hwnd As Long, ByVal hMenu As Long) As Long
    Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
    Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
    Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
    Private Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
    Private Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA" (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long
    'Other Functions
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function WindowFromPointXY Lib "user32" Alias "WindowFromPoint" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hwndNewParent As Long) As Long
    Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
    Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
    End Type
    Private Const WM_CLOSE = &H10
    ' SetWindowPos() hwndInsertAfter values
    Private Const HWND_TOP = 0
    Private Const HWND_BOTTOM = 1
    Private Const HWND_TOPMOST = -1
    Private Const HWND_NOTOPMOST = -2
    (待续)
      

  8.   

    接上面' GetWindow() Constants
    Private Const GW_HWNDFIRST = 0
    Private Const GW_HWNDLAST = 1
    Private Const GW_HWNDNEXT = 2
    Private Const GW_HWNDPREV = 3
    Private Const GW_OWNER = 4
    Private Const GW_CHILD = 5
    Private Const GW_MAX = 5
    ' ShowWindow() Commands
    Private Const SW_HIDE = 0
    Private Const SW_SHOWNORMAL = 1
    Private Const SW_NORMAL = 1
    Private Const SW_SHOWMINIMIZED = 2
    Private Const SW_SHOWMAXIMIZED = 3
    Private Const SW_MAXIMIZE = 3
    Private Const SW_SHOWNOACTIVATE = 4
    Private Const SW_SHOW = 5
    Private Const SW_MINIMIZE = 6
    Private Const SW_SHOWMINNOACTIVE = 7
    Private Const SW_SHOWNA = 8
    Private Const SW_RESTORE = 9
    Private Const SW_SHOWDEFAULT = 10
    Private Const SW_MAX = 10
    'Public hwnd As Long
    Public i As Long
    Public nhwnd As Long
    Public proname As String
    Public isok As StringPublic Function DrawWindowMenuBar(hwnd As Long) As Long
    DrawWindowMenuBar = DrawMenuBar(hwnd)
    End Function
    Public Function SetWindowMenu(hwnd As Long, hMenu As Long) As Long
    SetWindowMenu = SetMenu(hwnd, hMenu)
    End Function
    Public Function GetWindowMenu(hwnd As Long) As Long
    GetWindowMenu = GetMenu(hwnd)
    End Function
    Public Function SetText(hwnd As Long, sNewText As String) As Long
    SetText = SetWindowText(hwnd, sNewText)
    End Function
    Public Function GetText(hwnd As Long) As String
    Dim sText As String * 255
    Dim tmpLen As Long
    tmpLen = GetWindowText(hwnd, sText, 255)
    GetText = Left(sText, tmpLen)
    End Function
    Public Function GetWindowClassName(hwnd As Long) As String
    Dim sClass As String * 255
    Dim tmpLen As Long
    tmpLen = GetClassName(hwnd, sClass, 255)
    GetWindowClassName = Left(sClass, tmpLen)
    End Function
    Public Function GetTop(hwnd As Long) As Long
    Dim rc As RECT
    GetWindowRect hwnd, rc
    GetTop = rc.Top
    End Function
    Public Function GetLeft(hwnd As Long) As Long
    Dim rc As RECT
    GetWindowRect hwnd, rc
    GetLeft = rc.Left
    End Function
    Public Function GetWidth(hwnd As Long) As Long
    Dim rc As RECT
    GetWindowRect hwnd, rc
    GetWidth = rc.Right
    End Function
    Public Function GetHeight(hwnd As Long) As Long
    Dim rc As RECT
    GetWindowRect hwnd, rc
    GetHeight = rc.Bottom
    End Function
    Public Function GetFromXY(ByVal x As Long, ByVal Y As Long) As Long
    GetFromXY = WindowFromPointXY(x, Y)
    End Function
    Public Function Terminate(hwnd As Long)
    Terminate = SendMessage(hwnd, WM_CLOSE, 0, 0)
    End Function
    Public Function Minimize(hwnd As Long)
    Minimize = CloseWindow(hwnd)
    End Function
    Public Function Destroy(hwnd As Long)
    Destroy = DestroyWindow(hwnd)
    End Function
    Public Function SetWindowParent(hwnd As Long, hwndNewParent As Long) As Long
    SetWindowParent = SetParent(hwnd, hwndNewParent)
    End Function
    Public Function Flash(hwnd As Long) As Long
    Flash = FlashWindow(hwnd, 1)
    End Function
    Public Function BringToTop(hwnd As Long) As Long
    BringToTop = BringWindowToTop(hwnd)
    End Function
    Public Function Move(hwnd As Long, Left As Long, Top As Long, Width As Long, Height As Long, bRepaint As Boolean)
    MoveWindow hwnd, Left, Top, Width, Height, bRepaint
    End Function
    Public Function GetChildWindow(hWndParent As Long)
    GetChildWindow = GetWindow(hWndParent, GW_CHILD)
    End Function
    Public Function NextWindow(hwnd As Long) As Long
    NextWindow = GetNextWindow(hwnd, GW_HWNDNEXT)
    End Function
    Public Function DesktopWindow() As Long
    DesktopWindow = GetDesktopWindow
    End Function'Public Sub test()
    'hwnd = GetForegroundWindow
    'End Sub
    Public Function get_name() As String
    Dim hwnd As Long
    'Dim nhwnd As Long
    Dim Length As LongDim wntxt As String
    Dim rval As Long
    If i = 0 Then
    hwnd = GetForegroundWindow() 'Get the foreground window
    i = 1
    Else
    hwnd = nhwnd
    End If
    nhwnd = NextWindow(hwnd)
    Length = GetWindowTextLength(nhwnd) + 1
    wntxt = Space(Length)
    rval = GetWindowText(nhwnd, wntxt, Length) 'Get title bar text
    wntxt = Left(wntxt, Length - 1)
    get_name = wntxt
    End Function
    如果查找特定窗口,可以用下面的:
    Public Function checkname()
    Dim operini As New doini.do
    Dim m, n As Long
    Dim winname As StringDim pro As String
    Dim path As String
    Dim flag As Integer
    Dim windowname As String
    windowname = get_nameproname = "你的窗体名称"
    flag = InStr(1, windowname, proname)
    If flag <> 0 Then '找到合适窗口
        isok = "ok"
        'play nhwnd
        Exit Function
    End If
    If nhwnd = 0 Then '没找到合适窗口
        isok = "no"
        Exit Function
    End If
    End Function
      

  9.   

    晚生愚钝,还是不明,请多指教:
    1)好像能找到按钮,但按不下。为何?
    hBtn = FindWindowEx(winHwnd, lgNull, vbNullString, "5")'好像能找到按钮,但按不下。
    SendMessage hBtn, WM_LBUTTONDOWN, 0, 0 '按下
    SendMessage hBtn, WM_LBUTTONUP, 0, 0 '松开
    2)如果有两个输入框,又该如果区分它们呢?>>>这两个输入框的区别可以从如下方面考虑:其位置是否相同(可用api函数WindowFromPoint根据控件位置获取句柄),能否举个例子?
    不胜感谢!
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    先生,看题哟。。
      

  10.   

    按钮父窗口的类名与编程工具相关,
    SendMessage hBtn, WM_LBUTTONDOWN, 32, 0 '按下
    SendMessage hBtn, WM_LBUTTONUP, 32, 0 '松开
      

  11.   

    谢谢上面各位。
    但还有一个问题没解决:
    2)如果有两个输入框,又该如果区分它们呢?>>>这两个输入框的区别可以从如下方面考虑:其位置是否相同(可用api函数WindowFromPoint根据控件位置获取句柄),能否举个例子?
      

  12.   

    还有一个问题没解决:
    2)如果有两个输入框,又该如果区分它们呢?>>>这两个输入框的区别可以从如下方面考虑:其位置是否相同(可用api函数WindowFromPoint根据控件位置获取句柄),能否举个例子?
      

  13.   

    SendMessage hBtn, WM_LBUTTONDOWN, 32, 0 '按下
    SendMessage hBtn, WM_LBUTTONUP, 32, 0 '松开click好像模拟的不完全(可能是在下太笨,没搞出来)
    Private Sub Command1_Click()
    Dim winHwnd As Long
    Dim RetVal As Long
    winHwnd = FindWindow(vbNullString, "Form1")
    Dim hBtn As Long
    Dim lgNull As Long
    hBtn = FindWindowEx(winHwnd, lgNull, vbNullString, "Stop") 
    SendMessage hBtn, WM_LBUTTONDOWN, 32, 0 '按下SendMessage hBtn, WM_LBUTTONUP, 32, 0 '松开
    End SubPrivate Sub Command2_Click()
    MsgBox ("ok")
    End SubPrivate Sub Command2_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Form1.Caption = "already down"
    End SubPrivate Sub Command2_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Form1.Caption = "already up"
    End Sub我在form1上放置了一个用来测试的command2,command2.caption="Stop"
     测试结果可以确定两次sendmessage都是成功的
      

  14.   

    改为以下:
    SendMessage hBtn, WM_LBUTTONDOWN, 32, 0 '按下
    SendMessage hBtn, BM_SETSTATE, 1, 0
    SendMessage hBtn, WM_LBUTTONUP, 32, 0 '松开不过模拟单机一次之后,再执行就无效了。只能从启程序
      

  15.   

    //不过模拟单机一次之后,再执行就无效了。只能从启程序用sendmessage发送bm_click消息即可:
    Const BM_CLICK As Long = &HF5&....SendMessage hBtn, BM_CLICK, 0&, ByVal 0&
      

  16.   

    谢谢!
    上例是通过查找按钮的Caption进行区分,如果它是两个文本框,如何区分呢?