WINDOWS下,窗口之间的通信

首先说一下,因为我写的东西很杂,所以不细分类别,也不指明是那种语言写的,但干我们这行的应该能一眼看出用什么语言写的。呵呵
 

进程之间通讯的几种方法:

在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,希望这些对朋友有些帮助。
 

你可能感兴趣的:(Windows)