不得不承认使用MFC编程很方便,但是熟练掌握、运用MFC需要,并且了解MFC的实现原理并不是一件容易的事,了解其实现机制将会给我们编程过程带来更大的自由度,现在我们就来窥其究竟,以解知其然而不知其所以然的疑惑。
简单的讲,MFC就是在windows编程的基础上,对Windows函数进行了重新组织、封装,以便程序员们使用更方便,所以我们就需要windows程序的实现机制。
每一个windows程序都有一个入口函数WinMain(),windows程序基本遵循以下几个步骤:
1.定义窗口类。
2.注册窗口类。
3.利用注册的窗口类产生窗口。
4.显示窗口。
5.进入消息循环。
以上四个过程都是在WinMain()函数内进行的,尤其需要注意一点的是,每一个窗口类都和一个窗口过程函数相关联,而窗口过程函数恰恰负责对各种消息的响应。
下面给出代码,代码对关键点进行了注释,与各位分享。
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //声明窗口过程函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreinstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("HelloWin"); HWND hwnd; MSG msg; WNDCLASS wndclass; //窗口类结构体变量 wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; //用窗口过程函数名初始化窗口类的成员变量,由此窗口类和窗口过程函数联系了起来 wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; //窗口类的名字 RegisterClass(&wndclass); //注册窗口类 hwnd = CreateWindow(szAppName, //利用窗口类的名字作为CreatWindow的参数来创建窗口,从而窗口和窗口类联系了起来 TEXT("The hello program"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); //显示窗口 UpdateWindow(hwnd); while(GetMessage(&msg, NULL, 0, 0)) //从消息循环队列中不断的取消息并交由窗口过程函数进行处理 { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) //窗口过程函数的实现 { HDC hdc; PAINTSTRUCT ps; RECT rect; switch(message) { case WM_CREATE: PlaySound( TEXT("HELLOWIN>WAV"), NULL, SND_FILENAME | SND_ASYNC ); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); DrawText(hdc, TEXT("Hello,Windows98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); //窗口过程函数没有处理的消息交给默认窗口函数 }
大家不必为弄清楚每个变量的具体含义,只需看明白关键变量的传递,以及整个窗口产生、消息处理的机制就可以了。
总而言之,就是以窗口类为中间桥梁,将产生的窗口和窗口过程函数关联了起来,而由操作系统负责提取消息,并调用窗口过程函数来完成消息响应。