• WinMain和MFC的差别


    API(Application Programming Interface):开放给应用程序调用的系统功能。


    一个Windows Application(SDK):
    WinMain
    ReristerClass
    CreateWindow
    GetMessage/DispatchMessage
    /Window Procedure
    various Windows APIs
    一个MFC Application:
    WinMain由MFC提供
    RegisterClass包装于AfxWinInit中
    CreateWindow在CWinApp::InitInstance中调用
    GetMessage/DispatchMessage包装在CWinApp::Run中
    Window Procedure由MFC提供
    Windows APIs包装在MFC各类中
    Massage Mapping, Message Routing.
    Dynamic Creation, Serialization.
    CWinApp代表程序本体——代替WndProc
    传统上SDK程序的WinMain所完毕的工作如今由CWinAoo的三个函数完毕:
    virtual BOOL InitApplication();
    virtual BOOL InitInstance();
    virtual int Run();
    WinMain仅仅是扮演驾驶它们的角色。


    传统的SDK窗体函数写法是:

    long FAR PASCAL WndProc(HWND hWnd, UINT msg, WORD wParam, LONG lParam)
    {
    	switch(msg) {
    		case WM_COMMAND :
    			swtich(wParam) {
    				case IDM_ABOUT :
    					OnAbout(hWnd, wParam, lParam);
    					break;
    			}
    			break;
    		case WM_PAINT :
    			OnPaint(hWnd, wParam, lParam);
    			break;
    		default :
    			DefWindowProc(hWnd, msg, wParam, lParam);
    	}
    }


    MFC中使用两个函数OnPaint(),OnAbout()与其相应。MFC中的声明例如以下:
    class CMyFrameWnd : public CFrameWnd
    {
    public :
    	CMyFrameWnd();
    	afx_msg void OnPaint();
    	afx_msg void OnAbout();
    	DECLARE_MESSAGE_MAP()
    }


    OnPaint处理WM_PAINT
    OnAbout处理WM_COMMAND和IDM_ABOUT
    MFC内建的一个Message机制。会把消息自己主动送到“与消息相应的特定函数”中去,消息与相应函数之间的相应关系由程序猿指定。DECLARE_MESSAGE_MAP另搭配其他宏,就能够非常便利的将消息与其处理函数关联在一起:
    BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
    ON_WM_PAINT()
    ON_COMMAND(IDM_ABOUT, OnAbout)
    END_MESSAGE_MAP()
    /***********************************************************/
    /*                 WINMAIN.CPP                             */
    /***********************************************************/
    /*  int AFXAPI AfxWinMain (...)                            */
    /*  {                                                      */
    /*  	CWinApp* pApp = AfxGetApp();                       */
    /*  	                                                   */
    /*  	AfxWinInit(...);                                   */
    /*  	                                                   */
    /*  	pApp->InitApplication();                           */
    /*  	pApp->InitInstance();                              */
    /*  	nReturnCode = pApp->Run();                         */
    /*  	                                                   */
    /*  	AfxWinTerm();                                      */
    /*  }                                                      */
    /***********************************************************/
    /*                 HELLO.CPP                               */
    /***********************************************************/
    /*  CMyWinApp theApp;	//application object               */
    /*                                                         */
    /*  BOOL CMyWinApp::initInstance()                         */
    /*  {                                                      */
    /*  	m_pMainWnd = new CMyFrameWnd();                    */
    /*  	m_pMainWnd->ShowWindow(m_nCmdShow);                */
    /*  	m_pMainWnd->UpdateWindow();                        */
    /*  	return TRUE;                                       */
    /*  }                                                      */
    /*                                                         */
    /*  CMyFrameWnd::CMyFrameWnd()                             */
    /*  {                                                      */
    /*  	Create(NULL, "Hello MFC", ..., "MainMenu");        */
    /*  }                                                      */
    /*                                                         */
    /*  void CMyFrameWnd::OnPaint() {...}                      */
    /*  void CMyFrameWnd::OnAbout() {...}                      */
    /*                                                         */
    /*  BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)              */
    /*  	ON_COMMAND(IDM_ABOUT, OnAbout)                     */
    /*  	ON_WM_PAINT()                                      */
    /*  END_MESSAGE_MAP()                                      */
    /***********************************************************/


    Application object:每个MFC应用程序都有一个,并且仅仅有一个。
    WINMAIN.CPP中,AfxGetApp事实上就是取得CMyWinApp对象指针。所以,AfxWinMain中这种操作:
    CWinApp* pApp = AfxGetApp();
    pApp->InitApplication();
    pApp->InitInstance();
    nReturnCode = pApp->Run();
    事实上就相当于调用:
    CMyWinApp::InitApplication();
    CMyWinApp::InitInstance();
    CMyWinApp::Run();
    因而导致调用:
    CWinApp::InitApplication(); //由于CMyWinApp并没有改写InitApplication
    CMyWinAPP::InitInstance(); //由于CMyWinApp改写了InitInstance
    CWinApp::Run(); //由于CMyWinApp并没有改写Run
    AfxWinInit——AFX内部初始化操作
    WinMain一開始即调用AfxWinInit,注冊四个窗体类。


    MFC中也会为我们注冊窗体类,但不再是在AfxWinInit中完毕。
    pApp指向CMyWinApp对象(theApp)。所以,当程序调用:
    pApp->InitApplication();
    CMyWinApp继承自CWinApp,而InitApplication又是CWinApp的一个虚拟函数;若我们并没有改写它(大部分情况下不需改写它),上述操作相当于调用:
    CWinApp::InitApplication();
    与此类似,当程序调用
    pApp->InitInstance();
    相当于调用:
    CMyWinApp::InitInstance();。


    CFrameWnd::Create 产生主窗体(并先注冊窗体类)
    CMyWinApp::InitInstance 一開始new了一个CMyFrameWnd对象,准备用作主框窗体的C++对象。

    new会引发构造函数:
    CMyFrameWnd::CMyFrameWnd()
    {
    Create(NULL, "Hello MFC", WS_OVERLAPPEDWINDOW, rectDefault, NULL, "MainMenu");
    }
    当中,Create是CFrameWnd的成员函数,他将产生一个窗体。


    CFrame::Create的规格:
    BOOL Create(LPCTSTR lpszClassName, //指定WNDCLASS窗体类
    LPCTSTR lpszWindowName, //指定窗体标题
    DWORD dwStyle = WS_OVERLAPPEDWINDOW, //指定窗体风格
    const RECT& rect = rectDefault, //指定窗体的位置与大小
    CWnd* pParentWnd = NULL, //指定父窗体
    LPCTSTR lpszMenuName = NULL, //指定菜单
    DWORD dwExStyle = 0,
    CCreateContext* pContext = NULL ); //指向CCreateContext结构的指针,framework利用它,在具备Document/View结构的程序中初始化外框窗体.
    pApp指向CMyWinApp对象(theApp)。所以,当程序调用:
    pApp->Run();
    相当于调用:
    CMyWinApp::Run();
    把消息与处理函数连接在一起:Message Map机制


    MFC提供给应用程序使用的“非常方便的接口”是两组宏。以Hello的主窗体为例。第一个操作是在HELLO.H的CMyFrameWnd加上DECLARE_MESSAGE_MAP:
    class CMyFrameWnd : public CFrameWnd
    {
    public :
    CMyFrameWnd();
    afx_msg void OnPaint();
    afx_msg void OnAbout();
    DECLARE_MESSAGE_MAP();
    }
    第二个操作是在HELLO.CPP的不论什么位置(当然不能在函数之内)使用宏例如以下:
    BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
    ON_WM_PAINT()
    ON_COMMAND(IDM_ABOUT, OnAbout)
    END_MESSAGE_MAP()


    MFC把消息主要分为三大类。Message Map机制中对于消息与函数间的相应关系也明白下面三种:
      标准Windows消息(WM_xxx)的相应规则:

        |-----------------------------------------------------------------------------|
        |    宏名称         |     相应消息      |   消息处理函数(名称已由系统默认)    |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_CHAR        |    WM_CHAR        |          OnChar                     |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_CLOSE       |    WM_CLOSE       |          OnClose                    |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_CREATE      |    WM_CREATE      |          OnCreate                   |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_DESTROY     |    WM_DESTROY     |          OnDestroy                  |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_LBUTTONDOWN |    WM_LBUTTONDOWN |          OnLButtonDown              |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_LBUTTONUP   |    WM_LBUTTONUP   |          OnLButtonUp                |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_MOUSEMOVE   |    WM_MOUSEMOVE   |          OnMouseMove                |
        |-------------------|-------------------|-------------------------------------|
        | ON_WM_PAINT       |    WM_PAINT       |          OnPaint                    |
        |-----------------------------------------------------------------------------|


      命令消息(WM_COMMAND)的一般相应规则是:
        ON_COMMAND(<id>, <memberFxn>)
        比如:
    ON_COMMAND(IDM_ABOUT, OnAbout)
    ON_COMMAND(IDM_FILENEW, OnFileNew)
    ON_COMMAND(IDM_FILEOPEN,OnFileOpen)
    ON_COMMAND(IDM_FILESAVE,OnFileSave)
      "Notification消息"(由控件产生。比如 BN_xxx)的相应机制的宏分为好几种(由于控件分为好几种),例:
        |-----------------------------------------------------------|
    	|   控件   |              宏名称               |消息处理函数|
    	|----------|-----------------------------------|------------|
    	|  Button  |  ON_BN_CLICKED(<id>,<memberFxn>)  | memberFxn  |
    	|----------|-----------------------------------|------------|
    	| ComboBox |  ON_CBN_DBLCLK(<id>,<memberFxn>)  | memberFxn  |
    	|----------|-----------------------------------|------------|
    	|   Edit   |  ON_EN_SETFOCUS(<id>,<memberFxn>) | memberFxn  |
    	|----------|-----------------------------------|------------|
    	| ListBox  |  ON_LBN_DBLCLK(<id>,<memberFxn>)  | memberFxn  |
    	|-----------------------------------------------------------|


    各个消息处理函数均以afx_msg void 为函数类型。



  • 相关阅读:
    URAL 2067 Friends and Berries (推理,数学)
    URAL 2070 Interesting Numbers (找规律)
    URAL 2073 Log Files (模拟)
    URAL 2069 Hard Rock (最短路)
    URAL 2068 Game of Nuts (博弈)
    URAL 2066 Simple Expression (水题,暴力)
    URAL 2065 Different Sums (找规律)
    UVa 1640 The Counting Problem (数学,区间计数)
    UVa 1630 Folding (区间DP)
    UVa 1629 Cake slicing (记忆化搜索)
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6932504.html
Copyright © 2020-2023  润新知