首先说一下,因为我写的东西很杂,所以不细分类别,也不指明是那种语言写的,但干我们这行的应该能一眼看出用什么语言写的。呵呵
进程之间通讯的几种方法:
在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有
使用内存映射文件
通过共享内存DLL共享内存
使用SendMessage向另一进程发送WM_COPYDATA消息
比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一中方法.
这里就简单讲一下,首先是调用WINDOWS API
::FindWindow,原型如下
FindWindowA(
__in_opt LPCSTR lpClassName,
__in_opt LPCSTR lpWindowName);
第一个参数表示窗口派生类的名字,第二个参数是窗口的名字,这两个参数可以通过vs工具中的spy++获得。
用法:HWND hWnd = ::FindWindow(NULL,"ePhone");(这是我ePhone项目中窗口的名字);
得到窗口句柄然后发送消息,发送消息有两种选择:
::SendMessage
原型
SendMessageA(
__in HWND hWnd,
__in UINT Msg,
__in WPARAM wParam,
__in LPARAM lParam);
第一个参数是控制句柄,通过FindWindow可以拿到,第二个参数是消息类型,第三,四个参数是附加消息。
这里我讲我用过的消息类型,自定义消息。
#define WM_COPYDATA 0x004A
根据定义看到该自定义消息十六进制代码是0x004A,也就是说如果如我项目一样用其他程序(C#,JAVA)来接受这个自定义消息类型,则需要在程序中定义该变量,名字不重要,
但后面的十六进制代码必须一致。
一下是传递数据的结构:
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
COPYDATASTRUCT为结构名,可以直接用来声明结构变量,如COPYDATASTRUCT cpd;
其中有三个参数,第一个从名字上就知道是长整数指针类型,这个参数指定要发送的数据类型,这个完全可以自己定义
第二个是发送数据的大小,这个要相当准确,否则接受方无法分配合适的数据块大小,导致接受数据失败
第三个是关键,发送到指定程序的数据的指针,就是上面定义的cpd数据块的其实地址。
举个例子:
COPYDATASTRUCT cpd;
cpd.dwData = LOCATION; //标志为LOCATION类型,这个LOCATION是我自己定义的#define LOCATION 1
cpd.cbData = sizeof(COPYDATASTRUCT); //要传输数据结构的大小
cpd.lpData = (LPVOID)
data;//要传输数据的指针
这里的data也是我自己定义的一个结构,看例子
struct location
{
ATW_TUNER_EVENT movement;
int x;
int y;
};
location *
data = new location();
这样看下来就可以知道COPYDATASTRUCT 是本身winuser.h文件中定义的数据结构,用来发送自定义消息,而具体我要发送的数据又是我自己定义的一个结构
也就是包了两层发送出去。接下来看怎么发
::SendMessage(hWnd,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&
cpd);
这里的cpd我给的还是引用,传的是地址,也就是这个数据结构块。发送到指定的句柄。发送完了不要忘记释放刚才声明的
data。
再来是怎么收
收是发的逆过程,也就是拆包。同样你需要在接受端定义COPYDATASTRUCT 数据结构, 然后把接到的数据还原,也就是拆箱的过程
例如:
COPYDATASTRUCT *pCopyDataStruct
location *data = (location*)(pCopyDataStruct->lpData);
然后再拆,这里不细说。看到这里有人会问,那么我在哪里来写这段程序呢?这里本人只能给出在C#中的例子,不过相信在C/C++中也有相应的方法。
方法就是重写消息处理函数,每个FORM都会有这个函数。C#中:
protected override void WndProc(ref Message
m);
在网上也可能看到
protected override void DefWndProc(ref Message
m)看名字就是消息处理定义,具体读者可以自己去试验,我用的是上一个函数。
这里的
m
参数就是指定窗体接收到的消息。看例子:
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_COPYDATA)
{
//这里就是具体你想做的事……
}
else//其他消息扔给父类自己处理
base.WndProc(ref m);
}
好了,大致就是这些内容,毕竟本人水平有限,还是个菜鸟,详情还是参见MSDN,希望这些对朋友有些帮助。