[转]进程间发消息

Windows把0x400定义为WM_USER。如果想定义自己的一个消息,可以在WM_USER上加上一个值:

#define WM_CONTROLPRINT WM_USER+1001

另一种自定义窗口消息的方法是用RegisterWindowsMessage()函数来注册这个消息。与在WM_USER上加上某个数相比,它的好处是不必考虑所表示的消息标识符是否超出工程的允许范围。如:

const UINT WM_CONTROLPRINT=RegisterWindowMessage("reg_data");

在接收消息的程序中,需要对添加对应消息的响应处理函数,并将消息和消息处理函数关联,要不它不知道消息发给谁:

//函数定义,在//AFX_MSG中
afx_msg LRESULT OnControlPrint(WPARAM wParam,LPARAM lParam);

//函数实现
LRESULT CSendDlg::OnControlPrint(WPARAM wParam,LPARAM lParam)
{
}

//关联映射,在BEGIN_MESSAGE_MAP中
ON_MESSAGE(WM_CONTROLPRINT,OnControlPrint)//使用WM_USER+1001定义的消息
ON_REGISTERED_MESSAGE(WM_CONTROLPRINT,OnControlPrint)//使用RegisterWindowMessage定义的消息

消息如何传递呢?我们需要发送消息时,可以使用PostMessage和SendMessage。这两个消息发送函数不一样的地方就是SendMessage发送完消息后会等待消息处理函数处理完成后返回,PostMessage则不等待。所以,可以说PostMessage是不可靠的,实际运用中可以根据具体情况来确定用那一个。这两个函数的具体使用请查看MSDN。

如我向主窗体发送一个消息(第一个参数是接收消息的窗体句柄,第二个参数是要发送的消息,后边两个为随消息发送的参数信息):
::SendMessage(AfxGetApp()->GetMainWnd()->m_hWnd,WM_CONTROLPRINT,NULL,0);


2,使用自定义消息在进程间通讯;

我们可以用VC60建立两个基于对话框的工程,一个命名为Send,一个命名为Revice。

在Send对话框中添加一个名成为IDC_BUTTONSEND的按钮。

在SendDlg.h和ReviceDlg.g中都添加自定义消息。消息实现进程间通信,需要在这两个程序中定义或注册相同的消息,才能保证数据通信顺利进行:

#define WM_CONTROLPRINT WM_USER+1001

在Send工程中添加IDC_BUTTONSEND按钮的单击处理事件,并添加代码:

void CSendDlg::OnButtonsend()

{

//获取窗口句柄
CWnd *pWnd=CWnd::FindWindow(NULL,_T("Revice"));
if(pWnd==NULL)
{
AfxMessageBox("接收程序没有运行!");
return ;
}

//发送消息
pWnd->SendMessage(WM_SENDYKDISABLE,NULL,0);
}

在Revice工程中添加WM_CONTROLPRINT 的处理函数,关联映射,和上边描述的过程一样,在处理函数中添加相应的处理代码。这里就不多说了!

 

 

 

 

 

 

 

 

 

 

 


进程间传递消息的实现方法
作者: 来源:   发布日期:2007-07-03  
    随着我们开发的应用的日益复杂,像以往那样将所有功能坐在一个exe文件中情况越来越少,更多时候是整个应用由若干模块、甚至若干单独的exe文件组成,这就涉及到了模块或进程间的通讯交互问题,本文主要谈谈在进程间的信息传递方法,作为进一步探讨进程间通讯方案的参考。
1.使用用户自定义消息在进程间传递消息。
       经过一定时间的Win32开发,大家对Windows Mobile平台下的消息映射机制应该都比较清楚了,除了系统已经为我们设定的如WM_CREATE、WM_PAINT这类消息外,还有一种特殊的WM_USER消息用于用户自定义消息。
定义格式如下:
       #define WM_IAMHANDSOME WM_USER+1                  
然后同样的对于WM_IAMHANDSOME同样的将它映射到相应的处理函数上去。
当需要使用激发该消息时,采用SendMessage函数发送一个WM_IAMHANDSOME即可。下面谈谈在进程间如何进行用户自定义消息的传递。

       例,假设两个程序,一个叫zoujielun,一个叫feiyuqing,两个程序进行一项操作,唱一首名叫《千里之外》的歌。
       其中即需要一个程序“唱”完后通知另一个程序接着“唱”。
1)在两个程序中都定义#define WM_YOUTURN WM_USER+10
2)在feiyuqing进程中加入对应WM_YOUTURN的映射:
const MSG_MAP_MAIN_S g_mainMsg[] =
{
       //……
{WM_YOUTURN,OnYouturn},
       //……
};
3)在zoujielun中向feiyuqing发送WM_YOUTURN的消息,代码如下:
       Sing(_T(“屋檐如悬崖风铃如沧海我等燕归来……”));
           HWND findWindows=NULL;
       findWindows= FindWindow(_T(“feiyuqing”), _T(“feiyuqing\"));
           SendMessage(findWindows,WM_YOUTURN,0,0);
这样,即把消息发送给了feiyuqing进程。
4)在feiyuqing中,对应的OnYouTurn做出相应处理即可。
LRESULT OnYouTurn(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
       Sing(_T(“我送你离开千里之外 ……”));
       return 0;
}
    这样即实现了进程间通过自定义消息传递来进行通讯,但是这样的缺点是不能同时传递数据。假设feiyuqing因为年纪大了,如果突然“失忆”了,不记得歌词,需要zoujielun不但告诉他该唱了,还要告诉他该唱什么,这时就需要利用系统一个强大的消息WM_COPYDATA。  

2.使用WM_COPYDATA消息跨进程传递数据
       在SDK中,该消息对应的参数为:
    WM_COPYDATA wParam = (WPARAM)(HWND) hwnd;
               lParam = (LPARAM)(PCOPYDATASTRUCT) pcds; [Page]
关键在于第二个参数,即一个COPYDATASTRUCT结构的指针。
该数据结构的结构如下:
typedef struct tagCOPYDATASTRUCT {
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;
第一个数据成员可以传递一个DWORD类型,如果只是要在进程间传一个DWORD类型的数据,这里可以直接用这个成员传递。
关键在第二、三个数据成员,第三个lpData即为欲传递的数据的指针,第二个cbData即为传递的数据大小,以byte为单位。
下面举例,还是zoujielun和feiyuqing程序间的通讯。
1)在feiyuqing进程中加入对应WM_COPYDATA的映射:
const MSG_MAP_MAIN_S g_mainMsg[] =
{
       //……
{WM_COPYDATA,OnYouturn},
       //……
};
2)在zoujielun中向feiyuqing发送WM_YOUTURN的消息,代码如下:
       Sing(_T(“屋檐如悬崖风铃如沧海我等燕归来……”));
     HWND findWindows=NULL;
       findWindows= FindWindow(_T(“feiyuqing\"), _T(“feiyuqing\"));
       TCHAR *sContent = new TCHAR[256];
       wsprintf(sContent,_T(“我送你离开千里之外……\"));
COPYDATASTRUCT copyData;
copyData.cbData = _msize(sContent);
copyData.lpData = sContent;
SendMessage(findWindows,WM_COPYDATA,0,(LPARAM)&copyData);
3)在feiyuqing中,对应的OnOnYouTurn做出相应处理即可。
LRESULT OnYouTurn(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
       TCHAR *sContent = NULL;
            sContent =(TCHAR*)((COPYDATASTRUCT*)lParam)->lpData;
       Sing(sContent);
       return 0;
}
即收到该消息后从相应参数取出数据进行处理。


SendMessage FindWindow
http://www.cnblogs.com/shengshuai/archive/2007/05/01/sendmessagefindexec.html
MFC中获得各个类的句柄的总结
http://hi.baidu.com/mzyse/blog/item/74403501e1b97d001c9583f6.html
MFC中自由使用自定义消息
http://www.cppblog.com/xbgs/archive/2008/12/17/69647.html

posted @ 2010-07-26 10:17  欢哥哥  阅读(1574)  评论(0)    收藏  举报