正文

第三课:MFC思想2007-09-22 12:55:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/29595.html

分享到:

第三课:MFC思想 学完第一课的Windows程序运行原理及第二课经典C++知识回顾,这一课我们主要来看看MFC是如何用面向对象的方式对传统的面象过程的Windows程序运行原理代码进行封装的。 先看看第一课中的Winmain()代码 int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {        WNDCLASS wndClass;        wndClass.style=CS_HREDRAW;        wndClass.lpfnWndProc=(WNDPROC)DefWndProc;        wndClass.cbClsExtra=0;        wndClass.cbWndExtra=0;     wndClass.hInstance=hInstance;        wndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));        wndClass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));        LOGBRUSH lgbr;        lgbr.lbStyle=BS_SOLID;        lgbr.lbColor=RGB(192,192,0);        lgbr.lbHatch=0;        wndClass.hbrBackground=CreateBrushIndirect(&lgbr);        wndClass.lpszMenuName=NULL;     wndClass.lpszClassName="xxxxx";        RegisterClass(&wndClass);        HWND hWnd;        hWnd=CreateWindow("xxxxx","http://www.it315.org",WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX ,\        CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);        ShowWindow(hWnd,nCmdShow);        MSG msg;        while(GetMessage(&msg,NULL,0,0))        {            TranslateMessage(&msg);            DispatchMessage(&msg);        }        return true; }        在该段代码中,主要由三大部分组件,即设计窗口阶段(由WNDCLASS结构描述部分)、窗口的注册及创建显示过程、消息循环部分。以上的代码是标准的C语言代码,是面向过程的。在MFC中采用了面向对象的思想,即用面向对象的C++思想对以上代码进行了封装,也就是说将一些对窗口进行操作的API的函数封装到了一个类中,以下我将用简短的代码来演示一下这个过程: class CIt315Wnd { public:        HWND m_hWnd;        BOOL Create();        BOOL ShowWindow(); }; BOOL CIt315Wnd::Create() {        WNDCLASS wndClass;        wndClass.style=CS_HREDRAW;        wndClass.lpfnWndProc=(WNDPROC)DefWndProc;        wndClass.cbClsExtra=0;        wndClass.cbWndExtra=0;     wndClass.hInstance=hInstance;        wndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));        wndClass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));          LOGBRUSH lgbr;        lgbr.lbStyle=BS_SOLID;        lgbr.lbColor=RGB(192,192,0);        lgbr.lbHatch=0;               wndClass.hbrBackground=CreateBrushIndirect(&lgbr);        wndClass.lpszMenuName=NULL;     wndClass.lpszClassName="xxxxx";        RegisterClass(&wndClass);        HWND hWnd;        m_hWnd=CreateWindow("xxxxx","http://www.it315.org",WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX ,\        CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);          if(m_hWnd!=NULL)               return true;        else               return false; } BOOL CIt315Wnd::ShowWindow() {        return ShowWindow(hWnd,nCmdShow); } 为了保证代码和以前的执行方式一样,Winmain()函数可以写成如下形式: int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {        CIt315Wnd m_wnd;        m_wnd.Create();        m_wnd.ShowWindow();        MSG msg;        while(GetMessage(&msg,NULL,0,0))        {            TranslateMessage(&msg);            DispatchMessage(&msg);        }        return true; } 此时,如果再写一个新的类来对剩下的代码进行封装,代码如下: class CIt315App { public:        CIt315Wnd* m_pMainWnd;        BOOL InitInstance();        BOOL Run();        CIt315App(); };   CIt315App::CIt315App() {        if(InitInstance())               Run(); } BOOL CIt315App::InitInstance() {        CIt315Wnd m_wnd;        m_pMainWnd=&m_wnd;        m_pMainWnd->Create();        m_pMainWnd->ShowWindow();        return true; } BOOL CIt315App::Run() {        MSG msg;        while(GetMessage(&msg,NULL,0,0))        {            TranslateMessage(&msg);            DispatchMessage(&msg);        }        return true;     } 此时,在Winmain()函数中仅仅只需要写如下几行代码了,而且对于每个程序来说都是一样,既然如此,那每个程序都这样,微软就把这部分代码为我们写好了,所以,在我们的MFC的工程里,看不到Winmain()的函数。   CIt315App theApp; //全局变量 int PASCAL WinMain(HINSTANCE m_hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {        hInstance=m_hInstance; }        因为theApp是一个全局变量,它的构造函数会自动的被调用,所以以上的代码就跟我们在第一课看到的代码的执行逻辑一样。加上Winmain()函数不用我们自己来写,所以要求我们写的类也就只有一个CIt315App类了,由于所有的应用程序的Run()函数都一样,也可以采用一个新的基类来实现Run()然后它的子类就自动的从它继承,也就是说其子类不用实现Run()函数了,也就是说 ,对我们的一般程序设计用户而言,在子类中仅仅只需要实现一个InitInstance()函数即可。而且此时,在我们一般的程序设计用户代码中,程序首先执行Initialize()函数。这也就是MFC程序的入口点。 此时代码演示如下: class CMyWinApp { public:        CIt315Wnd* m_pMainWnd;        BOOL Run(); }; BOOL CMyWinApp::Run() {        MSG msg;        while(GetMessage(&msg,NULL,0,0))        {            TranslateMessage(&msg);            DispatchMessage(&msg);        }        return true;     } class CIt315App:public CMyWinApp { public:        CIt315App();        BOOL InitInstance(); }; CIt315App::CIt315App() {        if(this->InitInstance())               Run(); } BOOL CIt315App::InitInstance() {        CIt315Wnd m_wnd;        m_pMainWnd=&m_wnd;        m_pMainWnd->Create();        m_pMainWnd->ShowWindow();        return true; }   CIt315App theApp;   int PASCAL WinMain(HINSTANCE m_hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {        hInstance=m_hInstance; }       以上代码和变换仅仅只是一个代码游戏,但却反应了MFC的一种包装的思想,没有从本质上改变Windows程序的运行原理,但就是这种变换方便了我们的编程。在以上这些代码中,CIt315Wnd已经由MFC实现类名为CWnd,CMyWinApp在MFC中类名为CWnApp。        以上代码仅仅只是对Winmain()函数的包装,对于消息处理部分同样也有类似的包装,在此不多举例。  

阅读(4875) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册