C++笔记002 MFC框架理解

一 Win32窗口程序创建过程

#include <Windows.h>

//消息处理回调函数
LRESULT CALLBACK MessageWindowProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch (msg)
    {
    case WM_CLOSE:
        PostQuitMessage(0); //发送一条WM_QUIT给系统,入口函数中,while一旦接受到该消息,就马上退出程序
        break ;
    }
    return DefWindowProc(hwnd,msg,wParam,lParam); //调用默认的消息处理函数
}

INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE pInstance,LPSTR cmdLine,int nShow  ) {

    //1 设计窗体类
    //2 注册窗体类
    //3 创建窗体
    //4 显示窗体
    //5 更新窗体

    //设计窗体类
    WNDCLASSEX wndclass;
    wndclass.cbClsExtra = 0;                            //不需要窗口额外的存储空间
    wndclass.cbSize = sizeof(WNDCLASSEX);                //结构体大小
    wndclass.cbWndExtra = 0;                            //不需要为窗口准备额外的存储空间
    wndclass.hbrBackground = NULL;                        //不需要有背景,不需要有任何东西
    wndclass.hCursor =LoadCursor(NULL,IDC_ARROW) ;        //第一个参数
    wndclass.hIcon = NULL;                                //exe程序在文件夹中显示的图标
    wndclass.hIconSm = NULL;                            //程序运行后的窗口图标
    wndclass.hInstance = hInstance;                        //代表当前程序的实例,程序启动后,系统自动赋值了
    wndclass.lpfnWndProc = MessageWindowProc;                //消息相应回调函数
    wndclass.lpszClassName = L"MyWinForm";                //窗口ID,使用UNICODE环境,注意创建窗口的时候所填写的必须跟这里保持一模一样
    wndclass.lpszMenuName = NULL;               //Menu
    wndclass.style = CS_VREDRAW|CS_HREDRAW;     //样式

    //注册窗体类
    ATOM atom = RegisterClassEx(&wndclass);   //注册类
    if (!atom){
        return 0;
    }

    //创建窗体
    HWND hwnd = CreateWindowEx(NULL, L"MyWinForm", L"我的应用程序", WS_OVERLAPPEDWINDOW,
        100, 100, 800, 600, NULL, NULL, hInstance, NULL); //位置,大小,没有父窗口,没有菜单,程序实例,没有额外参数

    //显示窗体
    ShowWindow(hwnd,SW_SHOW);
    //更新窗体
    UpdateWindow(hwnd);

    // 通过死循环,让程序不退出
    MSG msg;
    while (true) { 
        if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)){ //如果拿到一条消息,这条消息是从所有地方获取所有消息,PM_REMOVE不要给任何过滤,抓到消息后,把该消息从消息顶端移除掉
            //获取消息后开始处理消息,如果是退出消息 从回调函数获取消息
            if (msg.message == WM_QUIT){
                break;
            }            
            TranslateMessage(&msg); //如果不是退出消息就转换该消息
            DispatchMessage(&msg);  //把该消息派发给消息处理函数
        }
    }
    return 0;
}

二   MFC中的WinMain在哪儿?

  MFC中不能直接看到WinMain函数,因为它被封装在 x:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\src\mfc\appmodul.cpp ] 中,_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, int nCmdShow)  _tWinMain是一个在 tchar.h中定义的宏: #define _tWinMain   WinMain,它在编译的时候直接被替换成了WinMain文本了。

      如何执行到WinMain的?在生成的项目中,解决方案资源管理器中,有一个以工程名字命名的头文件,在头文件中声明了一个全局变量  extern xxxxApp theApp;  其中一个带App的类(类名是项目名称XXXX与APP的组合),双击带有App后缀的类,可以在该文件中看到 theApp的定义,它代表了该应用程序。注: extern int theApp; //声明theApp而非定义,这时候它还没有内容的,也没有分配空间,它放在类外,表示一个全局的变量 如果赋值则表示定义 ,注意 theApp在类视图双击打开后的cpp文件中被定义,此时它成了一个有血有肉的具体对象了。由于它是全局的(保存在全局数据区域),程序一开始就先于WinMain函数执行执行初始化工作。由于它是一个全局对象,需要系统调用它的构造函数去分配空间。

  由于xxxxApp类继承了CWinApp类;CWinApp在一个单文档应用程序中的子类有且仅有一个,而theApp又是xxxxApp类的一个唯一对象,因此theApp就代表了应用程序本身。一个子类的构造一个对象的时候,需要先调用父类的构造器,先构造父类对象,如果当前子类还有个爷爷类,则要先构造爷爷,完成后构造父类对象,最后才构造自身。

       CWinApp 有一个构造函数explicit CWinApp( LPCTSTR lpszAppName = NULL); 基类如果有带参数构造器的,派生类应该去调用父类带参构造函器,在这里派生类xxxxApp的构造函数没有带参数,但如何显示的去传递值也能构造父类,原因就在于CWinApp的构造函数有一个缺省NULL;因此在构造的时候不用传递一个值也可以。

  _tWinMain()返回 return AfxWinMain(hInstance,pInstance,cmdLine,nShow); AfxWinMain()定义在WINMAN.CPP文件中,AfxWinMain函数内包括一个CWinApp *pApp=AfxGetApp();获取到theApp;theApp什么时候被传入的?它在CWinApp的构造器中由 pThreadState->m_pCurrentWinThread = this; 传入,具体打开 appcore.cpp中CWinApp中可以看到。获取到了theApp对象后,通过调用它的InitApplication()app内部管理函数,接着调用,InitInstance()等一系列函数完成设计,注册(WINCORE.CPP中的AfxEndDeferRegisterClass()实现),AfxEndDeferRegisterClass()里面预定义了多个窗口类,并在InitInstance的时候完成。

  创建窗口通过 class CMainFrame : public CFrameWnd  这个类来实现。它是以框架窗口,View类形成客户区。具体CMainFrame中 先于Create之前调用PreCreateWindow(WINFRM.CPP中PreCreateWindow())检查是否注册,没有注册则重新注册.如果注册了,开始首先调用(WINCORE.CPP中的CreateEx)Create();

CWnd显示,更新,通过调用(THRDCORE.CPP)CWinThread::Run() CWinThread::PumpMessage()实现消息循环。

  DOC与View实现显示\逻辑分开. App.InitInstance(DOC+VIEW+CMainFrame)组装在一起了。

猜你喜欢

转载自www.cnblogs.com/zhou8744/p/10404378.html