如题,我要实现两个进程窗体间的消息传递。
为了向另一个进程发送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 LongPublic Declare Function SendMessagelong Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPublic Declare Function SendMessageAny Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As LongPublic 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 IfSendMessage语句,只有VarPtr(DataStruct)这行能触发接收进程程序中窗体的
DefWndProc回调事件,但接收不到数据-数据为空串(接收程序代码是正确的,已用2个c#程序
发送、接收消息测试通过)。
不知DataStruct数据如何传递,VarPtr?,RtlCopyMemory?ObjPtr?
为了向另一个进程发送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 LongPublic Declare Function SendMessagelong Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPublic Declare Function SendMessageAny Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As LongPublic 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 IfSendMessage语句,只有VarPtr(DataStruct)这行能触发接收进程程序中窗体的
DefWndProc回调事件,但接收不到数据-数据为空串(接收程序代码是正确的,已用2个c#程序
发送、接收消息测试通过)。
不知DataStruct数据如何传递,VarPtr?,RtlCopyMemory?ObjPtr?
解决方案 »
- If i / 2 = i \ 2 Then
- 一个程序界面开发的问题,请指教?
- SQL问题:如何把一条记录插入到表结尾处
- 上次也问了这个问题,没有很好的人气。
- 关于指针,请大家看看,调用对吗?
- 关于过程与模块的菜鸟百思不得其解的简单问题,兼散分。
- 簡單問題,把Access中DateTime類型的數據的時間,拿出來?
- 在声卡中发出声音?
- CreateObject创建Word Excel对象失败,提示,无法加载DLL,怎么解决?
- 关于用Data Report和数据环境设计器(DataEnvironment)生成的报表问题。50分求答。
- 请前辈们看完图后能不能给个SQL语句,感激不尽!
- 哪位vb高手加我帮忙调试个程序啊。。。不胜感激
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByRef lParam As Any) As Long '<-注意是 ByRef'SendMessageAny frmHwnd, WM_COPYDATA, 0, DataStruct
vb其余代码为:
Public CtlText As String '控件文字
Public Type COPYDATASTRUCT
dwData As Integer
cbData As Integer
lpData As String
End Type
Public DataStruct As COPYDATASTRUCTCtlText = Text1.Text '发送文字
If frmHwnd <> 0 Then
DataStruct.lpData = Left(CtlText, 99)
DataStruct.cbData = Len(DataStruct.lpData) + 1
DataStruct.dwData = 100
SendMessageAny frmHwnd, WM_COPYDATA, 0, DataStruct
End If-----------c#代码为-----------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;using System.Runtime.InteropServices;//WindowsFormGetMsg
namespace ProcessReceive
{
public partial class Form1 : Form
{
const int WM_COPYDATA = 0x004A;
const int WM_USER = 0x0400; public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
labelType.Text = "";
} protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
switch(m.Msg)
{
case WM_COPYDATA:
mystr =(COPYDATASTRUCT)m.GetLParam(mytype);
this.textBox1.Text =mystr.lpData;
labelType.Text = "WM_COPYDATA";
break; default:
base.DefWndProc(ref m);
break;
}
} private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = "";
}
} public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)] public string lpData;
}
}我的vb代码需要如何修改?
dwData As Integer
cbData As Integer
lpData As String * 100 '假设你的字符串不超过100个字符'
End Type
Public Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As String
End Type
Public DataStruct As COPYDATASTRUCT
目前发送消息成功!
DataStruct.lpData = StrConv(Left(CtlText, 99),vbFromUnicode)
DataStruct.cbData = LenB(DataStruct.lpData) + 1
DataStruct.dwData = 100
只能接收到前面48个字节的数据。
哪位把程序改改!
程序下载地址:
http://download.csdn.net/source/1950913
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
【窗体】:
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 = &H4APublic 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 LongPublic 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 LongPublic 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 IntegerPublic pRecData As Long
Public sData As StringFunction 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
只能接收到前面48个字节的数据。
哪位把程序改改!
程序下载地址:
http://download.csdn.net/source/1950913
Public Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Public DatrStruct As COPYDATASTRUCT
两个vb的程序通讯成功
感谢老马和楼上的各位!
新年快乐!