MFC程式設計第一天——Windows程式設計與MFC程式設計基礎
Windows程式設計與MFC程式設計基礎
一、Windows程式設計
1、Windows應用程式程式設計介面API
-
Windows API 是指 Windows 作業系統應用程式程式設計介面 (Application Programming Interface, API),支援作業系統中的函式定義、引數定義、結構定義、訊息格式、巨集和介面的實現。主要學習 Win32 API ,此版本的 API 與其他版本的 API 不同在於,Win32 API 中有關安全方面的函式只能在 Windows NT 作業系統上使用。
-
Win32 API 主要包括以下方面:
方面 描述 Windows 管理 完成 Windows 管理中的各方面的功能。 Windows 控制元件 完成標準 Windows 控制元件的功能。 系統核心 完成 Windows 作業系統的一些核心操作。 GDI 圖形裝置介面 完成 Windows 作業系統有關圖形繪製的功能。 系統服務 提供對 Windows 作業系統底層服務的支援。 國際化支援 提供多語言的支援。 網路服務 完成 Windows 作業系統有關網路的功能。
2、使用控制代碼表示視窗
- 視窗是應用程式顯示在輸出螢幕上的一個矩形區域,用於接收使用者的輸入或程式的資料處理結果的顯示;多個應用程式可以共用同一個螢幕,但是同一時間只有一個視窗可以通過滑鼠和鍵盤等資料輸入裝置接受使用者資料的輸入,因此每個視窗都需要一個標識來區別。Windows API 中使用 HWND (視窗控制代碼型別)來標識視窗;Win32 API 中 HWND 是一個32位的無符號整型值;不同位數的作業系統下,HWND 的儲存空間大小不一樣,可通過 sizeof(HWND) 來計算。
3、輸入事件產生的訊息
-
Windows 應用程式是事件驅動的,通常情況下不會顯式地呼叫函式來獲取輸入,而是有系統將接收到的輸入傳遞給應用程式的不同視窗,再由相應的視窗的視窗函式(每個視窗都有一個對應的函式,稱為視窗函式)對輸入進行處理並執行對系統的控制。
-
系統使用訊息的形式將輸入傳遞給視窗函式;系統和應用都能建立訊息。應用程式可以產生指向其所屬視窗的訊息完成任務,也可以與其他應用程式通過訊息進行通訊。
-
系統向視窗函式傳送訊息,需要4個引數:
引數 描述 視窗控制代碼 用於表示向哪個視窗傳送訊息,作業系統通過該引數判斷哪個視窗函式接收這條訊息。 訊息標識 一個常數,用於表示訊息的種類。當訊息對應的視窗函式接收到訊息時,會通過訊息標識來確定如何處理訊息。 兩個訊息引數 用於表示訊息所附帶的引數,其含義和取值根據訊息的不同而不同;當不使用訊息引數時,通常設定為NULL。 -
Windows 作業系統使用以下兩種方式將訊息傳遞給視窗函式。
(1)傳送訊息到先進先出的訊息佇列中
- 用於儲存通過滑鼠或鍵盤輸入的使用者輸入,如 WM_MOUSEMOVE、WM_LBUTTONDWN、WM_KEYDOWN 和 WM_CHAR 等訊息;也用於儲存定時器訊息(WM_TIMER)、重繪訊息(WM_PAINT)和推出訊息(WM_QUIT)等。通過訊息佇列傳送的訊息稱為佇列訊息,使用 PostMessage() 函式傳送的訊息會發送打訊息佇列中。
(2)使用系統定義的記憶體物件臨時儲存訊息
- 除了上述的佇列訊息,其他訊息一般都會使用系統定義的記憶體物件臨時儲存訊息,併發送給視窗函式。使用 SendMessage() 函式發出的訊息會直接傳送給視窗函式。
4、Windows 控制代碼的資料型別
-
常用 Windows 控制代碼資料型別
型別 定義 型別 定義 HACCEL 加速鍵控制代碼 HHOOK 鉤子控制代碼 HANDLE 物件控制代碼 HICON 圖示控制代碼 HBITMAP 點陣圖控制代碼 HIMAGELIST 影象列表控制代碼 HBRUSH 畫刷控制代碼 HINSTANCE 例項控制代碼 HCURSOR 游標控制代碼 HKEY 登錄檔控制代碼 HDC 裝置上下文控制代碼 HKL 鍵盤佈局控制代碼 HDDEDATA DDE資料控制代碼 HLOCAL 本地記憶體塊控制代碼 HDESK 桌面控制代碼 HMENU 選單控制代碼 HDROP 內部下拉結構控制代碼 HMETAFILE 元檔案控制代碼 HDWP 視窗位置結構控制代碼 HMODULE 模組控制代碼 HENHMETAFILE 增強型圖元控制代碼 HMONITOR 顯示器控制代碼 HFILE 檔案控制代碼 HPEN 鉛筆控制代碼 HFONT 字型控制代碼 HRGN 區域控制代碼 HGDIOBJ GDI物件控制代碼 HRSRC 資源控制代碼 HGLOBAL 全域性記憶體塊控制代碼 HWND 視窗控制代碼
二、Windows 程式執行流程
- 核心要點:程式入口函式、視窗選單視窗函式以及關於對話方塊。
1、入口函式 WinMain()
-
Win32 平臺預設 WinMain()函式宣告如下:
int APIENTRY WinMain( HINSTANCE hInstance,//指定應用程式的當前例項控制代碼 HINSTANCE hPrevInstance,//指定應用程式的前一個例項的控制代碼,預設為NULL LPSTR lPCmdLine,//以非NULL結束的字串用於指定執行程式的應用程式命令列 int nCmdShow//應用程式的主對話方塊如何顯示 )
-
nCmdShow 引數用於指定窗體的顯示形式,其有效取值如下表
取值 顯示方式 SW_HIDE 隱藏對話方塊並激活其他對話方塊 SW_MINIMIZE 最小化指定對話方塊,並激活系統列表中最頂層的對話方塊 SW_RESTORE 啟用並顯示對話方塊。若果對話方塊是在最大化或最小化狀態,則系統恢復原始大小和位置,與 SW_SHOWNORMAL 引數的作用一樣 SW_SHOW 啟用對話方塊,並顯示當前大小和位置 SW_SHOWMAXIMIZED 啟用對話方塊,並將對話方塊最大化顯示 SW_SHOWMINIMIZED 啟用對話方塊,並將對話方塊以圖示形式顯示 SW_SHOWMINNOCTIVE 顯示對話方塊圖示,並且啟用的對話方塊仍然保持啟用狀態 SW_SHOWNA 以當前的狀態顯示對話方塊,啟用的對話方塊仍然保持啟用狀態 SW_SHOWNOACTIVATE 以最近的大小和位置顯示對話方塊,啟用的對話方塊仍然保持啟用狀態 SW_SHOWNORMAL 同 SW_RESTORE -
WinMain()函式初始化應用程式,顯示程式的主對話方塊、進入訊息迴圈和排程迴圈,直到收到 WM_QUIT 訊息。當收到 WM_QUIT 訊息程式會終止並將訊息傳入的 wParam 引數包含的退出程式碼值返回;如果在進入訊息迴圈前終止,則返回零。WinMain() 函式主要完成窗體類註冊、視窗建立和啟動訊息迴圈的工作。
2、窗體類註冊函式
-
每個窗體都必須有一個與其對應的窗體類,窗體類定義了窗體的屬性。入口函式的第一步就是註冊主窗體類,先使用類資訊初始化 WNDCLASS 物件,指定窗體屬性;然後將結構傳入 RegisterClassEx() 函式。
-
RegisterClassEx() 函式:
ATOM MyRegisterClass(HINSTANCE hInstance)//該函式在主函式內呼叫,接受的實參是本程式的HINSTANCE { WNDCLASSEXW wcex;//WNDCLASSEXW是個結構體,即我們所用的視窗類 wcex.cbSize = sizeof(WNDCLASSEX);//cbSize代表視窗類結構體所佔大小 wcex.style= CS_HREDRAW | CS_VREDRAW;//style視窗樣式,CS_HREDRAW | CS_VREDRAW代表的是視窗在水平和豎直方向運動時,視窗畫面的重繪 wcex.lpfnWndProc= WndProc; wcex.cbClsExtra= 0;//cbClsExtra代表視窗類後新增的位元組數,常置零 wcex.cbWndExtra= 0;//cbWndExtra代表視窗控制代碼後新增的位元組數,常置零 wcex.hInstance= hInstance;//hInstance代表本應用程式的例項 wcex.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT1));//hIcon代表程式圖示,MAKEINTRESOURCE將資源選單中相應ID的項作為資源 wcex.hCursor= LoadCursor(nullptr, IDC_ARROW);//hCursor代表滑鼠圖示 wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);//hbrBackground代表背景色 wcex.lpszMenuName= MAKEINTRESOURCEW(IDC_WINDOWSPROJECT1);//lpszMenuName代表選單名稱 wcex.lpszClassName= szWindowClass;//lpszClassName代表視窗類的名稱 wcex.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));//hIconSm代表視窗的小圖示 return RegisterClassExW(&wcex);//使用RegisterClassExW註冊視窗類,該函式是一個Windows API函式,是微軟提供Windows應用程式開發者的介面函式 }
3、使用 CreateWindow 建立視窗
-
CreateWindow() 函式用於建立已經註冊了的窗體類的視窗;第一引數是註冊視窗類的名稱,其餘引數指定視窗的其他屬性;呼叫完函式後使用 if 判斷是否建立成功,是則使用 ShowWindow() 函式顯示視窗。
//函式: InitInstance(HINSTANCE, int) // //目標: 儲存例項控制代碼並建立主視窗 // //註釋: // //在此函式中,我們在全域性變數中儲存例項控制代碼並 //建立和顯示主程式視窗。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 將例項控制代碼儲存在全域性變數中 //HWND是視窗控制代碼的縮寫,是系統管理視窗的一個標識 HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); //CreateWindow是Windows API函式,用於建立視窗控制代碼,該函式的引數的具體意義如下 /* szWindowClass是本檔案定義的一個TCHAR型別的陣列,用來儲存類名 szTitle儲存窗體的標題 WS_OVERLAPPEDWINDOW代表視窗的風格 第四、五個引數表示視窗左上角在螢幕中的位置,使用CW_USEDEFAULT是使x座標用預設值,該情況下y座標無須設定,可置0 第六、七個引數代表視窗所屬橫向、縱向大小,同樣預設 第八個引數代表這個視窗所屬的父類視窗控制代碼,當無需使用時該引數可設定為NULL 第九個引數代表使用的選單控制代碼 第十個引數hInstance是本程式的標識,代表建立的視窗屬於哪個應用程式 最後一個引數代表Windows引數 */ if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }
4、使用主訊息迴圈響應使用者輸入
-
用於響應使用者發出的命令。
// 主訊息迴圈: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg);//轉換訊息,翻譯快捷鍵訊息,若訊息按鍵在快捷鍵列表中存在,則執行快捷鍵相應的命令;此函式將按鍵訊息轉換成字元訊息。 DispatchMessage(&msg);//排程訊息, 將訊息傳送給相應的視窗函式。 } } /* GetMessage函式獲取訊息後通過TranslateAccelerator函式將訊息與熱鍵表比對,若不是熱鍵發出的選單指令, 則會將這些訊息傳遞給TranslateMessage函式翻譯出相應的形式之後,通過DispatchMessage函式傳遞給訊息的處理者 */
5、主窗體函式 WinProc()
-
主窗體函式如下:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // CALLBACK 修飾符用於指定函式使用標準函式呼叫轉換 { switch (message)// 根據訊息型別執行相應的操作 { case WM_COMMAND:// 如果是WM_COMMAND型別的 { int wmId = LOWORD(wParam);// 獲取傳送命令物件的ID int wmEvent = HIWORD(wParam); //獲取傳送的事件 // 分析選單選擇: switch (wmId) { case IDM_ABOUT:// 如果是“關於”命令,則顯示關於對話方塊 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT:// 如果是“退出”命令,則退出窗體 DestroyWindow(hWnd); break; default:// 其他命令,則做相應處理 return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT:// 如果是重繪命令 { PAINTSTRUCT ps;//宣告繪製窗體結構變數 HDC hdc = BeginPaint(hWnd, &ps); //開始重繪 // TODO: 在此處新增使用 hdc 的任何繪圖程式碼... RECT rt;//定義區域變數 GetClientRect(hWnd,&rt);//獲取客戶去範圍 DrawText(hdc,szHello,strlen(szHello),&rt,DT_CENTER);//繪製歡迎文字 EndPaint(hWnd, &ps); //結束重繪 } break; case WM_DESTROY://銷燬窗體 PostQuitMessage(0);//發出退出訊息 break; default: return DefWindowProc(hWnd, message, wParam, lParam);//預設情況,處理窗體訊息。 } return 0; }
三、MFC基礎
1、微軟基礎類庫 MFC
-
微軟基礎類庫(Microsoft Foundation Class Library,MFC)是一個編寫 Windows 應用程式的框架類庫。
-
MFC全域性函式
全域性函式 功能 AfxAbort() MFC提供的預設終止函式 AfxBeginThread() 建立新執行緒 AfxCheckError() 檢測程式碼是否為錯誤程式碼 AfxCheckMemory() 檢測是否發生有關記憶體的錯誤 AfxDaoInit() 初始化DAO資料庫引擎 AfxDaoTerm() 終止DAO資料庫引擎 AfxDbInitMoudle() 初始化MFC資料庫DLL AfxDoForAllClasses() 在應用程式記憶體空間中,列舉所有序列化派生類 AfxDump() 除錯程式時,列出物件的所有狀態 AfxDumpStack() 列出當前堆疊的情況 AfxEnableControlContainer() 支援對OLE控制元件的支援 AfxEnableMemoryTracking() 開啟記憶體跟蹤 AfxEndThread() 結束執行緒 AfxFreeLibrary() 釋放對DLL的引用 AfxGetApp() 獲取應用程式物件 AfxGetAppName() 獲取應用程式名稱 AfxGetHENV() 獲取當前使用的ODBC控制代碼 AfxGetInstanceHandle() 獲取當前應用程式的例項控制代碼 AfxGetInternetHandleType() 獲取Internet控制代碼型別 AfxGetMainWnd() 獲取應用程式主對話方塊 AfxGetResourceHandle() 獲取資源控制代碼 AfxGetStaticModuleState() 獲取靜態模組狀態 AfxGetThread() 獲取當前執行的執行緒 AfxInitExtensionModule() 初始化DLL AfxInitRichEdit() 初始化應用程式的編輯框 AfxIsMemoryBlock() 判斷指定的記憶體塊是否是有效的記憶體空間 AfxIsValidAddress() 判斷是否是有效的記憶體地址 AfxIsValidString() 判斷是否是有效的字串 AfxLoadLibrary() 裝載DLL AfxMessageBox() 呼叫訊息對話方塊 AfxNetInitNodule() 初始化MFC的Socket DLL AfxOleCanExitApp() 判斷OLE是否可以退出 AfxParseURL() 解析URL地址 AfxRegisterClass() 在DLL中註冊對話方塊類 AfxRegisterWndClass() MFC自動註冊幾個有用的對話方塊類 AfxSetAllocHook() 在每次分配記憶體時,允許使用鉤子函式 AfxSetResourceHandle() 設定資源控制代碼 AfxSocketInit() 初始化對Windows Socket的支援 AfxThrowDaoException() 丟擲DAO異常 AfxThrowDBException() 丟擲CDBException型別異常 AfxThrowFileException() 丟擲檔案異常 AfxThrowInternetException() 丟擲網路異常 AfxThrowMemoryException() 丟擲記憶體異常 AfxNotSupportException() 丟擲不支援異常 AfxThrowOleDispatchException() 丟擲OLE排程異常 AfxThrowOleException() 丟擲OLE異常 AfxThrowResourceException() 丟擲資源異常 AfxThrowUserException() 丟擲使用者異常 AfxWinInit() 初始對話方塊應用程式
2、MFC應用程式框架分析
-
MFC 中主應用程式類封裝了初始化、執行和終止 Windows 應用程式的功能。
-
初始化應用程式的 Initstance()函式
BOOL CMFCApplication1App::InitInstance() { AfxEnableControlContainer(); #ifdef _AFXDLL//判斷是否定義了AFXDLL Enable3dControls(); #else Enable3dControlsStatic(); #endif //設定登錄檔鍵 SetRegistryKey(_T("應用程式嚮導生成的本地應用程式")); LoadStdProfileSettings(4);// 載入標準 INI 檔案選項(包括 MRU),即載入標準配置設定 // 註冊應用程式的文件模板。文件模板 // 將用作文件、框架視窗和檢視之間的連線 CMultiDocTemplate* pDocTemplate;//定義多文件變數 pDocTemplate = new CMultiDocTemplate(IDR_MFCApplication1TYPE, RUNTIME_CLASS(CMFCApplication1Doc), RUNTIME_CLASS(CChildFrame), // 自定義 MDI 子框架 RUNTIME_CLASS(CMFCApplication1View)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); //增加到文件模板集合 // 建立主 MDI 框架視窗 CMainFrame* pMainFrame = new CMainFrame;//定義 CMainFrame 類 //裝載框架 if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME)) { delete pMainFrame; return FALSE; } m_pMainWnd = pMainFrame;//為主視窗類賦值 // 分析標準 shell 命令、DDE、開啟檔案操作的命令列 CCommandLineInfo cmdInfo;//定義命令列資訊變數 ParseCommandLine(cmdInfo);//解析命令列 // 排程在命令列中指定的命令。如果 // 用 /RegServer、/Register、/Unregserver 或 /Unregister 啟動應用程式,則返回 FALSE。 //處理命令 if (!ProcessShellCommand(cmdInfo)) return FALSE; // 主視窗已初始化,因此顯示它並對其進行更新 pMainFrame->ShowWindow(m_nCmdShow);//顯示主視窗 pMainFrame->UpdateWindow();//重新整理主視窗 return TRUE; }
3、框架程式的執行核心 Run() 函式
-
Run() 函式通過訊息迴圈,檢查訊息佇列中的有效訊息。如果訊息有效,Run 函式會根據訊息型別採取不同的處理方式。如果沒有訊息可用,Run 函式則會呼叫 OnIdle()函式完成空閒時程式或框架需要執行的操作。當應用程式結束時,Run 函式會呼叫 ExitInstance()函式。
-
Run 函式的封裝情況如下:
int CWinThread::Run() { ASSERT_VALID(this); _AFX_THREAD_STATE* pState = AfxGetThreadState(); // for tracking the idle time state BOOL bIdle = TRUE; LONG lIdleCount = 0; // acquire and dispatch messages until a WM_QUIT message is received. for (;;) { // phase1: check to see if we can do idle work while (bIdle && !::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)) { // call OnIdle while in bIdle state if (!OnIdle(lIdleCount++)) bIdle = FALSE; // assume "no idle" state } // phase2: pump messages while available do { // pump message, but quit on WM_QUIT if (!PumpMessage()) return ExitInstance(); // reset "no idle" state after pumping "normal" message //if (IsIdleMessage(&m_msgCur)) if (IsIdleMessage(&(pState->m_msgCur))) { bIdle = TRUE; lIdleCount = 0; } } while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE)); } }
4、MFC的訊息對映
-
在 Windows 系統中,訊息一般由從CWnd 派生而來的物件處理,包括 CFrameWnd、CMDIFrameWnd、CMDIChildWnd、CView、CDialog 和其他從這些類派生而來的物件。
-
VC 中使用訊息對映需要執行以下幾個個步驟
(1)在標頭檔案中使用 DECLARE_MESSAGE_MAP 巨集宣告訊息對映,放在類宣告結束部分。
(2)在原始檔中,使用 BEGIN_MESSAGE_MAP 巨集和 END_MESSAGE_MAP 巨集定義訊息對映,訊息對映必須定義在函式和類定義外的地方。
(3)在標頭檔案中使用 AFX_MSG 巨集宣告訊息函式。
(4)在原始檔中過載或新定義訊息函式的實現程式碼。
4.1、標準 Windows 訊息
-
為簡化工作,Windows 系統提供了標準 Windows 訊息,一般由對話方塊類和檢視類根據引數進行處理。這些標準 Windows 訊息以 WM 開頭的訊息 ID 和對應的巨集,格式是 ON_WM_xxx ;標準 Windows 訊息對應的處理函式名根據訊息巨集派生而來,格式 OnXxx;訊息處理函式的引數順序依次是 wParam 和 IParam。
// .h檔案中 class CMainFrame : public CMDIFrameWndEx { afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); DECLARE_MESSAGE_MAP() }; //.cpp 檔案中 BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx) ON_WM_CREATE() END_MESSAGE_MAP()
4.2、觸發選單/快捷鍵產生的命令訊息
-
命令訊息是使用者觸發選單或者快捷鍵時發出的訊息。使用 ON_COMMAND 巨集可以在訊息對映表中指定命令訊息的處理函式;使用 ON_UPDATE_COMMAND_UI 巨集可以在訊息對映表中指定命令更新訊息對應的處理函式。巨集的第一個引數是命令 ID ,第二個引數是命令訊息的處理函式。命令處理函式沒有引數和返回值,命令更新處理函式只有一個 CCmdUI 型別的引數並且沒有返回值。定義方式如下:
ON_COMMAND(id,memberFxn)//命令訊息巨集 ON_UPDATE_COMMANDA_UI(id,memberFxn)//命令更新訊息定義 例: // .h檔案中 #define ID_MYCMD 100//自定義訊息值 afx_msg void OnMyCommand();//訊息處理函式 afx_msg void OnUpdateMyCommand(CCmdUI* pCmdUI); DECLARE_MESSAGE_MAP() // .cpp 檔案中 BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx) ON_COMMAND(ID_MYCMD, OnMyCommand)//訊息對映 ON_UPDATE_COMMAND_UI(ID_MYCMD, OnUpdateMyCommand) END_MESSAGE_MAP() void CMainFrame::OnMyCommand()//訊息函式實現 { system("pass"); } void CMainFrame::OnUpdateMyCommand(CCmdUI* pCmdUI) { system("pass"); }
4.3、使用 ON_MESSAGE 巨集自定義訊息
-
使用 ON_MESSAGE 巨集可以在訊息對映表中指定訊息對應的處理函式。
//.h #define WM_MYMESSAGE WM_USER+100 afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() //.cpp BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx) ON_MESSAGE(WM_MYMESSAGE,OnMyMessage) END_MESSAGE_MAP() *CWnd* pWnd = new CWnd; pWnd->SendMessage(WM_MYMESSAGE);
- 使用者自定義的訊息 ID 值的範圍在 WM_USER~0x7fff.
4.4、註冊系統訊息
-
要在系統中定義一個獨立於視窗的唯一的訊息處理,可以使用 Windows 註冊訊息,使用 RegisterWindowMessage()函式可以建立在系統中唯一的訊息 ID, 使用 ON_REGISTERED_MESSAGE 巨集可以在訊息對映表中指定 Windows 註冊訊息對應的處理函式,巨集的引數為使用 RegisterWindowMessage()函式返回的UINT 型別的訊息 ID 。
//.h afx_msg LRESULT OnParse(WPARAM wParam, LPARAM lParam); //.cpp //註冊 Windows 訊息 static UINT NEAR WM_PARSE = RegisterWindowMessage((LPCWSTR)"COMMDLG_PARSE"); BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx) ON_REGISTERED_MESSAGE(WM_PARSE,OnParse) END_MESSAGE_MAP() LRESULT CMainFrame::OnParse(WPARAM wParam, LPARAM lParam) { system("pass"); return 0; }