多个窗口收发WINDOW消息阻塞的一点思考

在软件项目里有三个模块,分别为

一个应用模块(处理数据)
一个显示模块(屏幕)
一个通信模块(与主机通信)
每个模块都会继承WINDOW收发通信模块基类创建一个属于自己的子窗口,然后在窗口的消息处理函数中对收到的消息进行处理。
在其中一个测试过程中,当通信模块收到主机命令然后向应用模块发送指令,应用模块执行完后,应用模块会向通信模块发送指令执行成功消息。调用
ret = ::SendMessageTimeout(hRecvWnd,// handle to window
   WM_COPYDATA,// message type
   (WPARAM)hSendWnd,// first message parameter
   (LPARAM)&cds,// second message parameter
   SMTO_BLOCK,// send options
   3000,// time-out duration
   &dwResult);// return value for synchronous call
没想到最后执行超时了2次,最后一次才成功。延迟了9秒。
原因是当应用模块发送消息后,基类窗口处理函数调用的接收到的消息处理动作阻塞住了。
解决阻塞有3种方法
1. 把接受到的消息内容,先拷贝起来,然后直接给发送信息的窗口返回消息处理,然后继续对接受到的消息进行处理.
2. 每收到一个消息,创建一个线程,把收到的消息内容存储起来,然后在线程里对接受到的消息进行处理。
3. 把所有接受到的消息内容,拷贝到队列里,然后对队列里的接受到的消息进行处理


最后我选择了用线程,因为这个比较简单,而且线程数量也不多,释放也简单。

原来的窗口消息处理函数为
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   switch (message)
   {  
      case WM_COPYDATA:
  COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
  if ((cds!=NULL)&&(m_ipc!=NULL))
  { 

   //m_ipc为CIPC的类对象,
    m_ipc->OnReceive(m_csSendWndTile,cds->dwData,cds->lpData,cds->cbData); 
  }
     return 0;
   }

   return DefWindowProc(hwnd, message, wParam, lParam);
}

修改后的窗口消息处理函数为:

UINT Thread_Process(LPVOID lpContext)

   COPYDATASTRUCT* cds = new COPYDATASTRUCT;
   memcpy(cds,(COPYDATASTRUCT*)lpContext,sizeof(COPYDATASTRUCT));
   if ((cds!=NULL)&&(g_pIPC!=NULL))
   {   
       g_pIPC->OnReceive("",cds->dwData,cds->lpData,cds->cbData);
   }

   delete []cds;
   AfxEndThread(0);
   return 0;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   
   switch (message)
   {  
      case WM_COPYDATA:
  CString appName = AfxGetAppName();
  //因为只有应用模块发送消息的时候才会阻塞,而且如果显示模块也用线程的话,那每个线程都带有一个显示屏幕。
  //不好处理。通信模块需要自己给自己发送消息,所以如果创建线程的后,就涉及到线程间通信的问题,所以这两个
  //模块没有用线程。实际证明也不需要。
  if (appName.Compare("通信模块")==0 || appName.Compare("显示模块")==0) //
  {   
   COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam;
   if ((cds!=NULL)&&(g_pIPC!=NULL))
   {
                           g_pIPC->OnReceive("",cds->dwData,cds->lpData,cds->cbData);
   }
  }
  else
  {
      AfxBeginThread(Thread_Process,(COPYDATASTRUCT*)lParam);
  }
 
     return 0; 
   }
   return DefWindowProc(hwnd, message, wParam, lParam);

你可能感兴趣的:(多个窗口收发WINDOW消息阻塞的一点思考)