首页 > 代码库 > 创建接收消息的windows窗口

创建接收消息的windows窗口

我觉得应该花点时间熟悉一下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相关的显示。