zoukankan      html  css  js  c++  java
  • MFC程序和Win32程序的关系

    MFC把具有相当固定行为的WinMain内部操作封装在CWinApp中,把有着相当固定行为的WndProc内部操作封装在CFrameWnd中。

    几乎可以说CWinApp用来取代WinMain在SDK程序中的地位,CFrameWnd取代SDK程序中窗口函数的地位。

    首先MFC程序需要下面函数库:

    (1) Windows C Runtime函数库:LIBC.LIB / MSVCRT.LIB / MSVCRTD.LIB

    (2) DLL Import函数库:GDI32.LIB / USER32.LIB / KERNEL32.LIB

    (3) MFC函数库(AFX函数库):MFC42.LIB / MFC42D.LIB……

    同时,MFC程序需要下面头文件:

    (1) Stdafx.h:预编译头文件,其内只是载入其他的MFC头文件。

    (2) Afxwin.h:每个MFC程序都必须载入它,因为它以及它所载入的文件声明了所有的MFC类,此文件含有Afx.h,后者又载入Afxvver_.h,后者又载入Afxv_w32.h,后者又载入windows.h(SDK程序必须要的头文件)。

    (3) Afxext.h:使用工具栏、状态栏的程序必须载入这个文件。

    (4) Afxdlgs.h:使用通用型对话框的MFC程序需要此文件,其内部载入COMMDLG.H

    (5) Afxcmn.h:使用Win9x新增的通用型控件的MFC程序必须载入此文件。

    (6) Afxcoll.h:使用Collections Classes的程序要此文件

    (7) Afxres.h:MFC程序的RC文件必须载入此文件。

    [解释]预编译头文件:所谓预编译头文件是指将 .H 文件第一次编译后的结果保存起来,第2次编译的时候就可以直接从磁盘上取出来用。

    一个具体而微的MFC程序和Win32之间的关系:

    MFC程序也是Windows程序,所以它应该有一个WinMain,但在程序进入点之前,还有一个全局对象theApp,这是所谓的应用程序对象。当操作系统将程序加载并激活的时候,这个全局对象获得配置,其构造函数会先执行,必WinMain更早。

    CmyWinApp theApp;

    theApp是程序的应用程序对象,每一个MFC程序有且只有这么一个,当执行程序时,这个全局对象产生,于是构造函数执行起来。一般来说CwinApp的构造函数被执行。CwinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置与初值。

    theApp配置完成后,WinMain登场,我们并没有撰写WinMain程序代码,这是MFC早已准备好并由连接器直接加到应用程序代码中的。加入如下代码:

    extern “C” int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

    {

    return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    }

    其中AfxWinMain定义如下:

    int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

    {

    int nReturnCode = -1;

    CwinApp *pApp = AfxGetApp();

    AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    pApp->InitApplication();

    pApp->InitInstance();

    nReturnCode = pApp->Run();

    AfxWinTerm();

    Return nReturnCode;

    }

    关于AfxWinMain的四个主要操作说明:

    (1) AfxWinInit——AFX内部初始化操作。它是继CwinApp构造函数之后的第一个操作。在这函数内对theApp的某些成员初始化,而且还调用了AfxInitThread函数,把消息队列尽量加大到96。

    (2) CwinApp::InitApplication。InitApplication是CwinApp的一个虚函数,一般情况下不需要改写它。在此函数中的操作都是MFC为了内部管理而作的(DocManager相关)。

    (3) CmyWinApp::InitInstance。每个MFC程序都应该改写CwinApp::InitInstance这个函数,因为它在CwinApp中只是一个空函数。在这个函数里面,代码如下:

    BOOL CmyWinApp::InitInstance()

    {

    m_pMainWnd = new CmyFrameWnd();

    m_pMainWnd->ShowWindow(m_nCmdShow);

    m_pMainWnd->UpdateWindow();

    return TRUE;

    }

    其中一开始就new了一个CmyFrameWnd对象,准备用作主框窗口的C++对象,引发了CmyFrameWnd的构造函数:

    CmyFrameWnd::CmyFrameWnd

    {

    Create(NULL,”hello MFC”, WS_OVERLAPPEDWINDOW, rectDefault, NULL,”MainMenu”);

    }

    Create是CframeWnd的成员函数,CmyFrameWnd中并没有改写它。由于Create的第一个参数指定WNDCLASS窗口类名字,现在为NULL表示以MFC内建的窗口类产生一个标准的外框窗口。

    在CframeWnd::Create(…)函数中,调用了CreateEx函数,由于CframeWnd中并没有改写CreateEx函数,所以实际上调用的是CWnd::CreateEx。在CreateEx这个函数中,调用了PreCreateWindow和CreateWindowEx这两个函数。由于CframeWnd中改写了PreCreateWindow,所以这里调用的是CframeWnd::PreCreateWindow。在PreCreateWindow里面,调用了AfxDeferRegisterClass宏,该宏的定义如下:

    #define AfxDeferRegisterClass(fClass) \ ((afxRegisteredClasses & fClass) TRUE : AfxEndDeferRegisterClass(fclass))

    如果变量afxRegisteredClasses的值显示系统已经注册了fclass这种窗口类,MFC就啥也不做,否则就调用AfxEndDeferRegisterClass(fclass),准备注册之。AfxEndDeferRegisterClass函数中终于声明了WNDCLASS对象,并且调用了相应的MFC窗口类,并通过AfxRegisterClass(WNDCLASS*)和RegisterWithIcon这两个函数来注册窗口类。MFC内置6种窗口类。RegisterWithIcon中用到AfxRegisterClass函数,而AfxRegisterClass函数里面又调用了RegisterClass函数来注册窗口类。不同类的PreCreateWindow成员函数都是在窗口产生之前一刻被调用,准备用来注册窗口类的,如果我们指定窗口类为NULL,那么就是用系统默认类(MFC内置)。

    当创建完窗口以后,程序流程又回到CmyWinApp::InitInstance,于是调用ShowWindow函数令窗口显示出来,并调用UpdateWindow函数令程序送出WM_PAINT消息。

    (4) CwinApp::Run,由于在CmyWinApp中没有改写Run(大部分情况下都不用改写),所以调用的是CwinApp::Run。在该函数中又调用了CwinThread::Run,CwinThread::Run中调用了PumpMesage()函数,而PumpMessage函数中依次调用GetMessage / TranslateMessag / DispatchMessage函数。程序通过调用DispatchMessage函数,把消息丢给窗口函数。

    (5) 程序根据消息映射表来判断消息,从而做出相应的消息处理。

    至此,MFC程序和Win32程序的关系总算弄明白。

    MFC把具有相当固定行为的WinMain内部操作封装在CWinApp中,把有着相当固定行为的WndProc内部操作封装在CFrameWnd中。

    几乎可以说CWinApp用来取代WinMain在SDK程序中的地位,CFrameWnd取代SDK程序中窗口函数的地位。

    首先MFC程序需要下面函数库:

    (1) Windows C Runtime函数库:LIBC.LIB / MSVCRT.LIB / MSVCRTD.LIB

    (2) DLL Import函数库:GDI32.LIB / USER32.LIB / KERNEL32.LIB

    (3) MFC函数库(AFX函数库):MFC42.LIB / MFC42D.LIB……

    同时,MFC程序需要下面头文件:

    (1) Stdafx.h:预编译头文件,其内只是载入其他的MFC头文件。

    (2) Afxwin.h:每个MFC程序都必须载入它,因为它以及它所载入的文件声明了所有的MFC类,此文件含有Afx.h,后者又载入Afxvver_.h,后者又载入Afxv_w32.h,后者又载入windows.h(SDK程序必须要的头文件)。

    (3) Afxext.h:使用工具栏、状态栏的程序必须载入这个文件。

    (4) Afxdlgs.h:使用通用型对话框的MFC程序需要此文件,其内部载入COMMDLG.H

    (5) Afxcmn.h:使用Win9x新增的通用型控件的MFC程序必须载入此文件。

    (6) Afxcoll.h:使用Collections Classes的程序要此文件

    (7) Afxres.h:MFC程序的RC文件必须载入此文件。

    [解释]预编译头文件:所谓预编译头文件是指将 .H 文件第一次编译后的结果保存起来,第2次编译的时候就可以直接从磁盘上取出来用。

    一个具体而微的MFC程序和Win32之间的关系:

    MFC程序也是Windows程序,所以它应该有一个WinMain,但在程序进入点之前,还有一个全局对象theApp,这是所谓的应用程序对象。当操作系统将程序加载并激活的时候,这个全局对象获得配置,其构造函数会先执行,必WinMain更早。

    CmyWinApp theApp;

    theApp是程序的应用程序对象,每一个MFC程序有且只有这么一个,当执行程序时,这个全局对象产生,于是构造函数执行起来。一般来说CwinApp的构造函数被执行。CwinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置与初值。

    theApp配置完成后,WinMain登场,我们并没有撰写WinMain程序代码,这是MFC早已准备好并由连接器直接加到应用程序代码中的。加入如下代码:

    extern “C” int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

    {

    return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    }

    其中AfxWinMain定义如下:

    int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

    {

    int nReturnCode = -1;

    CwinApp *pApp = AfxGetApp();

    AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    pApp->InitApplication();

    pApp->InitInstance();

    nReturnCode = pApp->Run();

    AfxWinTerm();

    Return nReturnCode;

    }

    关于AfxWinMain的四个主要操作说明:

    (1) AfxWinInit——AFX内部初始化操作。它是继CwinApp构造函数之后的第一个操作。在这函数内对theApp的某些成员初始化,而且还调用了AfxInitThread函数,把消息队列尽量加大到96。

    (2) CwinApp::InitApplication。InitApplication是CwinApp的一个虚函数,一般情况下不需要改写它。在此函数中的操作都是MFC为了内部管理而作的(DocManager相关)。

    (3) CmyWinApp::InitInstance。每个MFC程序都应该改写CwinApp::InitInstance这个函数,因为它在CwinApp中只是一个空函数。在这个函数里面,代码如下:

    BOOL CmyWinApp::InitInstance()

    {

    m_pMainWnd = new CmyFrameWnd();

    m_pMainWnd->ShowWindow(m_nCmdShow);

    m_pMainWnd->UpdateWindow();

    return TRUE;

    }

    其中一开始就new了一个CmyFrameWnd对象,准备用作主框窗口的C++对象,引发了CmyFrameWnd的构造函数:

    CmyFrameWnd::CmyFrameWnd

    {

    Create(NULL,”hello MFC”, WS_OVERLAPPEDWINDOW, rectDefault, NULL,”MainMenu”);

    }

    Create是CframeWnd的成员函数,CmyFrameWnd中并没有改写它。由于Create的第一个参数指定WNDCLASS窗口类名字,现在为NULL表示以MFC内建的窗口类产生一个标准的外框窗口。

    在CframeWnd::Create(…)函数中,调用了CreateEx函数,由于CframeWnd中并没有改写CreateEx函数,所以实际上调用的是CWnd::CreateEx。在CreateEx这个函数中,调用了PreCreateWindow和CreateWindowEx这两个函数。由于CframeWnd中改写了PreCreateWindow,所以这里调用的是CframeWnd::PreCreateWindow。在PreCreateWindow里面,调用了AfxDeferRegisterClass宏,该宏的定义如下:

    #define AfxDeferRegisterClass(fClass) \ ((afxRegisteredClasses & fClass) TRUE : AfxEndDeferRegisterClass(fclass))

    如果变量afxRegisteredClasses的值显示系统已经注册了fclass这种窗口类,MFC就啥也不做,否则就调用AfxEndDeferRegisterClass(fclass),准备注册之。AfxEndDeferRegisterClass函数中终于声明了WNDCLASS对象,并且调用了相应的MFC窗口类,并通过AfxRegisterClass(WNDCLASS*)和RegisterWithIcon这两个函数来注册窗口类。MFC内置6种窗口类。RegisterWithIcon中用到AfxRegisterClass函数,而AfxRegisterClass函数里面又调用了RegisterClass函数来注册窗口类。不同类的PreCreateWindow成员函数都是在窗口产生之前一刻被调用,准备用来注册窗口类的,如果我们指定窗口类为NULL,那么就是用系统默认类(MFC内置)。

    当创建完窗口以后,程序流程又回到CmyWinApp::InitInstance,于是调用ShowWindow函数令窗口显示出来,并调用UpdateWindow函数令程序送出WM_PAINT消息。

    (4) CwinApp::Run,由于在CmyWinApp中没有改写Run(大部分情况下都不用改写),所以调用的是CwinApp::Run。在该函数中又调用了CwinThread::Run,CwinThread::Run中调用了PumpMesage()函数,而PumpMessage函数中依次调用GetMessage / TranslateMessag / DispatchMessage函数。程序通过调用DispatchMessage函数,把消息丢给窗口函数。

    (5) 程序根据消息映射表来判断消息,从而做出相应的消息处理。

    至此,MFC程序和Win32程序的关系总算弄明白。

    MFC把具有相当固定行为的WinMain内部操作封装在CWinApp中,把有着相当固定行为的WndProc内部操作封装在CFrameWnd中。

    几乎可以说CWinApp用来取代WinMain在SDK程序中的地位,CFrameWnd取代SDK程序中窗口函数的地位。

    首先MFC程序需要下面函数库:

    (1) Windows C Runtime函数库:LIBC.LIB / MSVCRT.LIB / MSVCRTD.LIB

    (2) DLL Import函数库:GDI32.LIB / USER32.LIB / KERNEL32.LIB

    (3) MFC函数库(AFX函数库):MFC42.LIB / MFC42D.LIB……

    同时,MFC程序需要下面头文件:

    (1) Stdafx.h:预编译头文件,其内只是载入其他的MFC头文件。

    (2) Afxwin.h:每个MFC程序都必须载入它,因为它以及它所载入的文件声明了所有的MFC类,此文件含有Afx.h,后者又载入Afxvver_.h,后者又载入Afxv_w32.h,后者又载入windows.h(SDK程序必须要的头文件)。

    (3) Afxext.h:使用工具栏、状态栏的程序必须载入这个文件。

    (4) Afxdlgs.h:使用通用型对话框的MFC程序需要此文件,其内部载入COMMDLG.H

    (5) Afxcmn.h:使用Win9x新增的通用型控件的MFC程序必须载入此文件。

    (6) Afxcoll.h:使用Collections Classes的程序要此文件

    (7) Afxres.h:MFC程序的RC文件必须载入此文件。

    [解释]预编译头文件:所谓预编译头文件是指将 .H 文件第一次编译后的结果保存起来,第2次编译的时候就可以直接从磁盘上取出来用。

    一个具体而微的MFC程序和Win32之间的关系:

    MFC程序也是Windows程序,所以它应该有一个WinMain,但在程序进入点之前,还有一个全局对象theApp,这是所谓的应用程序对象。当操作系统将程序加载并激活的时候,这个全局对象获得配置,其构造函数会先执行,必WinMain更早。

    CmyWinApp theApp;

    theApp是程序的应用程序对象,每一个MFC程序有且只有这么一个,当执行程序时,这个全局对象产生,于是构造函数执行起来。一般来说CwinApp的构造函数被执行。CwinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置与初值。

    theApp配置完成后,WinMain登场,我们并没有撰写WinMain程序代码,这是MFC早已准备好并由连接器直接加到应用程序代码中的。加入如下代码:

    extern “C” int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

    {

    return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    }

    其中AfxWinMain定义如下:

    int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

    {

    int nReturnCode = -1;

    CwinApp *pApp = AfxGetApp();

    AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    pApp->InitApplication();

    pApp->InitInstance();

    nReturnCode = pApp->Run();

    AfxWinTerm();

    Return nReturnCode;

    }

    关于AfxWinMain的四个主要操作说明:

    (1) AfxWinInit——AFX内部初始化操作。它是继CwinApp构造函数之后的第一个操作。在这函数内对theApp的某些成员初始化,而且还调用了AfxInitThread函数,把消息队列尽量加大到96。

    (2) CwinApp::InitApplication。InitApplication是CwinApp的一个虚函数,一般情况下不需要改写它。在此函数中的操作都是MFC为了内部管理而作的(DocManager相关)。

    (3) CmyWinApp::InitInstance。每个MFC程序都应该改写CwinApp::InitInstance这个函数,因为它在CwinApp中只是一个空函数。在这个函数里面,代码如下:

    BOOL CmyWinApp::InitInstance()

    {

    m_pMainWnd = new CmyFrameWnd();

    m_pMainWnd->ShowWindow(m_nCmdShow);

    m_pMainWnd->UpdateWindow();

    return TRUE;

    }

    其中一开始就new了一个CmyFrameWnd对象,准备用作主框窗口的C++对象,引发了CmyFrameWnd的构造函数:

    CmyFrameWnd::CmyFrameWnd

    {

    Create(NULL,”hello MFC”, WS_OVERLAPPEDWINDOW, rectDefault, NULL,”MainMenu”);

    }

    Create是CframeWnd的成员函数,CmyFrameWnd中并没有改写它。由于Create的第一个参数指定WNDCLASS窗口类名字,现在为NULL表示以MFC内建的窗口类产生一个标准的外框窗口。

    在CframeWnd::Create(…)函数中,调用了CreateEx函数,由于CframeWnd中并没有改写CreateEx函数,所以实际上调用的是CWnd::CreateEx。在CreateEx这个函数中,调用了PreCreateWindow和CreateWindowEx这两个函数。由于CframeWnd中改写了PreCreateWindow,所以这里调用的是CframeWnd::PreCreateWindow。在PreCreateWindow里面,调用了AfxDeferRegisterClass宏,该宏的定义如下:

    #define AfxDeferRegisterClass(fClass) \ ((afxRegisteredClasses & fClass) TRUE : AfxEndDeferRegisterClass(fclass))

    如果变量afxRegisteredClasses的值显示系统已经注册了fclass这种窗口类,MFC就啥也不做,否则就调用AfxEndDeferRegisterClass(fclass),准备注册之。AfxEndDeferRegisterClass函数中终于声明了WNDCLASS对象,并且调用了相应的MFC窗口类,并通过AfxRegisterClass(WNDCLASS*)和RegisterWithIcon这两个函数来注册窗口类。MFC内置6种窗口类。RegisterWithIcon中用到AfxRegisterClass函数,而AfxRegisterClass函数里面又调用了RegisterClass函数来注册窗口类。不同类的PreCreateWindow成员函数都是在窗口产生之前一刻被调用,准备用来注册窗口类的,如果我们指定窗口类为NULL,那么就是用系统默认类(MFC内置)。

    当创建完窗口以后,程序流程又回到CmyWinApp::InitInstance,于是调用ShowWindow函数令窗口显示出来,并调用UpdateWindow函数令程序送出WM_PAINT消息。

    (4) CwinApp::Run,由于在CmyWinApp中没有改写Run(大部分情况下都不用改写),所以调用的是CwinApp::Run。在该函数中又调用了CwinThread::Run,CwinThread::Run中调用了PumpMesage()函数,而PumpMessage函数中依次调用GetMessage / TranslateMessag / DispatchMessage函数。程序通过调用DispatchMessage函数,把消息丢给窗口函数。

    (5) 程序根据消息映射表来判断消息,从而做出相应的消息处理。

    至此,MFC程序和Win32程序的关系总算弄明白。

  • 相关阅读:
    windwos8.1英文版安装SQL2008 R2中断停止的解决方案
    indwows8.1 英文版64位安装数据库时出现The ENU localization is not supported by this SQL Server media
    Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds
    SQL数据附加问题
    eclipse,myeclipse中集合svn的方法
    JAVA SSH 框架介绍
    SSH框架-相关知识点
    SuperMapRealSpace Heading Tilt Roll的理解
    SuperMap iserver manage不能访问本地目的(IE9)
    Myeclipse中js文件中的乱码处理
  • 原文地址:https://www.cnblogs.com/draeag/p/906678.html
Copyright © 2011-2022 走看看