如何取得一個窗體下的command button 的句柄?
窗體的句柄可以用findwindow 來取,但是如何取得command button的句柄?

解决方案 »

  1.   

    调用API函数:
    1.CheckDlgButton 函数
    函数功能:该函数改变按钮控制的选中状态。    函数原型:BOOL CheckDlgButton(HWNDhDlg,int nlDButton,UINT uCheck);    参数:    hDlg:指向含有该按钮的对话框的句柄。    nlDButton:标识要修改的按钮。    uCheck:给定该按钮的选中状态。该参数可取下列值,这些值的含义如下:    BST_CHECKED:设置按钮状态为己选中(checked)。    BST_INDETERMINATE:设置按钮状态变灰,表示不确定状态。只有在该按钮具有BS_3STATE或BS_AUTO3STATE样式时才能使用该值。    BST_UNCHECKED:设置按钮为未选中状态(unchecked)。    返回值:如果函数执行成功,返回值非零;如果函数失败,则返回值为零。若想获取更多错误信息,请调用 GetLastError函数。    速查;Windows NT:3.1 及以上版本;WindowS:95及以上版本;Windows CE:不支持:头文件:Winuser.h;库文件:user32.lib。
    -----------------------------------
    2.CheckRadioButton函数
     函数功能:该函数给一组单选按钮中的一个指定按钮加上选中标志,并且清除组中其他按钮的选中标志。    函数原型:BOOL CheckRadioButtoh(HWNDhDlg, intnlDFirstButton, intnlDLastBUtton, intnlDCheckButton);    参数:    hDlg:指向包含单选按钮的对话框的句柄。    nlDFirstButton:指定组中第1个单选按钮的标识符。    nlDLastButton:指定组中最后一个单选按组的标识符。    nlDCheckButton:指出要选中的那个单选按钮的标识符。    返回值:如果函数执行成功,返回值非零;如果失败,则返回零。若想获取更多错误信息,请调用GetLastError函数。    速查:Windows NT:3.1及以上版本;Windows:95及以广版本;Windows CE:1.0及以上版本;头文件:winuser.h;库文件:user32.lib。
    ----------------------
    3.IsDlgButtonChecked函数
    函数功能:该函数可以确定某个按钮控制是否有选中标志,或者三态按钮控制是否为灰色的、选中的、或两者都不是。    函数原型:UINT IsDlgButtonChecked(HWND hDlg,Int nlDBUtton);    参数:    hDlg:指向包含按钮控制的对话框。    nkDButtom:指定按钮控制的整型标识符。    返回值:使用BS_AUTOCHECKBOX、BS_AUTORADIOBUTTON、BS_AUTO3STATE、BS_CHECKBOX、BS_RADIOBUTION或BS_3STATE样式创建的按钮的返回值可以是如下值之一:    BST_CHECKED:表示按钮被选中。    BST_INDETERMINATE:表示按钮是灰色的,即为不确定状态(只有具有BS_3STATE或BS_AUTO3STATE样式的按钮才使用该值)。    BST_UNCHECKED:表示该按钮未选中(unckecked)。如果该按钮用其他任何样式,那么返回值为零。    速查:Windows NT:3.1及以11版本;Windows:95及以上版本;Windows CE:不支持:头文件:winuser.h;库文件:user32.lib。
      

  2.   

    hWndBtn = FindWindowEx(主窗口句柄, 0, "按钮类名", vbNullString)
      

  3.   

    参考网上现有的代码例子(SPY++的源码),可以用鼠标的压下和抬起来模拟窗口句柄的捕获,只用一个定位取得窗体句柄的函数(好像叫POINT什么什么的,你再查查)就可以实现按钮句柄的捕获了.
    如果你是写后台程序,又不想被使用者发现......那就参考2楼"严重睡眠不足啊^_^"的意见,先取得指定的程序窗口句柄,再根据自己测试后已经获得的按钮类名来取得按钮句柄.不过只能取得一个,之后得使用配套使用的函数取得同层的下一个按钮,一个个检查显示的文本,直到你找到需要的那个按钮.这种方法的缺陷是只能对固定的程序来进行捕获(比如某个著名的聊天软件),并且已经用SPY++之类的工具取得过某个按钮的句柄,知道了他的窗口类名(取窗体句柄用)和按钮类名(取按钮句柄用).这样软件的使用范围就受到了限制.
      

  4.   

    这两天正好找到这个在用,发给你看看 
     Private Type POINTAPI
              x   As Long
              y   As Long
      End Type
        
      Private Declare Sub GetCursorPos Lib "user32" (lpPoint As POINTAPI)
      Private Declare Function WindowFromPoint Lib "user32" (ByVal ptY As Long, ByVal ptX As Long) As Long
      Private Declare Function GetModuleFileName Lib "kernel32" Alias "GetModuleFileNameA" (ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long
      Private Declare Function GetWindowWord Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
      Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
      Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
      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 GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
      Private Declare Function SetWindowPos Lib "user32" (ByVal h&, ByVal hb&, ByVal x&, ByVal y&, ByVal cx&, ByVal cy&, ByVal f&) As Long
      Private Declare Function GetActiveWindow& Lib "user32" ()
        
      Const GWW_HINSTANCE = (-6)
      Const GWW_ID = (-12)
      Const GWL_STYLE = (-16)
      Const HWND_TOPMOST = -1
      Const HWND_NOTOPMOST = -2
      Const SWP_NOMOVE = 2
      Const SWP_NOSIZE = 1
      Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
      Const SW_MINIMIZE = 6
        
        
        
        
      Private Sub Form_Load()
        
      'This   centers   the   form.   I   usually   add   a   function   to   center
      'a   form   but   since   this   is   just   a   one-form   kinda   program,
      'I   just   put   it   here.
      Me.Left = (Screen.Width - Me.Width) / 2
      Me.Top = (Screen.Height - Me.Height) / 2
        
      'This   calls   the   StayOnTop   function.   You   can   find   this
      'particular   function   under   every   rock   and   in   just   about
      'every   book   on   Visual   Basic.   :)
      StayOnTop Me
        
      End Sub
        
        
      '使本窗体alwaysontop
      Private Sub StayOnTop(frm As Form)
        
      Dim success&
      success& = SetWindowPos(frm.hwnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
        
      End Sub
        
      Private Sub Timer1_Timer()
        
      'Among   the   things   I   played   with   was   removing   the   Hex   function   from
      'this   code.   Personally,   I   don't   care   much   about   Hex   values.   If   that
      'kind   of   thing   floats   *your*   boat,   pull   out   the   KB   article   and
      'change   it   back.   :)
        
      Dim ptCursor     As POINTAPI
      Dim sWindowText     As String * 100
      Dim sClassName     As String * 100
      Dim hWndOver     As Long
      Dim hWndParent     As Long
      Dim sParentClassName     As String * 100
      Dim wID     As Long
      Dim lWindowStyle     As Long
      Dim hInstance     As Long
      Dim sParentWindowText     As String * 100
        
      Dim sModuleFileName     As String * 100
      Static hWndLast     As Long
        
      Call GetCursorPos(ptCursor)     '   Get   cursor   position
      hWndOver = WindowFromPoint(ptCursor.x, ptCursor.y)         '   Get   window   cursor   is   over
      If hWndOver <> hWndLast Then           '   If   changed   update   display
      hWndLast = hWndOver       '   Save   change
      Cls   '   Clear   the   form
      Print "Window   Handle:   "; (hWndOver)       '   Display   window   handle
      Print "Focus:   "; GetActiveWindow()       'I   added   this
      r = GetWindowText(hWndOver, sWindowText, 100)           '   Window   text
      Print "Window   Text:   " & Left(sWindowText, r)
        
      r = GetClassName(hWndOver, sClassName, 100)           '   Window   Class
      Print "Window   Class   Name:   "; Left(sClassName, r)
        
      lWindowStyle = GetWindowLong(hWndOver, GWL_STYLE)         '   Window   Style
      Print "Window   Style:   "; (lWindowStyle)
        
      '   Get   handle   of   parent   window:
      hWndParent = GetParent(hWndOver)
        
      '   If   there   is   a   parent   get   more   info:
        
      If hWndParent <> 0 Then
      '   Get   ID   of   window:
      wID = GetWindowWord(hWndOver, GWW_ID)
      Print "Window   ID   Number:   "; (wID)
      Print "Parent   Window   Handle:   "; (hWndParent)
        
      '   Get   the   text   of   the   Parent   window:
      r = GetWindowText(hWndParent, sParentWindowText, 100)
      Print "Parent   Window   Text:   " & Left(sParentWindowText, r)
        
      '   Get   the   class   name   of   the   parent   window:
      r = GetClassName(hWndParent, sParentClassName, 100)
      Print "Parent   Window   Class   Name:   "; Left(sParentClassName, r)
      Else
      '   Update   fields   when   no   parent:
      Print "Window   ID   Number:   N/A"
      Print "Parent   Window   Handle:   N/A"
      Print "Parent   Window   Text   :   N/A"
        
      Print "Parent   Window   Class   Name:   N/A"
      End If
        
      '   Get   window   instance:
      hInstance = GetWindowWord(hWndOver, GWW_HINSTANCE)
        
      '   Get   module   file   name:
      r = GetModuleFileName(hInstance, sModuleFileName, 100)
      Print "Module:   "; Left(sModuleFileName, r)
      End If
        
        
        
      End Sub
     
      

  5.   


    請問像我這個例子,“按鈕類名”是不是“Button”?
      

  6.   

    還有,就是窗體下有幾個button,一個是“Yes”,一個是“OK”,如何區別呢?具體的是,其實是有兩個對話框,一個對話框是含有button"Yes",另一個對話框含有的button“Ok”,由於兩個對話框都是同樣的標題和類,所以無法用findwindow做出判斷。所以我只能根據不同的button來區別兩個對話框。
    而我要根據不同的對話框,作出不同的sendkeys操作。
      

  7.   

    建议思路:先得到窗体句柄然后EnumChildWindows,得到其下所有子窗体句柄(按钮也是窗体)上面过程中可以使用GetClassName过滤一下特定的类名.接着GetWindowText或SENDMESSAGE+GETTEXT,得到其标题~~根据标题的不同,或者子窗体的坐标,或者啥其它能区别这两个窗体的特征,去判断
      

  8.   

    模块代码Option ExplicitPublic Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Public Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    Public 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
    Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Public 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
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
    Public Const WM_PASTE = &H302
    Public Const WM_LBUTTONDOWN = &H201
    Public Const WM_LBUTTONUP = &H202
    Public Const WM_LBUTTONDBLCLK = &H203
    Public Const MK_LBUTTON = &H1
    Public Const WM_KEYDOWN = &H100
    Public Const WM_KEYUP = &H101
    Public Const WM_CHAR = &H102Public FormHwnd As LongPublic Function EnumChildProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
      
        Dim tmpStr As String * 255
        Dim retval As Long
        Dim ClassName As String
        Dim ObjText As String
        Dim r As Integer, i As Long
          
        r = GetClassName(hwnd, tmpStr, 255)
        i = InStr(tmpStr, Chr(0))
        ClassName = Left(tmpStr, i - 1)
        tmpStr = ""
        Select Case UCase(ClassName)
            Case "BUTTON"
                r = GetWindowText(hwnd, tmpStr, 255)
                i = InStr(tmpStr, Chr(0))
                ObjText = Left(tmpStr, i - 1)
                If ObjText = "确定" Then            End If
    '        Case "EDIT"
        End Select
        EnumChildProc = 1
    End Function窗体代码Option ExplicitPrivate Sub Command1_Click()
        FormHwnd = FindWindow(vbNullString, "打印到文件")'窗体标题
        EnumChildWindows FormHwnd, AddressOf EnumChildProc, ByVal 0&
    End Sub