我觉得应该花点时间熟悉一下windows编程了,不然项目的代码没法看啊。今天在家,实现了一个简单的接收消息的windows窗口,可以接收其他进程发送过来的消息。
《windows程序设计》开头就讲了一个windows程序的基本框架,该例程创建了一个可视的窗口,步骤还挺多的。如果创建的窗口仅用于接收消息,那就简单得多,不需要我们注册一个自定义的WNDCLASS,也不需要将界面显示出来。
先看一下CreateWindow的帮助文档:
http://msdn.microsoft.com/en-us/library/ms632679.aspx
lpClassName可以自己注册,也可以用系统预定义的,我在程序中用的是STATIC,如果这个参数填一个不存在的classname,那么CreateWindow会返回NULL。用户可以自定义消息,需要从WM_USER开始定义,而且处理消息和发送消息的进程都需要知道这份定义。WndProc是窗口处理函数,是通过SetWindowLong向窗口注册的。我写的WndProc只处理了WM_USER + 100和WM_USER + 200消息,其他的消息委托给DefWindowProc处理。
#include <tchar.h>
#include <windows.h>
#include <iostream>
using namespace std;
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR szText[MAX_PATH] = {0};
_stprintf(szText, _T("wParam=%d lParam=%d"), wParam, lParam);
switch(message)
{
case WM_USER + 100:
OutputDebugString(_T("WM_USER + 100"));
OutputDebugString(szText);
return 0;
case WM_USER + 200:
OutputDebugString(_T("WM_USER + 200"));
OutputDebugString(szText);
PostQuitMessage(0);
return 0;
default:
OutputDebugString(_T("default"));
OutputDebugString(szText);
break;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hWnd = CreateWindow(
_T("static"),
_T("MsgRecv"),
WS_OVERLAPPEDWINDOW,,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL);
if(hWnd != NULL && IsWindow(hWnd))
{
SetWindowLong(hWnd, GWL_WNDPROC, (LONG) WndProc);
}
MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
发送消息的进程实现比较简单,先FindWindow找到窗口句柄,然后在SendMessage即可。在如下代码中,我每隔10ms发送一个WM_USER + 100消息,发送100次后,我发送一个WM_USER + 200让接收消息的窗口退出。
#include<windows.h>
#include<tchar.h>
#include<iostream>
using namespace std;
int main()
{
HWND hWnd = ::FindWindow(_T("static"), _T("MsgRecv"));
if (hWnd)
{
for (int i = 1; i <= 100; i++)
{
::SendMessage(hWnd, WM_USER + 100, WPARAM(i), NULL);
Sleep(10);
}
::SendMessage(hWnd, WM_USER + 200, NULL, NULL);
cout << "finish send" << endl;
}
else
{
cout << "hwnd is null" << endl;
}
return 0;
}
这样一个接收消息的窗口程序就完成了。先运行创建窗口的进程,再运行发送消息的进程,在DebugView中就能够看到效果啦。
这个例子有很多应用场景,比如在客户端UI中,需要显示一个扫描线程的进度,其中,扫描进程用SendMessage上报进度,UI线程创建一个窗口接收进度信息,并在WndProc中做UI相关的显示。
来源:oschina
链接:https://my.oschina.net/u/1453800/blog/299765