深入浅出MFC笔记(5)



1.MFC的外围环境:

Windows C Runtime函数库LIBC.LIB静态联结MSVCRT.LIB动态联结MSVCRTD.LIB使用Debug模式

DLL Import 函数库GDI 32.LIB  USER32.LIB KERNEL32.LIB 

MFC 函数库(AFX 函数库):可静态联结或动态联结,是application framework的本体。MFCXXX.LIB  

SDK 程序只要包含WINDOWS.H 就好,所有API  的函数声明、消息定义、常数定义、宏定义。

MFC需要的头文件:

Precompiled header 就是将.H 档第一次编译后的结果保存,第二次再编译时就可以直接从取出来用。

STDAFX.H-这个文件用来做为Precompiled header file,其内只包含其它的MFC 头文件,包含AFXWIN.H

AFXWIN.H-以及它所包含的文件声明了所有的MFC类别。内含AFX.H,后者又包含AFXVER_.H,后者又包含AFXV_W32.H,后者又包含WINDOWS.H

AFXEXT.H-工具栏、状态列AFXDLGS.H -通用型对话框(Common Dialog)内包COMMDLG.H

AFXCMN.H-通用型控制组件(Common ControlAFXCOLL.H-Collections Classes 

AFXDLLX.H-MFC extension DLLs  AFXRES.H -RC 文件必须包含此档。 对于标准资源(例如FileEdit  等菜单项目)的ID 都有默认值,定义于此文件中,例如:

所有MFC 头文件均置于\MSVC\MFC\INCLUDE。这些文件连同Windows SDK 的包含档WINDOWS.HCOMMDLG.HTOOLHELP.HDDEML.H... 每每在编译过程中耗费大量的时间,因此你绝对有必要设定Precompiled header

2.SDK 程序设计的第一要务是了解最重要的数个API  函数的意义和用法,像RegisterClassCreateWindowGetMessageDispatchMessage,以及消息的获得与分配。

MFC 程序设计的第一要务则是熟记MFC 的类别阶层架构,并清楚知晓其中几个一定会用到的类别。

3.CWinApp-取代 WinMain的地位

CWinApp 之中的成员变量将因为theApp这个全域对象的诞生而获得配置与初值。称为application objectCWinApp 本身就代表一个程式本体。一个程序的本体是与程序本身有关而不与视窗有关的资料或动作:

系统传进来的四个WinMain参数、InitApplication InitInstance、消息循环。

class CWinApp : public CWinThread{// Attributes// Startup args (do not change)

  HINSTANCE m_hInstance;HINSTANCE m_hPrevInstance;LPTSTR m_lpCmdLine;int m_nCmdShow;

  // Running args (can be changed in InitInstance)

  CWnd* m_pMainWnd;           // main window (optional)记录主窗口的handle

  CWnd* m_pActiveWnd;         // active main window (may not be m_pMainWnd)

public:

    virtual BOOL InitApplication();// hooks for your initialization code 

    virtual BOOL InitInstance();// overrides for implementation

    virtual int Run();// overrides for implementation

——节录自AFXWIN.HCWinApp 声明

// in APPMODUL.CPP

extern "C" int WINAPI    //_tWinMain是为了支持Unicode 而准备的一个宏。

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){

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

}

int AFXAPI AfxWinMain (  //源代码可从MFC WINMAIN.CPP 中获得稍加整理去芜存菁

HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){

    int nReturnCode = -1;

    CWinApp* pApp = AfxGetApp();//一个指向theApp的指针和四个动作

    AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    pApp->InitApplication();

    pApp->InitInstance();

    nReturnCode = pApp->Run();

    AfxWinTerm();

    return nReturnCode;

}//AfxGetApp 是一个全域函数,定义于AFXWIN1.INL

_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp(){ return afxCurrentWinApp; }

 #define afxCurrentWinApp  AfxGetModuleState()->m_pCurrentWinApp//定义于AFXWIN.H

CWinApp::CWinApp(LPCTSTR lpszAppName){

    m_pszAppName = lpszAppName;

AFX_MODULE_THREAD_STATE* pThreadState = AfxGetModuleThreadState(); // initialize CWinThread state

    pThreadState->m_pCurrentWinThread = this;

    m_hThread = ::GetCurrentThread();

    m_nThreadID = ::GetCurrentThreadId();

AFX_MODULE_STATE* pModuleState = AfxGetModuleState();// initialize CWinApp state

    pModuleState->m_pCurrentWinApp = this;    ...//所以thistheApp对象

}

AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); //实际情况

#ifdef _AFXDLL

#define _AFX_CMDTARGET_GETSTATE() (m_pModuleState)

#else

#define _AFX_CMDTARGET_GETSTATE() (AfxGetModuleState())

#endif

以上说明CWinApp* pApp = AfxGetApp();返回的指针是指向子类对象theApp,在WinMain中调用的函数:

CWinApp::InitApplication(); //CMyWinApp 只改写CWinApp中的 InitInstance 

CMyWinApp::InitInstance();//通常它不改写InitApplication和 Run

CWinApp::Run();

AfxWinInit--AFX 内部初始化动作

节录自APPINIT.CPP

节录自THRDCORE.CPP

BOOL AFXAPI AfxWinInit(HINSTANCE hInstance, 

HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){

    ASSERT(hPrevInstance == NULL);

    // set resource handles

    AFX_MODULE_STATE* pState = AfxGetModuleState();

    pState->m_hCurrentInstanceHandle = hInstance;

    pState->m_hCurrentResourceHandle = hInstance;

    // fill in the initial state for the application

    CWinApp* pApp = AfxGetApp();

    if (pApp != NULL){

        // Windows specific initialization (not done if no CWinApp)

        pApp->m_hInstance = hInstance;

        pApp->m_hPrevInstance = hPrevInstance;

        pApp->m_lpCmdLine = lpCmdLine;

        pApp->m_nCmdShow = nCmdShow;

        pApp->SetCurrentHandles();

    }

    // initialize thread specific data (for main thread)

    if (!afxContextIsDLL)

        AfxInitThread();

    return TRUE;

}

void AFXAPI AfxInitThread(){

    if (!afxContextIsDLL){

 // attempt to make the message queue bigger

    for (int cMsg = 96; !SetMessageQueue(cMsg) && (cMsg -= 8); );

 // set message filter proc

    _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();

ASSERT(pThreadState->m_hHookOldMsgFilter == NULL);

pThreadState->m_hHookOldMsgFilter =::SetWindowsHookEx (WH_MSGFILTER,_AfxMsgFilterHook, NULL, ::GetCurrentThreadId());

 // intialize CTL3D for this thread

     _AFX_CTL3D_STATE* pCtl3dState = _afxCtl3dState;

    if (pCtl3dState->m_pfnAutoSubclass != NULL)

            (*pCtl3dState->m_pfnAutoSubclass)(AfxGetInstanceHandle());

 // allocate thread local _AFX_CTL3D_THREAD just for automatic termination

    _AFX_CTL3D_THREAD* pTemp = _afxCtl3dThread;

    }

}

WinMain  一开始即调用AfxWinInit,注册四个窗口类别

BOOL CWinApp::InitApplication(){//APPCORE.CPP中(大部份情况下不需改写它)

    if (CDocManager::pStaticDocManager != NULL){

        if (m_pDocManager == NULL)  m_pDocManager = CDocManager::pStaticDocManager;

        CDocManager::pStaticDocManager = NULL;

    }

    if (m_pDocManager != NULL)  m_pDocManager->AddDocTemplate(NULL);

    else   CDocManager::bStaticInit = FALSE;

    return TRUE;

}

pApp->InitInstance();CWinApp 中只是个空函数,没有任何内建(预设)动作。

BOOL CMyWinApp::InitInstance(){

   m_pMainWnd = new CMyFrameWnd();

   m_pMainWnd->ShowWindow(m_nCmdShow);

   m_pMainWnd->UpdateWindow();

   return TRUE;

}

CMyFrameWnd::CMyFrameWnd(){//new引发的构造式

     Create(NULL, "Hello MFC", WS_OVERLAPPEDWINDOW, rectDefault, NULL,"MainMenu");

}//Create只有前两个参数必须指定

 BOOL CFrameWnd::Create(LPCTSTR lpszClassName    ,// WINFRM.CPP

                           LPCTSTR lpszWindowName,

                           DWORD dwStyle,

                           const RECT& rect,

                           CWnd* pParentWnd,

                           LPCTSTR lpszMenuName,

                           DWORD dwExStyle,

                           CCreateContext* pContext){

    HMENU hMenu = NULL;

    if (lpszMenuName != NULL){

        // load in a menu that will get destroyed when window gets destroyed

        HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU);

        hMenu = ::LoadMenu(hInst, lpszMenuName);

    }

    m_strTitle = lpszWindowName;    // save title for later

    CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,

          rect.left, rect.top,  rect.right - rect.left, rect.bottom - rect.top,

          pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext);

    return TRUE;

}

‹  

BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,int x, int y, int nWidth, int nHeight,HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam){// allow modification of several common create parameters   WINCORE.CPP

    CREATESTRUCT cs;

 cs.dwExStyle = dwExStyle;cs.lpszClass = lpszClassName;cs.lpszName = lpszWindowName;cs.style = dwStyle;

 cs.x = x;cs.y = y;cs.cx = nWidth;cs.cy = nHeight;cs.hwndParent = hWndParent;cs.hMenu = nIDorHMenu;

 cs.hInstance = AfxGetInstanceHandle();cs.lpCreateParams = lpParam;

    PreCreateWindow(cs);

    AfxHookWindowCreate(this);  

HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,

                    cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);

    ...

}

BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs){    //WINFRM.CPP

  if (cs.lpszClass == NULL){

        AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);

        cs.lpszClass = _afxWndFrameOrView;  // COLOR_WINDOW background

    }

    ...

}

#define  AfxDeferRegisterClass(fClass) \

  ((afxRegisteredClasses  & fClass) ? TRUE :  AfxEndDeferRegisterClass(fClass))// in AFXIMPL.H 

#define  afxRegisteredClasses   AfxGetModuleState()->m_fRegisteredClasses// in AFXWIN.H

 BOOL AFXAPI AfxEndDeferRegisterClass(short fClass)   // in WINCORE.CPP

4.CFrameWnd-取代WndProc的地位

class CMyFrameWnd : public CFrameWnd{//MFC

public:

        CMyFrameWnd();

        afx_msg void OnPaint();//处理WM_PAINT

        afx_msg void OnAbout();//WM_COMMAND IDM _ABOUT

        DECLARE_MESSAGE_MAP()

};

BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)

ON_WM_PAINT()

ON_COMMAND(IDM_ABOUT, OnAbout)

END_MESSAGE_MAP()

long FAR PASCAL WndProc(HWND hWnd, UNIT msg, WORD wParam, LONG lParam){ switch(msg) {

 case WM_COMMAND :switch(wParam) {case IDM_ABOUT :OnAbout(hWnd, wParam, lParam);break;}break;

 case WM_PAINT :OnPaint(hWnd, wParam, lParam);break;

 default :DefWindowProc(hWnd, msg, wParam, lParam);

 }//传统的SDK 窗口函数

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值