首先说一下,因为我写的东西很杂,所以不细分类别,也不指明是那种语言写的,但干我们这行的应该能一眼看出用什么语言写的。呵呵 进程之间通讯的几种方法:
在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有
使用内存映射文件
通过共享内存DLL共享内存
使用SendMessage向另一进程发送WM_COPYDATA消息
【WINDOWS下,窗口之间的通信】比起前两种的复杂实现来,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_COPYDATA0x004A 根据定义看到该自定义消息十六进制代码是0x004A,也就是说如果如我项目一样用其他程序(C#,JAVA)来接受这个自定义消息类型,则需要在程序中定义该变量,名字不重要, 但后面的十六进制代码必须一致。 一下是传递数据的结构: typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
COPYDATASTRUCT为结构名,可以直接用来声明结构变量,如COPYDATASTRUCT cpd;
其中有三个参数,第一个从名字上就知道是长整数指针类型,这个参数指定要发送的数据类型,这个完全可以自己定义 第二个是发送数据的大小,这个要相当准确,否则接受方无法分配合适的数据块大小,导致接受数据失败 第三个是关键,发送到指定程序的数据的指针,就是上面定义的cpd数据块的其实地址。 举个例子: COPYDATASTRUCT cpd;
cpd.dwData = https://www.it610.com/article/LOCATION;
//标志为LOCATION类型,这个LOCATION是我自己定义的#define LOCATION 1
cpd.cbData = https://www.it610.com/article/sizeof(COPYDATASTRUCT);
//要传输数据结构的大小
cpd.lpData = https://www.it610.com/article/(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 = https://www.it610.com/article/(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,希望这些对朋友有些帮助。
推荐阅读
- windows11|Windows11安装Android子系统
- C#|C# 文件路径操作
- 其他|有趣的10个CMD命令
- windows|Windows 11 手机诞生,还是双屏的()
- java|My GrokTalk-十分钟内十种工具
- Ubuntu|Ubuntu 3D桌面