正文

第三课: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实现类名为CWndCMyWinAppMFC中类名为CWnApp

       以上代码仅仅只是对Winmain()函数的包装,对于消息处理部分同样也有类似的包装,在此不多举例。


 

阅读(4657) | 评论(0)


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

评论

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