MFC是Miscrosoft Foundation Classes的缩写,是微软对Windows API的封装,所以要学习MFC,首先要对Win32程序有一个基本的了解,下面用一个例子来说明Win32程序的基本结构。
上面的程序要点可以规纳如下:
1、设置窗体类的各个属性并注册此窗体类。
2、定义窗体类的消息处理函数。
3、根据注册的窗体类来创建应用程序的窗体。
上面的代码确实比直接使用WIN32 API要简单很多。但是对比第一个程序中的要点,我们原来总结的要点在这里却再也找不到对应了。
//test1.cpp
//编译:cl /EHsc test1.cpp user32.lib
#include <windows.h>
CHAR g_appName[] = "TestWin32";
//消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam);
//错误输出函数
void ErrorOutput();
//主入口函数
int WinMain(HINSTANCE hInst,HINSTANCE hPreInst,LPSTR lpCmd,int iCmdShow)
{
//定义窗体类,最主要的是定义了窗体类的消息处理函数入口
WNDCLASS wc;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WndProc;//指定消息处理函数入口
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wc.lpszMenuName = NULL;
wc.lpszClassName = g_appName;
//在注册表中注册上面定义的窗体类
if(!RegisterClass(&wc))//user32.lib
{
ErrorOutput();
return -1;
}
//利用前面定义的窗体类来创建窗体对象
HWND hWnd = CreateWindow(g_appName,"Test",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInst,NULL);
if(hWnd == NULL)
{
ErrorOutput();
return -1;
}
//显示窗体对象
ShowWindow(hWnd,iCmdShow);
UpdateWindow(hWnd);
MSG msg;
//开始消息处理循环
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
switch(nMsg)
{
//关闭窗口时要发送WM_QUIT,否则不能结束进程
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
//使用默认的消息处理函数
return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
void ErrorOutput()
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
MessageBox(NULL,(LPCTSTR)lpMsgBuf,"Error",MB_OK);
LocalFree(lpMsgBuf);
}
上面的程序要点可以规纳如下:
1、设置窗体类的各个属性并注册此窗体类。
2、定义窗体类的消息处理函数。
3、根据注册的窗体类来创建应用程序的窗体。
4、显示注册的窗体并开始消息循环。
因为MFC对上面的过程进行了封装,所以在MFC程序中,上面大部分的过程我们是看不见的。但为了能随心所欲的使用MFC(或许更大程度上是满足我们的好奇心(∩_∩)),我们就需要弄清楚MFC程序和上面的程序中各个过程的对应关系。
下面我们在来看一个使用MFC的封装库完成的简单的窗体程序。
///
//file:test2.cpp
//编译:cl /c /EHsc test2.cpp
//连接:link /SUBSYSTEM:WINDOWS test2.obj
#include <afxwin.h>
class MyApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
class MyFrame : public CFrameWnd
{
public:
MyFrame();
};
MyFrame::MyFrame()
{
Create(0,_T("My App"));
}
BOOL MyApp::InitInstance()
{
m_pMainWnd = new MyFrame();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return true;
}
MyApp g_app;
///
上面的代码确实比直接使用WIN32 API要简单很多。但是对比第一个程序中的要点,我们原来总结的要点在这里却再也找不到对应了。
MFC到底做了什么?注册窗体、创建窗体和消息循环等过程都在哪里?带着上面的这些疑问,让我们来剖析上面的这个“简单的”MFC程序吧!
上面的内容主要只是让一个WIN32程序和MFC程序运转起来。
*上面内容均在侯俊杰先生的《深入浅出MFC》中有细致规范的说明。