问题是, FORM 如何识别出来这个自定义的消息呢?是不是一定用 APIs?

解决方案 »

  1.   

    很简单,可以实现,首先,建立一个模块,在里面声明GetWindowLong,SetWindowLong,CallWindowProc,SendMessage就可以,然后用GetWindowLong获取当前进程的消息句柄,然后用SetWindowLong交给自己编写的函数,注意:自己编写的函数形参必须与消息标准函数一样,然后在自编函数最后调用CallWindowProc将处理过的消息传递给系统,就一切OK了,这样可以成功收到所有系统发给本程序的消息,然后你可以用SendMessage发送自己的消息,消息为WM_USER+1即可!在自编函数中加以判断,IF Msg=WM_USER+1 then(处理自己的事件)
    如果不明白,可以UP,我为你解决!
      

  2.   

    感谢您使用微软产品。您可以用API函数SetWindowLong指定处理消息的窗口过程(window procedure)为自定义的函数WindowProc,捕获消息ID为WM_USER+1的自定义消息或系统消息。并且,为了保证窗口能正确的响应消息,需要保存原来默认的窗口过程并在自定义函数WindowProc中调用。如下例,在按钮事件中发送自定义消息,WindowProc捕获了窗口大小变化的系统定义消息和用户自定义的消息并显示用户自定义的消息参数wParam:在Moduel中加入以下代码,
    Option ExplicitPrivate Const GWL_WNDPROC = -4
    Public Const GWL_USERDATA = (-21)Public Const WM_SIZE = &H5Public Const WM_USER = &H400Private 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 GetWindowLong Lib "user32" Alias "GetWindowLongA" _
    (ByVal hwnd As Long, ByVal nIndex As Long) As LongPrivate Declare Function SetWindowLong Lib "user32" Alias _
      "SetWindowLongA" (ByVal hwnd As Long, _
       ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPublic Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As LongPublic Function Hook(ByVal hwnd As Long) As Long   Dim pOld As Long
    ‘指定自定义的窗口过程
       pOld = SetWindowLong(hwnd, GWL_WNDPROC, _
           AddressOf WindowProc)                                    
    ‘保存原来默认的窗口过程指针
       SetWindowLong hwnd, GWL_USERDATA, pOld
       Hook = pOldEnd FunctionPublic Sub Unhook(ByVal hwnd As Long, ByVal lpWndProc As Long)   Dim temp As Long
       'Cease subclassing.
       temp = SetWindowLong(hwnd, GWL_WNDPROC, lpWndProc)End SubFunction WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
       ByVal wParam As Long, ByVal lParam As Long) As Long  If uMsg = WM_SIZE Then
    ‘处理WM_SIZE消息
            MsgBox "SIZE"
        End If
    If uMsg = WM_USER + 1 Then
             MsgBox wParam
        End If
       Dim lpPrevWndProc As Long
                     ‘查询原来默认的窗口过程指针
      lpPrevWndProc = GetWindowLong(hw, GWL_USERDATA)‘调用原来的窗口过程
      WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, _
               wParam, lParam)
    End Function在Form中加入以下代码:
    Dim wParam As Long
    Dim lParam As Long
    Dim lResult As LongPrivate Sub Command1_Click()
    wParam = 12345
    lResult = SendMessage(Me.hwnd, WM_USER + 1, wParam, lParam)
    End Sub
    Private Sub Form_Load()
       Me.Tag = Hook(Me.hwnd)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
       Unhook Me.hwnd, Me.Tag
    End Sub
    在VB中用自定义过程捕获并处理消息的详细信息和例子请参考:
    Q170570 HOWTO: Build a Windows Message Handler with AddressOf in Visual
    http://support.microsoft.com/support/kb/articles/q170/5/70.asp
    Q168795 HOWTO: Hook Into a Window's Messages Using AddressOf
    http://support.microsoft.com/support/kb/articles/q168/7/95.asp
    - 微软全球技术中心 VB技术支持本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款
    (http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
    为了为您创建更好的讨论环境,请参加我们的用户满意度调查
    (http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。