怎样截获窗体中的按钮事件,当然按钮中不能出现代码,只是想在点击按钮时msgbox一个被点击按钮的id or name

解决方案 »

  1.   

    sub command1_click()
           msgbox command1.caption
    end sub
    哈哈,你能把问题说清楚点吗
      

  2.   

    子类处理参照api setWindowsLong(hwnd,GWL_WNDPROC,newAddress of WNDPROC)
      

  3.   

    窗体,在窗体上添加command1, command2, command3, picture1, command4代码
    Option Explicit
    Private Sub Form_Load()
        On Error Resume Next
        ProcOld = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        SetWindowLong hwnd, GWL_WNDPROC, ProcOld
    End Sub
    模块
    Option Explicit
    Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg 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 ProcOld As Long
    Public Const GWL_WNDPROC = (-4)
    Public Const WM_COMMAND = &H111Public Function WindowProc(ByVal hwnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Select Case iMsg
        Case WM_COMMAND
            Dim s As String * 255
            GetWindowText lParam, s, 255
            Dim i As Integer
            Dim ss As String
            For i = 1 To 255
                If Mid(s, i, 1) <> Chr(0) Then
                    ss = ss & Mid(s, i, 1)
                Else
                    Exit For
                End If
            Next i
            MsgBox "标题 = " & ss & " ID = " & wParam
        End Select
        WindowProc = CallWindowProc(ProcOld, hwnd, iMsg, wParam, lParam)
    End Function
    运行结果
    command1 id=5
    command2 id=4
    command3 id=3
    command1 id=1
    剩下的picturebox估计id=2了。
      

  4.   

    运行结果
    command1 id=5
    command2 id=4
    command3 id=3
    command4 id=1
    剩下的picturebox估计id=2了。
      

  5.   

    窗体,在窗体上添加command1, command2
    Option Explicit
    Private Sub Form_Load()
      HookForm Me
    End Sub
    Private Sub Form_Unload(Cancel As Integer)
     UnHookForm Me
    End Sub模块
    Option Explicit
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Declare Function SetClipboardViewer Lib "user32" (ByVal hwnd As Long) As Long
    Public Const GWL_WNDPROC = (-4)
    Dim PrevProc As Long
    Public Const BN_CLICKED = 0
    Public Const WM_COMMAND = &H111Public Sub HookForm(F As Form)
        PrevProc = SetWindowLong(F.hwnd, GWL_WNDPROC, AddressOf WindowProc)
    End Sub
    Public Sub UnHookForm(F As Form)
        SetWindowLong F.hwnd, GWL_WNDPROC, PrevProc
    End Sub
    Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
        If uMsg = WM_COMMAND And wParam \ 65536 = BN_CLICKED Then
            If lParam = Form1.Command1.hwnd Then
                MsgBox "you clicked button1"
            ElseIf lParam = Form1.Command2.hwnd Then
                MsgBox "you clicked button2"
            End If
        End If
    End Function
      

  6.   

    如果我用的是excel中的vba,那么如何拦截sheet中的按钮事件?
      

  7.   

    某个窗体:
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA"( _
        ByVal hwnd As Long, _
        ByVal lpString As String, _
        ByVal cch As Long) As LongPrivate Sub Form_Load()
        HookForm Me
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        UnHookForm Me
    End SubPublic Sub Interface(ByVal hButton As Long, ByVal wCtrlID As Integer)
        Dim sBtnName As String
        sBtnName = Space$(255)
        GetWindowText hButton, sBtnName, 255
        sBtnName = Trim$(sBtnName)
        Debug.Print String$(40, "+")
        Debug.Print "Interface "
        Debug.Print "Button Handle : " & FormatHexString(hButton)
        Debug.Print "Button ID     : " & wCtrlID
        Debug.Print "Button Name   : " & sBtnName
        Debug.Print String$(40, "+")
    End SubPrivate Function FormatHexString(ByVal Value As Long) As String
        FormatHexString = Hex$(Value)
        FormatHexString = String$(8 - Len(FormatHexString), "0") & FormatHexString
        FormatHexString = "&H" & FormatHexString
    End Function某模块
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
        ByVal hwnd As Long, _
        ByVal nIndex As Long, _
        ByVal dwNewLong As Long) As Long
    Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _
        ByVal lpPrevWndFunc As Long, _
        ByVal hwnd As Long, _
        ByVal Msg As Long, _
        ByVal wParam As Long, _
        ByVal lParam As Long) As LongPublic Const WM_DRAWCLIPBOARD = &H308
    Public Const GWL_WNDPROC = (-4)
    Public Const CBN_DROPDOWN = 7
    Public Const WM_COMMAND = &H111
    Public Const BN_CLICKED = 0Private mpfnPrevProc    As Long
    Private mHookedForm     As FormPublic Sub HookForm(F As Form)
        Set mHookedForm = F
        mpfnPrevProc = SetWindowLong(F.hwnd, GWL_WNDPROC, AddressOf WindowProc)
    End SubPublic Sub UnHookForm(F As Form)
        Set mHookedForm = Nothing
        SetWindowLong F.hwnd, GWL_WNDPROC, mpfnPrevProc
    End SubPublic Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        On Error Resume Next
        Dim wNotifyCode As Integer
        Dim wCtrlID     As Integer
        Select Case uMsg
        Case WM_COMMAND
            wNotifyCode = Int(wParam / &H10000)
            Select Case wNotifyCode
            Case BN_CLICKED
                wCtrlID = uMsg And &HFFFF
                CallByName mHookedForm, "Interface", VbMethod, lParam, wCtrlID
            End Select
        End Select
        WindowProc = CallWindowProc(mpfnPrevProc, hwnd, uMsg, wParam, lParam)
    End Function
      

  8.   

    我指的是excel中的sheet上的按钮
      

  9.   

    Excel不是很熟悉,如果你的按钮是通过VBA的Toolbox添加的,在VBA编辑器中就可以看到Command的事件。
      

  10.   

    我要的是excel开发面向对象的基类,所以要截获按钮事件而不是简单的填写事件,难点1:excel 中的sheet按钮,即toolbox添加的按钮没有hwnd;难点2:excel中的sheet没有hwnd,因为excel中sheet的message进程已交由excel处理而不是由windows管理。上述代码在vb中的确有效,可在excel中就显得无能为力了。
    望有相关api及excel经验的与我联系或跟帖:
    msn:[email protected]
    各位在vb控件版可以找到我
    谢谢
      

  11.   

    你用 SPY++ 截获这个消息吧
    FAN 的!
      

  12.   

    spy++当然拦截不到这个消息,因为一般程序按钮就是窗体,可excel不是,它的进程入口也不是windows的,而是excel的,这就好像网页中的按钮一样,你拦截不到他的存在,这并不是大多数人认为的是窗体模式的关系,而是实际windows和ie中并不存在这个按钮,它仅仅存在于虚拟机中。看来我的想法是没可能实现了。望大家参考一下我的观点,并不要走弯路了。
    交个朋友吧。三天后结帖
      

  13.   

    用SPY++是拦截不到这个消息,放弃!!
      

  14.   

    大致明白你问的是什么了,你应该在一开始就说明实现方法:
    在sheet按钮上点右建,粘贴下记代码
    Private Sub Worksheet_Activate()
    MsgBox me.name
    End Sub
    that`s ok!
      

  15.   

    就是子类化:SetWindowLong
    使当有消息时运行你的函数!!!!
      

  16.   

    HOOKhttp://www.csdn.net/cnshare/soft/11/11463.shtm