zoukankan      html  css  js  c++  java
  • 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 为函数类型。



  • 相关阅读:
    如果向某网址Post信息,并得到CookieContainer以便以后直接通过验证
    使用WebClient自动填写并提交ASP.NET页面表单的源代码
    mysql中文乱码,phpmyadmin乱码,php乱码 产生原因及其解决方法
    自己修改的一个WebRequest+代理+POST登录
    HttpWebRequest POST 数据时请求头多了一行Expect: 100continue,少了数据行
    [zt]Windows 2000下PHP5+IIS的安装方法(ISAPI方式)
    GridView控件修改、删除示例(修改含有DropDownList控件)
    GridView的常用操作(增删改查)
    ASP.net 验证码(C#)
    IE对input元素onchange事件的支持BUG
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6932504.html
Copyright © 2011-2022 走看看