vb使用SendMessage发送WM_COPYDATA消息,结构体指针或内存拷贝?高手请进

jwh2004 2009-12-29 10:09:06
如题,我要实现两个进程窗体间的消息传递。
为了向另一个进程发送WM_COPYDATA消息,我封装了一个结构体:DataStruct
代码如下:
【模块中】:
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As

String) As Long

Public Declare Function SendMessagelong Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As

Long) As Long

Public Declare Function SendMessageAny Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As

Any) As Long

Public Const WM_COPYDATA As Long = &H4A
Public frmHwnd As Long

【窗体代码中】:
If frmHwnd <> 0 Then
'向窗体发送WM_COPYDATA消息
DataStruct.lpData = Left(CtlText, 99)
DataStruct.cbData = Len(DataStruct.lpData) + 1
DataStruct.dwData = 100
'SendMessage frmHwnd, WM_COPYDATA, 0, ByVal VarPtr(DataStruct)
SendMessagelong frmHwnd, WM_COPYDATA, 0, ByVal VarPtr(DataStruct)
'SendMessageAny frmHwnd, WM_COPYDATA, 0, ByVal DataStruct
End If

SendMessage语句,只有VarPtr(DataStruct)这行能触发接收进程程序中窗体的
DefWndProc回调事件,但接收不到数据-数据为空串(接收程序代码是正确的,已用2个c#程序
发送、接收消息测试通过)。
不知DataStruct数据如何传递,VarPtr?,RtlCopyMemory?ObjPtr?
...全文
1220 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
嗷嗷叫的老马 2010-01-03
  • 打赏
  • 举报
回复
新年快乐!!!
jwh2004 2009-12-31
  • 打赏
  • 举报
回复
ProcessSend与c#的ProcessReceive程序通讯正常,但与vb的ProcessReceive程序通讯,
只能接收到前面48个字节的数据。
哪位把程序改改!
程序下载地址:
http://download.csdn.net/source/1950913
jwh2004 2009-12-31
  • 打赏
  • 举报
回复
接收程序:
【窗体】:
Option Explicit
Private Sub Form_Load()
Text1.Text = "准备接收"
TextHwnd1.Text = "句柄1:" & Text1.hwnd

On Error GoTo 0
'On Error Resume Next
'这就是窗口子类化
prevWndProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
'AddressOf是取函数的地址,注意WndProc必须位于一个模块中
SetWindowLong Me.hwnd, GWL_WNDPROC, AddressOf WndProc
'-----------------
End Sub

'清空
Private Sub Command1_Click()
Text1.Text = ""
End Sub

模块:
Option Explicit
Public Const GWL_WNDPROC = (-4)
Public Const WM_USER = &H400
Public Const WM_COPYDATA As Long = &H4A

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
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(pDst As Any, pSrc As Any, ByVal ByteLen As Long)
'Public Declare Sub RtlMoveMemory Lib "KERNEL32" _
(lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)

Public prevWndProc As Long

Public Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As String
End Type
Public DatrStruct As COPYDATASTRUCT

'为全局原子表添加一个原子
'返回值:Long,如执行成功,返回原子值(&C000 到 &FFFF);零表示出错。会设置GetLastError
Declare Function GlobalAddAtom Lib "kernel32" Alias "GlobalAddAtomA" _
() ' (ByVal lpString As String) As Integer

Public pRecData As Long
Public sData As String

Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim l As Long, sData As String

'If Msg = WM_USER Then
'End If
If Msg = WM_COPYDATA Then
pRecData = VarPtr(DatrStruct)
'只能收到前面48个字符,不知道为什么???
CopyMemory DatrStruct, ByVal lParam, LenB(DatrStruct)
'DatrStruct.lpData = StrConv(DatrStruct.lpData, vbFromUnicode)
Form1.Text1 = DatrStruct.lpData
'WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
Else
WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End If
End Function
slowgrace 2009-12-31
  • 打赏
  • 举报
回复
CopyMemory 如何声明的?
slowgrace 2009-12-31
  • 打赏
  • 举报
回复
DatrStruct在哪里以及如何声明的?
slowgrace 2009-12-31
  • 打赏
  • 举报
回复
pRecData 在哪里以及如何声明的?
jwh2004 2009-12-31
  • 打赏
  • 举报
回复
10楼的StrConv不行呀,是不是接收进程也要相应的修改?
Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim l As Long, sData As String

'If Msg = WM_USER Then
'End If
If Msg = WM_COPYDATA Then
pRecData = VarPtr(DatrStruct)
'只能收到前面48个字符,不知道为什么???
CopyMemory DatrStruct, ByVal lParam, LenB(DatrStruct)
'DatrStruct.lpData = StrConv(DatrStruct.lpData, vbFromUnicode)
Form1.Text1 = DatrStruct.lpData
'WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
Else
WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End If
End Function
slowgrace 2009-12-31
  • 打赏
  • 举报
回复
10楼试了么?
jwh2004 2009-12-31
  • 打赏
  • 举报
回复
ProcessSend与c#的ProcessReceive程序通讯正常,但与vb的ProcessReceive程序通讯,
只能接收到前面48个字节的数据。
哪位把程序改改!
程序下载地址:
http://download.csdn.net/source/1950913
slowgrace 2009-12-31
  • 打赏
  • 举报
回复
声明为long是最好的,声明为string可能会遭遇VB自动进行的Unicode到ANSI的字符转换,导致各种问题。


新年快乐!
jwh2004 2009-12-31
  • 打赏
  • 举报
回复
最后将结构体的定义改成了:
Public Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Public DatrStruct As COPYDATASTRUCT
两个vb的程序通讯成功
感谢老马和楼上的各位!
嗷嗷叫的老马 2009-12-31
  • 打赏
  • 举报
回复
dwData是结构长度,传lenb(DatrStruct)

cbData是后面指针所指内容的长度,传lenb([字符串])

lpData声明为一个String,然后直接赋值为字符串变量就行.
jwh2004 2009-12-31
  • 打赏
  • 举报
回复
人呢?别都回家了呀
Tiger_Zhao 2009-12-29
  • 打赏
  • 举报
回复
API 中应该是 ANSI 字符串。
DataStruct.lpData = StrConv(Left(CtlText, 99),vbFromUnicode)
DataStruct.cbData = LenB(DataStruct.lpData) + 1
DataStruct.dwData = 100
jwh2004 2009-12-29
  • 打赏
  • 举报
回复
c#的int对应vb6的long型,指针都是long型的,我给忽略了,呵呵,看来使用语言不熟练是不行的
jwh2004 2009-12-29
  • 打赏
  • 举报
回复
已知道了,应该为:
Public Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As String
End Type
Public DataStruct As COPYDATASTRUCT
目前发送消息成功!
slowgrace 2009-12-29
  • 打赏
  • 举报
回复
改成这样定义试一下呢?

Public Type COPYDATASTRUCT 
dwData As Integer
cbData As Integer
lpData As String * 100 '假设你的字符串不超过100个字符'
End Type
jwh2004 2009-12-29
  • 打赏
  • 举报
回复
不知COPYDATASTRUCT 结构体的定义是否正确呢?
jwh2004 2009-12-29
  • 打赏
  • 举报
回复
SendMessageAny最后改成ByRef lParam As Any
slowgrace 2009-12-29
  • 打赏
  • 举报
回复
SendMessageAny 的函数声明 最后一个参数你改成ByRef了么?
加载更多回复(6)

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧