跳到主要內容

Hello, MFC

一個典型的 MFC 應用程式並沒有 WinMain 函式,也不會呼叫 RegisterClass 或是 CreateWindow 這兩個函式。
MFC 是一組由 Microsoft 所提供的 C++ 類別函式庫,它將 Windows API 用物件導向的方式包裝起來。
MFC 以全域函式的形式提供了一組 API,它們的名稱都以 Afx 開頭。

下面是書中 MFC 的範例應用程式碼

///////////////////////////////////////////
// Hello.h

class CMyApp : public CWinApp
{
public:
    virtual BOOL InitInstance();
};

class CMainWindow : public CFrameWnd
{
public:
    CMainWindow();
   
protected:
    afx_msg void OnPaint();
    DECLARE_MESSAGE_MAP()
};


///////////////////////////////////////////
// Hello.cpp

#include
#include "Hello.h"

CMyApp myApp;

// CMyApp member functions
BOOL CMyApp::InitInstance()
{
    m_pMainWnd = new CMainWindow;
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();
    return TRUE;
}

// CMainWindow message map and member functions
BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
    ON_WM_PAINT()
END_MESSAGE_MAP()

CMainWindow::CMainWindow()
{
    Create(NULL, _T("The Hello Application"));
}

void CMainWindow::OnPaint()
{
    CPaintDC dc(this);
    CRect rect;
    GetClientRect(&rect);
    dc.DrawText(_T("Hello, MFC"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}


應用程式物件 (important !!)
MFC 應用程式的核心,就是衍生自 CWinApp 類別的應用程式物件。
CWinApp 提供了訊息迴路來擷取訊息,當引用標頭檔 Afxwin.h 後,CWinApp 及其它 MFC
類別即被引入你的程式之中。MFC 有唯一的應用程式物件,且該物件必須被宣告成全域變
數,以讓它在程式一開始就被放到記憶體中。

上述範例程式碼中,Hello 的應用程式類別稱為 CMyApp,而它就被宣告成一個全域變數,
CMyApp 中只改寫一個繼承自 CMyApp 的 InitInstance 函式,它是在應用程式生命週期中
早期被呼叫,時間點是在應用程式開始後,視窗建立之前,所以必須要在 InitInstance
中建立一個視窗,否則程式中是不會有視窗顯示的。

InitInstance 的回傳值決定了框架下一步要做什麼;回傳 FALSE 時會關閉應用程式,反之則
讓程式繼續執行。你也可以將程式執行時所需要做初始化的動作放置在此處。

若想在 MFC 程式中呼叫一般的 API 函式,就必須在函式名稱前面加上全域解析運算子(::),
如 ::UpdateWindow(hwnd);
如此一來,即使呼叫者本身也有相同名稱的成員函式時,也能確保呼叫到該 API 函式。

Message Mapping
將訊息與成員函式關聯起來的表格。

CMainWindow 類別的 WM_PAINT 訊息映射實作如下:
BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)  // (theClass, baseClass)
    ON_WM_PAINT()
END_MESSAGE_MAP()

ON_WM_PAINT 是 Map entry,而相對的 Function prototype 為 afx_msg void OnPaint();
此對映之關係可參考 MSDN。

DECLARE_MESSAGE_MAP()
宣告類別所定義的訊息對映。每一個 CCmdTarget 衍生類別必需要提供一個訊息對映來處理訊息。

當想要處理一個 MFC 沒有提供訊息映射巨集的訊息時,可以用具有一般性的 ON_MESSAGE 巨集
來建立該訊息項目。




PS. 以上 note 參考 "Windows 程式設計使用 MFC" 中文版

留言