当前位置:编程学习 > VB >>

VB接收来之postmessage自定义的消息。求高手赐代码。

VB接收来之postmessage自定义的消息。求高手赐代码。 --------------------编程问答-------------------- 必须使用子类化技术,hook窗口过程,在自定义的窗口过程中处理你自定义的事件
子类化使用SetWindowLong函数 --------------------编程问答-------------------- 用API函数SetWindowLong指定处理消息的窗口过程(window procedure)为自定义的函数WindowProc,捕获消息ID为WM_USER+1的自定义消息或系统消息。并且,为了保证窗口能正确的响应消息,需要保存原来默认的窗口过程并在自定义函数WindowProc中调用。如下例,在按钮事件中发送自定义消息,WindowProc捕获了窗口大小变化的系统定义消息和用户自定义的消息并显示用户自定义的消息参数wParam:
在Moduel中加入以下代码,

  Option Explicit
   Private Const GWL_WNDPROC = -4
   Public Const GWL_USERDATA = (-21)
   Public Const WM_SIZE = &H5
   Public Const WM_USER = &H400
   Private 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
   ‘处理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 Long
  Private 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 Sub
  Private Sub Form_Unload(Cancel As Integer)
   Unhook Me.hwnd, Me.Tag
  End Sub
 

--------------------编程问答-------------------- 这个基本就是楼上两位的这样做。
--------------------编程问答--------------------
引用 1 楼  的回复:
必须使用子类化技术,hook窗口过程,在自定义的窗口过程中处理你自定义的事件
子类化使用SetWindowLong函数


IF( FindWindow("postmessage") == 0) THEN
    MsgBox("程序没有打开请打开");
else
AppID1=FindWindow("postmessage");
ENDIF
postMessage(AppID1,688,0101,0101);
//AppID1=postMessage(AppID1,2264,0101,0101); 我使用的工业组态软件给发的。代码如上。你给的程序能不能接受到我发的消息 --------------------编程问答--------------------
引用 2 楼  的回复:
用API函数SetWindowLong指定处理消息的窗口过程(window procedure)为自定义的函数WindowProc,捕获消息ID为WM_USER+1的自定义消息或系统消息。并且,为了保证窗口能正确的响应消息,需要保存原来默认的窗口过程并在自定义函数WindowProc中调用。如下例,在按钮事件中发送自定义消息,WindowProc捕获了窗口大小变化的系统定义消息和用户自定义的消息并……


IF( FindWindow("postmessage") == 0) THEN
  MsgBox("程序没有打开请打开");
else
AppID1=FindWindow("postmessage");
ENDIF
postMessage(AppID1,688,0101,0101);
//AppID1=postMessage(AppID1,2264,0101,0101); 我使用的工业组态软件给发的。代码如上。你给的程序能不能接受到我发的消息 --------------------编程问答-------------------- 自定义消息注册了没有 --------------------编程问答--------------------
引用 6 楼  的回复:
自定义消息注册了没有
 大侠。。求赐教 --------------------编程问答-------------------- 注册自定义消息:
http://blog.csdn.net/nogodoss/article/details/6091343 --------------------编程问答--------------------
引用 5 楼  的回复:
IF( FindWindow("postmessage") == 0) THEN
   MsgBox("程序没有打开请打开");
else
AppID1=FindWindow("postmessage");
ENDIF
postMessage(AppID1,688,0101,0101);

代码如果是这样写的,则两边程序启动时都需要先调用RegisterWindowMessage注册一个标识,比如"MY_MESSAGE_FUNC_01",并保存得到的值,这个值就是向系统注册后的一个消息标识,不同进程使用同样的字符串,能得到相同的值,方便通讯.

以上为基础.

其二,如果是使用FindWindow("postmessage")这样的方式来找接收方句柄,则需要创建一个Caption为"postmessage"的窗体.不然发送方找不到.

其三,接收方将第二步的窗体进行子类化,并过滤消息ID为第一步所得到的数值的消息,即可接收到所需要的数据了.

其中第二步,我个人意见是使用BroadcastSystemMessage,这个API是广播消息,虽然效率没有直接POSTMESSAGE高,但是在低频率应用时是非常方便的,不需要找窗口.

另外关于第三步中所需要用到的子类化技术,这里有PctGL封装的一个超精简子类化类模块:

http://www.m5home.com/bak_blog/article/487.html

仅需要一句SetMsgHook调用即可开始子类化,然后再在GetWindowMessage事件里判断Message即可.
补充:VB ,  API
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,