- MFC 教程
- MFC - 首頁
- MFC - 概述
- MFC - 環境設定
- MFC - VC++ 專案
- MFC - 入門
- MFC - Windows 基礎
- MFC - 對話方塊
- MFC - Windows 資源
- MFC - 屬性表
- MFC - Windows 佈局
- MFC - 控制元件管理
- MFC - Windows 控制元件
- MFC - 訊息與事件
- MFC - ActiveX 控制元件
- MFC - 檔案系統
- MFC - 標準 I/O
- MFC - 文件/檢視
- MFC - 字串
- MFC - CArray
- MFC - 連結串列
- MFC - 資料庫類
- MFC - 序列化
- MFC - 多執行緒
- MFC - Internet 程式設計
- MFC - GDI
- MFC - 庫
- MFC 有用資源
- MFC - 快速指南
- MFC - 有用資源
- MFC - 討論
MFC - 訊息與事件
一個應用程式是由各種物件組成的。大多數時候,計算機上執行著不止一個應用程式,並且作業系統不斷地被要求執行一些任務。由於可能會有如此多的請求以不可預測的方式出現,因此作業系統將決定權留給物件來指定它們想要什麼、何時想要以及期望什麼行為或結果。
概述
Microsoft Windows 作業系統無法預測一個物件需要處理哪種請求,以及另一個物件需要哪種任務。
為了管理所有這些任務和請求,物件傳送訊息。
每個物件都有責任決定傳送什麼訊息以及何時傳送。
為了傳送訊息,控制元件必須建立事件。
為了區分兩者,訊息的名稱通常以 WM_ 開頭,代表視窗訊息。
事件的名稱通常以 On 開頭,表示一個動作。
事件是傳送訊息的動作。
訊息對映
由於 Windows 是一個面向訊息的作業系統,因此 Windows 環境的大部分程式設計都涉及訊息處理。每次發生諸如擊鍵或滑鼠點選之類的事件時,都會嚮應用程式傳送一條訊息,然後應用程式必須處理該事件。
為了讓編譯器管理訊息,它們應該包含在類定義中。
DECLARE_MESSAGE_MAP 宏應該在類定義的末尾提供,如下面的程式碼所示。
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
DECLARE_MESSAGE_MAP()
};
實際的訊息應該列在 DECLARE_MESSAGE_MAP 行的正上方。
要實現訊息,您需要建立一個程式正在使用的訊息表。
此表使用兩個分隔宏;
它以 BEGIN_MESSAGE_MAP 開始,以 END_MESSAGE_MAP 宏結束。
BEGIN_MESSAGE_MAP 宏接受兩個引數,您的類的名稱以及您從中派生類的 MFC 類,如下面的程式碼所示。
#include <afxwin.h>
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {
// Create the window's frame
Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
public:
BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance(){
m_pMainWnd = new CMainFrame;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CMessagesApp theApp;
讓我們透過建立一個新的 Win32 專案來了解一個簡單的示例。
步驟 1 - 要建立 MFC 專案,請右鍵單擊該專案並選擇“屬性”。
步驟 2 - 在左側部分,單擊“配置屬性”→“常規”。
步驟 3 - 在“專案預設值”部分中選擇“在共享 DLL 中使用 MFC”選項,然後單擊“確定”。
步驟 4 - 我們需要新增一個新的原始檔。
步驟 5 - 右鍵單擊您的專案並選擇“新增”→“新建項”。
步驟 6 - 在“模板”部分,單擊“C++ 檔案 (.cpp)”。
步驟 7 - 單擊“新增”繼續。
步驟 8 - 現在,在 *.cpp 檔案中新增以下程式碼。
#include <afxwin.h>
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {
// Create the window's frame
Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
public:
BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance() {
m_pMainWnd = new CMainFrame;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CMessagesApp theApp;
Windows 訊息
有不同型別的 Windows 訊息,例如建立視窗、顯示視窗等。以下是一些常用的 Windows 訊息。
讓我們來看一個簡單的視窗建立示例。
WM_CREATE - 當建立一個稱為視窗的物件時,建立物件的框架會發送一個標識為 ON_WM_CREATE 的訊息。
步驟 1 - 要建立 ON_WM_CREATE,請在 DECLARE_MESSAGE_MAP() 之前新增 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);,如下所示。
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
步驟 2 - 在 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) 之後和 END_MESSAGE_MAP() 之前新增 ON_WM_CREATE()。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() END_MESSAGE_MAP()
步驟 3 - 這是 OnCreate() 的實現。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
// Call the base class to create the window
if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {
// If the window was successfully created, let the user know
MessageBox(L"The window has been created!!!");
// Since the window was successfully created, return 0
return 0;
}
// Otherwise, return -1
return -1;
}
步驟 4 - 現在您的 *.cpp 檔案將如下所示。
#include <afxwin.h>
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {
// Create the window's frame
Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
public:
BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
END_MESSAGE_MAP()
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
// Call the base class to create the window
if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {
// If the window was successfully created, let the user know
MessageBox(L"The window has been created!!!");
// Since the window was successfully created, return 0
return 0;
}
// Otherwise, return -1
return -1;
}
BOOL CMessagesApp::InitInstance() {
m_pMainWnd = new CMainFrame;
m_pMainWnd -> ShowWindow(SW_SHOW);
m_pMainWnd -> UpdateWindow();
return TRUE;
}
CMessagesApp theApp;
步驟 5 - 編譯並執行上述程式碼後,您將看到以下輸出。
步驟 6 - 單擊“確定”後,將顯示主視窗。
命令訊息
圖形應用程式的主要功能之一是呈現 Windows 控制元件和資源,允許使用者與機器互動。我們將學習的控制元件示例包括按鈕、列表框、組合框等。
我們在上一課中介紹了一種資源型別,即選單。當用戶單擊此類控制元件和資源時,它們可以啟動自己的訊息。源自 Windows 控制元件或資源的訊息稱為命令訊息。
讓我們來看一個簡單的命令訊息示例。
為了使您的應用程式能夠建立新文件,CWinApp 類提供了 OnFileNew() 方法。
afx_msg void OnFileNew(); BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_COMMAND(ID_FILE_NEW, CMainFrame::OnFileNew) END_MESSAGE_MAP()
以下是方法定義 -
void CMainFrame::OnFileNew() {
// Create New file
}
鍵盤訊息
鍵盤是連線到計算機的硬體物件。預設情況下,它用於在控制元件上輸入可識別的符號、字母和其他字元。鍵盤上的每個鍵都顯示一個符號、一個字母或它們的組合,以指示該鍵可用於什麼。使用者通常按下某個鍵,該鍵會向程式傳送訊號。
每個鍵都有一個作業系統可以識別的程式碼。此程式碼稱為虛擬鍵碼。
按下某個鍵會導致將WM_KEYDOWN 或WM_SYSKEYDOWN 訊息放入執行緒訊息中。這可以定義如下 -
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
讓我們來看一個簡單的示例。
步驟 1 - 以下是訊息。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_WM_KEYDOWN() END_MESSAGE_MAP()
步驟 2 - 以下是 OnKeyDown() 的實現。
void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
switch (nChar) {
case VK_RETURN:
MessageBox(L"You pressed Enter");
break;
case VK_F1:
MessageBox(L"Help is not available at the moment");
break;
case VK_DELETE:
MessageBox(L"Can't Delete This");
break;
default:
MessageBox(L"Whatever");
}
}
步驟 3 - 編譯並執行上述程式碼後,您將看到以下輸出。
步驟 4 - 按下 Enter 鍵後,將顯示以下訊息。
滑鼠訊息
滑鼠是連線到計算機的另一個物件,允許使用者與機器互動。
如果按下左滑鼠按鈕,則會發送 ON_WM_LBUTTONDOWN 訊息。此訊息的語法如下 -
afx_msg void OnLButtonDown(UINT nFlags, CPoint point)
如果按下右滑鼠按鈕,則會發送 ON_WM_RBUTTONDOWN 訊息。其語法如下 -
afx_msg void OnRButtonDown(UINT nFlags, CPoint point)
類似地,如果釋放左滑鼠,則會發送 ON_WM_LBUTTONUP 訊息。其語法如下 -
afx_msg void OnLButtonUp(UINT nFlags, CPoint point)
如果釋放右滑鼠,則會發送 ON_WM_TBUTTONUP 訊息。其語法如下 -
afx_msg void OnRButtonUp(UINT nFlags, CPoint point)
讓我們來看一個簡單的示例。
步驟 1 - 在 CMainFrame 類定義中新增以下兩個函式,如下面的程式碼所示。
class CMainFrame : public CFrameWnd {
public:
CMainFrame();
protected:
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
步驟 2 - 新增以下兩個訊息對映。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_KEYDOWN() ON_WM_LBUTTONDOWN() ON_WM_RBUTTONUP() END_MESSAGE_MAP()
步驟 3 - 以下是函式定義。
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) {
CString MsgCoord;
MsgCoord.Format(L"Left Button at P(%d, %d)", point.x, point.y);
MessageBox(MsgCoord);
}
void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point) {
MessageBox(L"Right Mouse Button Up");
}
步驟 4 - 執行此應用程式時,您將看到以下輸出。
步驟 5 - 單擊“確定”後,您將看到以下訊息。
步驟 6 - 右鍵單擊此視窗。現在,當您釋放滑鼠右鍵時,將顯示以下訊息。