eVC编程遇到的各种问题之——进程之间的通讯

本文介绍了在编程中遇到的进程间通讯问题,采用发送COPYDATA消息的方式,详细描述了从获取主进程句柄到实现通讯的整个过程,包括EnumWindows函数和回调函数的使用,以及在静态函数中处理句柄的错误和自定义消息的不稳定情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在做个程序,要读取串口数据、提取、分析、显示。在程序执行时要调用串口程序,因此要读取到串口进程的数据。这就涉及了所谓进程间的通讯了~~

 

进程间的通讯方法有多种,就选了个比较简单的,发送COPYDATA消息的方法来实现。调用串口进程后,每每串口接收到数据后,向主进程发送COPYDATA消息,主进程在接到消息后进行处理。

 

现在将遇到的问题和解决的办法总结下~~备忘……

 

问题一:如何在子进程(串口进程)中获得主进程的句柄

 

尝试1:

开始的时候我是想在串口程序的主窗口处理中调用GetWindowThreadProcessId函数的,以为知道当前窗口,就能得到创建当前窗口的进程ID号。但是试过了发现,返回的进程ID号其实还是串口进程的ID号。想想也是~~串口进程的窗口必然是串口进程创建了后再创建的么~~~虽然“此路不通”,但是也学会了GetWindowThreadProcessId的用法。

 

尝试2: 

在创建串口进程的时候,把主进程的句柄作为一个信息传递给串口进程,这样子进程就知道主进程的窗口句柄了。不过问题又来了——那个串口进程的窗口句柄怎么知道呢?~~~⊙﹏⊙b汗

好在知道子进程的句柄和ID号,看看能不能通过这个句柄和ID号得到其主窗口的句柄吧~~

 

尝试3:

查到网上http://blog.youkuaiyun.com/vcforever/archive/2005/03/11/317498.aspx一篇文章,正好是解决这个问题的。偷来用~

其实说的简单点就是使用EnumWindows函数,枚举出所有的符合主窗口条件的上层窗口,然后通过GetWindowThreadProcessId函数获得窗口所属的进程ID,如果所得到的进程ID和已知的进程ID相同,就说明该窗口是这个进程的一个主窗口。

 

这里学习了下EnumWindows函数的用法,参照http://topic.youkuaiyun.com/t/20020705/12/852259.html,自己做个总结~

EnumWindows函数的原型如下: 

BOOL   EnumWindows(WNDENUMPROC   lpEnumFunc,   //   callback   function   
                                     LPARAM   lParam                         //   application-defined   value )  

第一个参数是回调函数的指针,第二个是我们自己选择传递的参数(可选可不选)

 

这个函数的内部实现如下:

  BOOL   EnumWindows(WNDENUMPROC   lpEnumFunc,  LPARAM   lParam)  
  {  
          BOOL   bContinue;  
          HWND   hwnd   =   GetNextWindow(   NULL,   GW_HWNDNEXT   );  
          for(   ;hwnd   !=   NULL   ;   )  
          {  
                  bContinue   =   lpEnumFunc(   hwnd,   lParam   );  
                  if(   !bContinue   )   return   TRUE;  
                  hwnd   =   GetNextWindow(   hwnd,   GW_HWNDNEXT   );    
          }  
          return   TRUE;  
  }

其实就是不断的寻找下一个窗口,每找到一个,就把窗口句柄传递给回调函数,并调用一次回调函数。直到找到所有的窗口,或者回调函数的返回值为FALSE为止。

 

回调函数的形式如下:

BOOL   CALLBACK   EnumWindowsProc(HWND   hwnd,LPARAM   lParam)     
{    
     DWORD ProcessId = 0;
     // 根据窗口句柄,得到进程标识
     if (!GetWindowThreadProcessId(hwnd, &ProcessId))
     {
          return TRUE;
     }
     AfxMessageBox(_T("%x,%x",hwnd,ProcessId));

     //查找进程标识和所找的进程标识是否相同
     if (lParam == ProcessId)
     {
          h_WinSerialPort = hwnd;
          return FALSE;
     }
     //继续列举窗体
     return TRUE;

}  

尝试4:

不幸的是,在编译的时候,出现了新的错误。大意是说在静态函数中h_WinSerialPort = hwnd;这么赋值是不对的。

http://www.sunxin.org/forum/thread/2728.html;jsessionid=6488FB6F7CDA7D959D0FE271A4F5CCFA中也遇到了类似的情况,后来把HWND h_WinSerialPort;定义为全局变量后,编译通过了。

 

对于static变量,了解的还比较多,但是说到static函数,就有点陌生了~~在这里学习了static函数的用法。http://blog.youkuaiyun.com/zhy05/archive/2007/06/09/1646104.aspx

 

尝试5:

现在,通过EnumWindows及其回调函数,可以找到串口进程的窗口句柄,但是发送WM_COPYDATA消息,仍旧毫无反应……

为排除错误,把进程之间的消息传递改到统一进程下仍旧没有相应。但是同样的自定义消息,却可以响应~~~不知道为什么,待解……

 

那就先用好用的办法,自定义了一个消息WM_MYWORK,用它来作为两进程之间传递的消息类型。不过奇怪的是,有的时候好用,有的时候不好用,不解~~~

 

 

 

待续…… 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值