天天看點

C++MFC程式設計筆記day01 MFC介紹、建立MFC程式和重寫消息處理一、MFC概念和作用機制1:MFC入口函數機制機制2:MFC視窗建立機制:

1、全稱Microsoft Foundation Class Library,我們稱為微軟基礎類庫,封閉了絕大部分的win32 Api函數,C++文法中的資料結構,程式的執行流程

MFC就是一個庫(動态庫,靜态庫)

MFC還是一個程式架構

2、為什麼使用MFC

基于架構程式設計,提高工作效率,減少開發周期,節約開發成本。

二、幾個重要的頭檔案

afx.h    -絕大部分類的聲明頭檔案

afxwin.h -包含了afx.h和windows.h

afxext.h -提供了擴充視窗類的支援(工具欄,狀态欄等)

三、使用MFC

1、使用MFC庫做自己的控制台程式

入口函數 _tmain()不同于以往的main()

CWinApp theApp;-全局程式對象。

注意:

::函數名()-為win32的API函數。

以Afx開頭的函數,為MFC庫裡的全局函數。

2、使用MFC庫做自己的庫程式(MFC AppWizard dll)

規則動态庫:可以被任何程式調用

擴充動态庫:隻能被支援MFC的程式調用

3、MFC視窗程式

單文檔視圖構架程式。

CFrameWnd-架構視窗類;

CWinApp-應用程式類,負責管理整個程式的執行流程;

CDocument-文檔類,負責管理資料(資料的提取、轉換、存儲等操作);

CView-視圖視窗類,負責顯示資料

多文檔視圖構架程式。

CMDIChildWnd-子架構視窗類,負責管理子架構視窗。

CMDIFrameWnd-主架構視窗類

對話框程式

CDialog-對話框類

四、MFC類的介紹

CObject -mfc庫絕大部分類的基類,封裝了MFC庫中最基本的一些機制,運作時類資訊機制/動态建立機制/序列化機制.

CCmdTarget-消息映射機制基類

CWinThread/CWinApp-應用程式類

CDocTemplate及其子類 -文檔模版類

CDocument及其子類-文檔類,封裝了對各種資料的操作。

Exceptions - 異常類,封裝了MFC中的各種異常情況。

CFile-文操作類

CWnd  -所有視窗類基類

FrameWindows  架構視窗類,封裝了對各種架構視窗的操作

ControlBars-各種工具欄類,封閉了對各種工具欄的操作

Dialog Boxes 對話框類。

Views 視圖視窗類

Controls 控件類

CDC/CGdiObject 封裝了繪圖操作

CArray/AList/CMap  對C++中的資料的封裝,以C開頭。

現在學習時,MFC都是建立Win32 Application程式,然後通過下列步驟改為MFC程式,隻有一步步了解怎麼去手動建立MFC,以後通過MFC向導自動生成的大量MFC代碼我們才能看得懂。

1、删除主程式cpp中的入口函數

2、将stdafx.h中的windows.h改為afxwin.h

3、工程-設定 中選擇使用MFC庫

4、自定義架構類和程式類,繼承自MFC類,并重寫CWinApp的InitInstance方法:

class CMyFrameWnd:public CFrameWnd

{

};

class CMyWinApp:public CWinApp

public:

CMyWinApp();

virtual BOOL InitInstance();

CMyWinApp::CMyWinApp()

}

BOOL CMyWinApp::InitInstance()

CMyFrameWnd *pFrame=new CMyFrameWnd;

pFrame->Create(NULL,"MFC base");

m_pMainWnd=pFrame;

pFrame->ShowWindow(SW_SHOW);

pFrame->UpdateWindow();

return true;

5、建立一個程式類對象(觸發點):

CMyWinApp theApp;

AFX_MODULE_STATE* pModuleState = AfxGetModuleState();//擷取目前程式子產品狀态資訊

AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;//擷取目前線程狀态資訊

pThreadState->m_pCurrentWinThread = this;//theapp全局對象資訊指派

pModuleState->m_pCurrentWinApp = this;

ASSERT(bool表達式);//如果表達式不成立,則彈出錯誤,不往下執行

全局函數:AfxGetApp(),AfxGetThread() 擷取theApp位址

AfxMessageBox();//彈出消息

vc6中,檢視-調試視窗-call stack 可以看到被誰調用

可重寫(前加virtual):

BOOL CMyWinApp::InitApplication();

BOOL CMyWinApp::InitInstance()//初始化

int  CMyWinApp::Run()//運作

BOOL CMyWinApp::OnIdle(LONG lcount);//空閑時處理

int CMyWinApp::ExitInstance();

示例代碼:

AfxGetInstanceHandle();//全局句柄

1、加載菜單

2、調用CreateEx 設計、注冊視窗類

PreCreateWindow():

WNDCLASS   wndcls;wndcls.lpfWinProc=DefWindowProc;

AfxRegisterWithIcon(),AfxRegisterClass()

::RegisterClass注冊一個局部視窗類,類名“AfxFrameOrView42sd”,預設處理函數。

AfxHookWindowCreate(pFrame) 埋下勾子

CHandleMap* pMap = afxMapHWND(TRUE);

AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//映射對象儲存到全局變量

pState->m_pmapHWND = new CHandleMap(...);

pMap->SetPermanent(m_hWnd = hWndNew, this);

    //pFrame->m_hWnd 為視窗句柄。

CWnd* pWnd=CWnd::FromHandlePermanent(hWnd);

//pState->m_pmapHWND->LookupPermanent(HANDLE h)成員,可通過視窗句柄擷取pFrame

::CreateWindowEx函數,建立視窗

3、鈎子處理函數

将架構對象位址和視窗句柄建立一一對應關系。

利用::SetWindowLong,将視窗處理函數更改為AfxWndProc.

----------MSDN Library Visual Studio 6.0

//埋下勾子

HHOOK SetWindowsHookEx(

  int idHook,        // 勾子類型

  HOOKPROC lpfn,     // 處理函數(不同類型不同)

  HINSTANCE hMod,    // 程序句柄,NULL時不限制範圍

  DWORD dwThreadId   // 線程ID

);

//勾子類型為WH_CBT時的處理函數

LRESULT CALLBACK CBTProc(

  int nCode,      // hook code

  WPARAM wParam,  // 建立好的視窗句柄

  LPARAM lParam   // depends on hook code

//勾子處理函數修改預設處理函數

WNDPROC afxWndProc = AfxGetAfxWndProc();

oldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC,(DWORD)afxWndProc);

//修改視窗處理函數

LONG SetWindowLong(

  HWND hWnd,       // 視窗句柄

  int nIndex,      // 傳入:GWL_WNDPROC

  LONG dwNewLong   // 視窗處理函數位址

//全局變量資訊

_AFX_THREAD_STATE* pThreadState=_afxThreadState.GetDate();

::GetCurrentThreadId();//擷取目前線程ID

pThreadState->m_pWndInit = pWnd;//指派到全局變量

::CreateWindowEx() //此函數處理完後直接進入勾子處理函數

重寫消息處理函數

LRESULT CMyFrameWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

switch(message)

case WM_CREATE:

AfxMessageBox("WM_CREATE");

break;

return CFrameWnd::WindowProc(message,wParam,lParam);

示例:

繼續閱讀