我在程序A中给程序B传递一个自定义消息,
但是B中怎么才能接收到呢?
代码如下:
A程序:
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private 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
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Const WM_CLOSE = &H10
Const WM_QUIT = &H12
Dim Handle As Long
Dim pid As Long ' 储存进程标识符( Process Id )
Dim n As Integer
Dim wParam As Long
Dim lParam As Long
Dim lResult As LongPrivate Sub Command1_Click()
    '得到应用程序句柄
    Handle = FindWindow(vbNullString, "test1")'test1是B程序的标题
    wParam = 12345
    lResult = SendMessage(pid, WM_USER + 1, wParam, Me.hwnd)
End SubB程序如下:
B的Form中
Option Explicit
    Dim wParam As Long
    Dim lParam As Long
    Dim lResult As Long
    Private Sub Form_Load()
      Me.Tag = Hook(Me.hwnd)
    End Sub
B的模块中 
Option Explicit      Private Const GWL_WNDPROC = -4
      Public Const GWL_USERDATA = (-21)
      Public Const WM_SIZE = &H5
      Public Const WM_USER = &H400
      Public PrevWndProc 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 GetWindowLong Lib "user32" Alias "GetWindowLongA" _
      (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias _
      "SetWindowLongA" (ByVal hwnd As Long, _
        ByVal nIndex As Long, ByVal dwNewLong As Long) 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 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 = pOld
    End Function    Public Sub Unhook(ByVal hwnd As Long, ByVal lpWndProc As Long)
      Dim temp As Long
      '注释:Cease subclassing.
      temp = SetWindowLong(hwnd, GWL_WNDPROC, lpWndProc)
    End Sub    Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
      ByVal wParam As Long, ByVal lParam As Long) As Long
      If uMsg = WM_SIZE Then      End If
      If uMsg = WM_USER + 1 Then
        If wParam = 12345 Then
          
        End If
      End If
      Dim lpPrevWndProc As Long
    '查询原来默认的窗口过程指针
      lpPrevWndProc = GetWindowLong(hw, GWL_USERDATA)
    '调用原来的窗口过程
      WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
    End Function但是B中一直没有收到,具体应该怎么操作呢?

解决方案 »

  1.   

    你应该先把自己定义的消息注册一下,否则是不行的,因为不注册的话在TRANSLATEMESSGE的时候就会被过滤掉,不再放到消息队列里了。
      

  2.   

    而且接收部分是接收你注册成功时返回的消息句柄。代码形式如下。
    注册:handleMessage = RegisterWindowMessage("MyMessage")
    发送:SendMessage hwnd_, handleMessage, 100&, 0&
    接收:Case handleMessage
               MsgBox wParam
      

  3.   

    Dim pid As Long ' 储存进程标识符( Process Id )
    lResult = SendMessage(pid, WM_USER + 1, wParam, Me.hwnd)pid是窗体句柄吗??????Handle = FindWindow(vbNullString, "test1")'test1是B程序的标题
    wParam = 12345
    lResult = SendMessage(Handle, WM_USER + 1, wParam, Me.hwnd)
    这样试试
      

  4.   

    province_(雍昊) 
    你说的我还是不是很清楚!
    因为第一次接触消息机制,所以很多不明白的地方,麻烦说明白点!
    谢谢了!
      

  5.   

    现在注册已经OK了!
    还有个问题,我用SendMessage发送消息的时候需要发送字符给另外一个程序,但是好象SendMessage的参数都是Long型的?
    不过我不确定!
    有做过相同类型的高人没,解答一下!
    谢谢了!
      

  6.   

    Public Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
      

  7.   

    把字符放到数组里,再把第一个元素的地址传过去,接收的时候要用COPYMEMORY来获得内容。
      

  8.   

    问题在于我接收的WindowProc和CallWindowProc中lParam类型也是Long啊!有替换的吗?
    Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long      If uMsg = WM_TEST Then      ElseIf uMsg = WM_Send Then      Else
                    WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)      End IfEnd Function
      

  9.   

    就是LONG啊,COPYMEMORY接收的参数就是LONG型的地址啊。
      

  10.   

    如果你要传递比较多的数据到另1个程序,那么你可以用WM_COPYDATA消息,也可以用文件映射,管道等等
      

  11.   

    province_(雍昊)
    我这里面好象没有用到CopyMemory啊!
      

  12.   

    //回复人: province_(雍昊) ( ) 信誉:100  2005-9-20 12:24:20  得分: 0  
     
    //把字符放到数组里,再把第一个元素的地址传过去,接收的时候要用COPYMEMORY来获得内容。  这样做好像不行吧。Windows系统中,一个进程中得到的地址应该是该进程堆栈的相对地址,而不是整个内存的绝对地址,这样如果在另一个进程中使用该地址指针,指向的是本进程中的堆栈。
     
    我觉得两个进程间通信还应该使用管道或文件映射的方式。
      

  13.   

    其实现在我就想搞清楚,如果我发送消息的时候lparam是字符的话,在WindowProc中应该怎么接收,怎么判别?
      

  14.   

    你有没有试过截获WM_DEVICECHANGE消息呢?那里面的LPARAM就是一个地址,你可以把它用到COPYMEMORY里去,获得一个结构里的所有元素。TO benyfeifei(狒狒)这种做法本来就是在一个进程,何来进程间的事情?
      

  15.   

    WM_Devicechange不是当设备的硬件配置改变时发送的消息吗?
      

  16.   

    偶说了,如果实在要用消息传递的话,就用WM_COPYDATA
      

  17.   

    那具体应该怎么做呢?
    如果用WM_COPYData
    能给一点具体的代码看看吗?
      

  18.   

    dim data() as bytesub yoursub()
    data=strconv("HELLO",VBFROMUNICODE)
    sendmessage hwnd,yourmessage,5&,byref data(0)
    end sub模块里:
    dim data() as byte
    wndproc(.....)
    select msgcase yourmessage:
    redim data(wparam)
    copymemory byref data(0),lparam,wparam
    现在DATA()里就是HELLO的ASCII码了....
      

  19.   

    http://www.mredkj.com/vbquicktakes/Subclassing.html