我目前正在成功使用Win32 API的SendMessage函数,使用WM_SETTEXT参数在两个线程之间发送文本。
我想要做的是发送自定义数据类型而不是原始数据类型。
所以让我说我有
Type myType
a as Integer
b(5) as Boolean
d(15) as Double
End Type
Dim tmp as myType
我希望能够:
Call SendMessage(dstHWnd, WM_SETTEXT, 0, tmp)
我猜我必须使用WM_COPYDATA或类似的,但另一个问题是这会产生错误,因为我的数据类型无法按照函数定义转换为Any:
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
是否有可能哄骗这种转换?或者是否有另一种最佳实践方法(快速和最佳)?
答案 0 :(得分:3)
将SendMessage
的最后一个参数声明为byref lParam as myType
。
为了澄清,在接收端,您正在执行以下操作来获取数据
首先,使用最后一个参数ByVal lParam As Long
声明消息处理例程。还有一个功能:
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
然后,当您收到消息时:
if uMsg = WM_SETTEXT then
dim t as myType
copymemory t, byval lParam, len(t)
'Using t here
end if
进一步澄清。
因为所有线程都在一个进程内,所以你可以简单地共享指针并按WM_COPYDATA
的平均值进行操作。您只需要COPYDATASTRUCT
结构的第一个成员。
在发送端,您设置COPYDATASTRUCT.dwData = VarPrt(your_struct)
。
在接收端,您执行上面显示的相同CopyMemory
事项。
请注意,如果您的消息处理例程仅接收该单个消息(并且没有其他消息),那么您可以简单地将其最后一个参数声明为ByRef lParam As myType
并直接使用它,从而避免复制。
答案 1 :(得分:3)
如何使用内存映射文件?
'Write to MyMMF
Private Function writeMyType(newMyType As myType)
hMMF = OpenFileMapping(FILE_MAP_ALL_ACCESS, False, "MyMMF")
If hMMF = 0 Then
hMMF = CreateFileMapping(-1, 0, PAGE_READWRITE, 0, LenB(newMyType), "MyMMF")
End If
If Not hMMF = 0 Then
pMemfile = MapViewOfFile(hMMF, FILE_MAP_ALL_ACCESS, 0, 0, 0)
RtlMoveMemory1 pMemfile, ByVal newMyType, LenB(newMyType)
End If
CloseHandle hMMF
End Function
'Read from MyMMF
Private Function readMyType(ByRef inMyType As myType)
hMMF = OpenFileMapping(FILE_MAP_ALL_ACCESS, False, "MyMMF")
If hMMF = 0 Then
MsgBox "No data in MyMMF"
Exit Function
Else
pMemfile = MapViewOfFile(hMMF, FILE_MAP_ALL_ACCESS, 0, 0, 0)
RtlMoveMemory2 ByVal inMyType, pMemfile, LenB(inMyType)
End If
CloseHandle hMMF
End Function
'Declares and Constants
Public Type myType
a As Integer
b(5) As Boolean
d(15) as Double
End Type
Public Declare Function OpenFileMapping Lib "kernel32" Alias "OpenFileMappingA" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal lpName As String) As Long
Public Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, ByVal lpAttributes As Long, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Long
Public Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Sub RtlMoveMemory1 Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByVal Destination As Long, _
ByRef Source As Any, _
ByVal Length As Long)
Public Declare Sub RtlMoveMemory2 Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, _
ByVal Source As Long, _
ByVal Length As Long)
Public Const FILE_MAP_ALL_ACCESS = &H1F
Public Const PAGE_READWRITE = &H4
答案 2 :(得分:1)
如果它们是两个线程(每个都有自己的窗口?在VB6中?hmm)那么你只需要发送一个指向变量VarPtr(blah)
的指针,并确保在返回之前复制出窗口过程。< / p>
但是,如果线程在两个独立的进程中,则选项要少得多。
您可以使用为您进行编组的WM_COPYDATA
消息,或者设置一些共享/全局内存并通过普通SendMessage()
传递指针/偏移量
正常的线程同步实践适用于后一种方法。