在Windows操作系统里,当窗口显示之后,它就可以接收到系统源源不断地发过来的消息,然后窗口就需要处理这些消息,因此就需要一个函数来处理这些消息。在API里定义了一个函数为回调函数,当系统需要向窗口发送消息时,就会调用窗口给出的回调函数WindowProc,如果WindowProc函数不处理这个消息,就可以把它转向DefWindowProc函数来处理,这是系统的默认消息处理函数。当你按下菜单,或者点击窗口时,窗口需要运行这个消息处理函数。
函数WindowProc声明如下:
LRESULT CALLBACK WindowProc( HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
hwnd是当前窗口的句柄。
uMsg是系统发过来的消息。
wParam是消息参数。
lParam是消息参数。
这个函数一定是静态函数,也就是全局函数,在编译时已经确定了地址。由于它需要设置在注册的窗口类型里,如下:
// First.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
HINSTANCE hinst;
TCHAR szTitle[] = "这是一个测试窗口"; //定义窗口标题
TCHAR szWindowClass[] = "szClassName"; // 定义窗口类名
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //申明消息处理回调函数
ATOM MyRegisterClass(HINSTANCE hInstance); // 申明注册函数: MyRegisterClass()
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MyRegisterClass(hInstance); //用写好的注册函数注册
InitInstance(hInstance, SW_SHOWNORMAL); //调用写好的初始华函数
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex; //定义一个窗口结构的对象wcex
wcex.cbSize = sizeof(WNDCLASSEX); //设置窗口结构的大小
wcex.style = CS_HREDRAW | CS_VREDRAW; //设置窗口类型
wcex.lpfnWndProc = WndProc; //设置窗口消息处理函数WndProc
wcex.cbClsExtra = 0; //设置窗口类型的扩展为空
wcex.cbWndExtra = 0; //设置窗口类型的扩展为空
wcex.hInstance = hInstance; //设置窗口当前实例句柄
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); //设置窗口图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //设置光标为箭头
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置窗口背景颜色
wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); //设置窗口菜单这里设置为空也可用MAKEINTRESOURCE(菜单ID)取到
wcex.lpszClassName = szWindowClass; //设置窗口类名
wcex.hIconSm = NULL; //设置窗口小图标可用LoadIcon(wcex.hInstance, MAKEINTRESOURCE(图标ID))取到
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hinst = hInstance;
HWND hWnd;
hWnd = CreateWindow(szWindowClass, // szWindowClass是窗口注册名称
szTitle, // 窗口显示的标题
WS_OVERLAPPEDWINDOW, // 窗口显示类型
CW_USEDEFAULT, // 缺省的左上角坐标
CW_USEDEFAULT, // 窗口左上角坐标,由于X坐标设置为缺省的坐标了
CW_USEDEFAULT, // 设置窗口的宽度。使用缺省值
CW_USEDEFAULT, // 设置窗口的高度
NULL, // 父窗口设置为无
NULL, // 主菜单设置为无
hInstance, // 窗口当前实例句柄
NULL); // 传递给窗口的自定义参数
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) //编写消息处理回调函数
{
int wmid,wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch(uMsg)
{
case WM_COMMAND:
wmid = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 菜单选项命令响应
switch(wmid)
{
case IDM_ABOUT:
DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, NULL);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
了窗口消息处理函数,就可以响应不同的消息,实现各种各样的功能。