在做个程序,要读取串口数据、提取、分析、显示。在程序执行时要调用串口程序,因此要读取到串口进程的数据。这就涉及了所谓进程间的通讯了~~
进程间的通讯方法有多种,就选了个比较简单的,发送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,用它来作为两进程之间传递的消息类型。不过奇怪的是,有的时候好用,有的时候不好用,不解~~~
待续……