转了一个大圈,我们仿佛又回到了SDK编程的开始。但现在我们现在能清楚地知道,表面上MFC与SDK编程截然不同,但实质上MFC只是用类的形式封装了SDK函数,封装之后,我们在WinMain()函数中只需要几行代码,就可以完成一个窗口程序。我们也由此知道了应如何去封装应用程序类(CWinApp)和主框架窗口类(CFrameWnd)。下面把上开始设计这两个类。
为了简单起见,我们忽略这两个类的基类和派生类的编写,可能大家会认为这是一种很不负责任的做法,但本人觉得这既可减轻负担,又免了大家在各类之间穿来穿去,更好理解一些(我们在关键的地方作注明)。还有,我把全部代码写在同一个文件中,让大家看起来不用那么吃力,但这是最不提倡的写代码方法,大家不要学哦!
#include <windows.h> HINSTANCE hInstance; class CFrameWnd { HWND hwnd; public: CFrameWnd(); //也可以在这里调用Create() virtual ~CFrameWnd(); int Create(); //类就留意这一个函数就行了! BOOL ShowWnd(); }; class CWinApp1 { public: CFrameWnd* m_pMainWnd;//在真正的MFC里面 //它是CWnd指针,但这里由于不写CWnd类 //只要把它写成CFrameWnd指针 CWinApp1* m_pCurrentWinApp;//指向应用程序对象本身 CWinApp1(); virtual ~CWinApp1(); virtual BOOL InitInstance();//MFC原本是必须重载的函数,最重要的函数!!!! virtual BOOL Run();//消息循环 }; CFrameWnd::CFrameWnd(){} CFrameWnd::~CFrameWnd(){} int CFrameWnd::Create() //封装创建窗口代码 { WNDCLASS wndcls; wndcls.style=0; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); wndcls.hIcon=LoadIcon(NULL,IDC_ARROW); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=DefWindowProc;//默认窗口过程函数。 //大家可以想象成MFC通用的窗口过程。 wndcls.lpszClassName=”窗口类名”; wndcls.lpszMenuName=NULL; RegisterClass(&wndcls); hwnd=CreateWindow(“窗口类名”,”窗口实例标题名”,WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL); return 0; } BOOL CFrameWnd::ShowWnd()//显示更新窗口 { ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); return 0; } ///////////// CWinApp1::CWinApp1() { m_pCurrentWinApp=this; } CWinApp1::~CWinApp1(){} //以下为InitInstance()函数,MFC中要为CWinApp的派生类改写, //这里为了方便理解,把它放在CWinApp类里面完成! //你只要记住真正的MFC在派生类改写此函数就行了。 BOOL CWinApp1::InitInstance() { m_pMainWnd=new CFrameWnd; m_pMainWnd->Create(); m_pMainWnd->ShowWnd(); return 0; } BOOL CWinApp1::Run()//////////////////////封装消息循环 { MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } //////////////////////////////////////////////////////封装消息循环 CWinApp1 theApp; //应用程序对象(全局) int WINAPI WinMain( HINSTANCE hinst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { hInstance=hinst; CWinApp1* pApp=theApp.m_pCurrentWinApp; //真正的MFC要写一个全局函数AfxGetApp,以获取CWinApp指针。 pApp->InitInstance(); pApp->Run(); return 0; } |
代码那么长,实际上只是写了三个函数,一是CFrameWnd类的Create(),第二个是CWinApp类的InitInstance()和Run()。在此特别要说明的是InitInstance(),真正的MFC中,那是我们跟据自己构造窗口的需要,自己改写这个函数。
大家可以看到,封装了上面两个类以后,在入口函数WinMain中就写几行代码,就可以产生一个窗口程序。在MFC中,因为WinMain函数就是固定的那么几行代码,所以MFC绝对可以帮我们自动完成(MFC的特长就是帮我们完成有规律的代码),所以我们创造MFC应用程序的时候,看不到WinMain函数。
写到这里,MFC六大关键技术之一:MFC程序的初始化过程(模拟),就差不多写完了。回头看一下,居然写了八千多字,原本以为写完六大关键技术也不用写那么多字,现在还觉得庆幸的是不把文档、视类牵连进去,否则更不知写到何时。
还有五大关键技术没有写,我还应该写下去吗?上面写了八千多字,都是我一个字一个字地敲进去,每个例子都是自己生硬地想出来。用了十多个小时,换来的可能更多是论坛中朋友们的漫骂,讥讽!
但我觉得还是值得的,我一向认为VC没有敌人,只有朋友,放眼周围,发觉学VC的朋友越来越少,也没有发现多少招收VC程序员的地方。记得读大学的时候,我遇到一位搞美术的师兄,本来同行如敌国(我曾经搞过美术)。师兄美术功底很好,但他从来没有在学校获过美术一等奖,原因评奖的不懂得欣赏他的作品。我的出现,他深刻地体会到了:多一个朋友,会少一分孤独!有时觉得学习VC的朋友是英雄(但我不是英雄,因为我学VC多年来无甚突破),是值得尊敬的人物,大家交流一下,纠正一下自己的错误,真是一种福份……
>> 本文固定链接: http://www.vcgood.com/archives/1257