WinCE应用程序开发---进程间通信

 上篇博文介绍了线程间同步,本博文将介绍进程间通信。实现进程间通信的方式有好几种,其中最常用的而且最可靠的是采用内存映射的方式实现这一功能。

1. 目的:通过内存映射的方式实现进程间通信。

2. 实现:

2.1 平台:WinCE + VS2005

2.2 具体实现过程

为了叙述的方便,将主应用程序对应的进程称为Host进程,程序称为Host程序;将从应用程序对应的进程称为Target进程,程序称为Target程序。

2.2.1 Host端

首先在Host程序的头文件中添加如下自定义消息,注意自定义消息

/************************************************************************/
// 用于访问内存映射文件的用户自定义消息

#define WM_MSG_SEND_COMMAND   WM_USER+111   // 发送消息(命令)给Bottom窗口

#define WM_MSG_SEND_DATA   WM_USER+112   // 发送消息(数据)给Bottom窗口

#define WM_MSG_RECEIVE_COMMAND  WM_USER+113   // 接收来自Bottom的消息(命令)

#define WM_MSG_RECEIVE_DATA   WM_USER+114   // 接收来自Bottom的消息(数据)

/************************************************************************/

其次,在Host程序的源文件中添加想要发送到Target程序的消息,比如

::SendMessage(m_hTarget, WM_MSG_SEND_COMMAND, (WPARAM)QueryUSBStatus,(LPARAM)0);

// 参数1表示Target程序对应的窗口句柄,有几种方式可获得窗口的句柄,在本博文小结中,我会给出具体的获取窗口句柄的方法。

// 参数2表示自定义消息,这个消息就是Target程序要响应的,因此该消息同样要在Target程序的头文件中有定义。

// 参数3和参数4是用户可灵活使用的,一般用于告诉接受端访问哪段内存区域,告诉用户指针的偏移地址和数据长度,以方便接受端从指定的内存区域取数据。内存映射访问共享数据就用到了这个方法。

为了方便叙述,给出了Host程序向Target程序发送的部分命令样式。

/************************************************************************/
// WinCE发给USB端的命令
#define  QueryUSBStatus  1         // 0x01
#define  USBStatusReturn  16         // 0x10表示USB正常,0x12表示USB不正常
#define  QueryUSBReady  17           // 0x11表示正常,仅用在USBConnectRigth为FALSE的情况下才使用这个命令
#define  WinCEStatusReturn 32       // 0x20表示WinCE正常,0x22表示WinCE端不正常
#define  WinCEToUSBStart  33        // 0x21表示WinCE通知USB开始发送数据
#define  NotifyWinCEGetData 48      // 0x30表示USB通知WinCE取数据
#define  WinCEToUSBStop  49        // 0x31表示WinCE通知USB停止发送数据
#define  USBSendDataFinish 64       // 0x40表示USB通知此次测试已经完毕
#define  SetUSBWndMinimized  65   // 0x41表示WinCE通知USB窗口最小化
#define  CloseUSB   80                   // 0x50表示WinCE通知USB退出程序
#define  USBReady   97                  // 0x61表示USB通知WinCE端USB已经准备好
/************************************************************************/

2.2.2 Target端

接受端Target程序有4处需要注意。

1)在Target的头文件中添加与Host头文件中一样的自定义消息定义,如下所示。

/************************************************************************/
// 用于访问内存映射文件的用户自定义消息,这个定义直接来自WinCE程序
#define WM_MSG_SEND_COMMAND   WM_USER+111  // 发送消息(命令)给Bottom窗口

#define WM_MSG_SEND_DATA   WM_USER+112  // 发送消息(数据)给Bottom窗口

#define WM_MSG_RECEIVE_COMMAND  WM_USER+113  // 接收来自Bottom的消息(命令)

#define WM_MSG_RECEIVE_DATA   WM_USER+114  // 接收来自Bottom的消息(数据)

#define WM_MSG_ExitWindow   WM_USER+115  // 如果已经有个实例在运行,则直接让之后打开的实例退出
/************************************************************************/

2)在Target的源文件中添加自定义消息映射

BEGIN_MESSAGE_MAP(CTVLFUSBCommunicationDlg, CDialog)

  ON_MESSAGE(WM_MSG_SEND_COMMAND, OnReceiveCommand) // 对于Host是发送命令,对于Target则是接收命令

END_MESSAGE_MAP()

3)在Target程序的头文件中添加消息响应函数的定义

afx_msg LRESULT OnReceiveCommand(WPARAM wParam,LPARAM lParam); // 收到来自Top的命令

4)完善自定义消息对应的消息响应函数

LRESULT CTVLFUSBCommunicationDlg::OnReceiveCommand(WPARAM wParam,LPARAM lParam)
{
   int CommandID  = wParam;
   int usedBufferLen = lParam;

  switch(CommandID)
   {
       case QueryUSBStatus:
       { // 向WinCE返回当前USB的状态
          int USBstatus = 16;
          memset(m_pCommandBuf+sizeof(int), 0 ,sizeof(int));
          memcpy(m_pCommandBuf+sizeof(int), &USBstatus, sizeof(int));
          break;
       }
       case WinCEToUSBStart:
       {
          // 收到WinCE的命令,以及积分次数和每个测点号的数据点个数,然后开始发送数据给WinCE
          memcpy(&IntegrationNumbers, m_pCommandBuf+sizeof(int)*10, sizeof(int));
          memcpy(&DataNumbers, m_pCommandBuf+sizeof(int)*11, sizeof(int)); 
          currentIntegralCount = 0;
          this->SetTimer(1, TimerPeriod, NULL);
          break;
       }
       case WinCEToUSBStop:
       {
          currentIntegralCount = 0;
          this->KillTimer(1);
          break;
       }
       ...........  
   }
 return 0;

}

3. 总结:

3.1 在进程A中使用SendMessage()函数向进程B发送消息,需明确进程B对应的窗口句柄。在进程B源程序中获取窗口句柄的方式有:

1)hTarget = ::FindWindow(NULL, TargetExeWindowName);    // 其中TargetExeWindowName为CString类型,表示进程B对应的窗口名称

2)hTarget= AfxGetApp()->GetMainWnd()->m_hWnd;

3)hTarget= AfxGetMainWnd()->m_hWnd;

4)hTarget= this->GetSafeHwnd();

3.2 SendMessage()和PostMessage()发送消息的区别在于发送消息是否立即返回,可根据实际需要权衡利弊选择最适合项目程序的发送消息方式。

3.3 文中只介绍了发送命令接受命令的方法,发送数据和接受数据的方法与其类似,不再赘述,区别仅在于发送数据时传递了2个参数,1个参数是指针的起始偏移地址,1个参数是数据长度。

 

你可能感兴趣的:(WinCE)