VC定制特性化的MessageBox處理辦法。本站提示廣大學習愛好者:(VC定制特性化的MessageBox處理辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是VC定制特性化的MessageBox處理辦法正文
信任學過VC的人都曉得MessageBox()函數的用法:
int MessageBox( HWND hWnd, // handle to owner window LPCTSTR lpText, // text in message box LPCTSTR lpCaption, // message box title UINT uType // message box style );
固然在參數uType中可以指定一些款式,但你在法式中可以或許對MessageBox的外不雅所做的界說卻不多。緣由是當挪用MessageBox()函數後,它在外部有本身的新聞輪回(一切的形式對話框都有本身的新聞輪回),前往時MessageBox對話框窗口曾經被Destroy,所以你沒有方法獲得MessageBox對話框的窗口句柄。但你可以依據本身的分歧需求用上面的辦法中去定制你的MessageBox:
假如你只是想用本身的icon去取代體系MessageBox供給的那幾種無限的icon,用MessageBoxIndirect()函數便可以了:
int MessageBoxIndirect( CONST LPMSGBOXPARAMS lpMsgBoxParams // message box parameters ); typedef struct { UINT cbSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpszText; LPCTSTR lpszCaption; DWORD dwStyle; LPCTSTR lpszIcon; DWORD_PTR dwContextHelpId; MSGBOXCALLBACK lpfnMsgBoxCallback; DWORD dwLanguageId; } MSGBOXPARAMS, *PMSGBOXPARAMS;
看到MSGBOXPARAMS構造中的lpszIcon吧,在應用進程中你應該預備一個適合的MSGBOXPARAMS構造,假如你要用本身的icon,你必定要用MB_USERICON這個flag。
下面我們也講到不克不及定制MessageBox對話框的緣由是沒有方法獲得它的窗口句柄,但我們真的沒有方法了嗎?固然有方法,那就是應用HOOK(鉤子)機制。在windows體系中有多種HOOK,但在這裡我們只用到HK_CBT類型的鉤子。HK_CBT鉤子進程在WM_MOVE、WM_SIZE、WM_ACTIVE、WM_CREATE、WM_DESTROY時被體系挪用,所以HK_CBT鉤子可以在這裡用。上面讓我們看若何完成MessageBox的定制進程。
1.裝置HK_CBT鉤子;
2.挪用MessageBox()函數;
3.移除HK_CBT鉤子。
全部進程很簡略吧?我們在這裡引見第一步和第三步。
裝置HK_CBT鉤子:
HHOOK hMsgBoxHook = SetWindowsHookEx( WH_CBT, // Type of hook CBTProc, // Hook procedure (see below) NULL, // Module handle. Must be NULL (see docs) GetCurrentThreadId() // Only install for THIS thread!!! );
主要的是SetWindowHookEx()函數的後邊兩個參數,用它可以差別裝置是一個全局鉤子照樣一個線程鉤子,在這裡我們只需裝置一個線程鉤子。所以我們將Module handle設置為NULL,同時將thread ID設為本線程的ID。
在SetWindowHookEx()函數中有一個hook procedure,這是window挪用的一個回調函數,在windows體系中有一個HOOK鏈,我們在編寫hook procedure時要留意包管此鏈的完全,所以我們的hook procedure要挪用CallNextHookEx()函數。上面就是我們的hook procedure:
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) { HWND hwnd; if(nCode < 0) return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam); switch(nCode) { case HCBT_ACTIVATE: // 如今wParam中就是message box的句柄 hwnd = (HWND)wParam; // 我們曾經有了message box的句柄,在這裡我們便可以定制message box了! return 0; } // Call the next hook, if there is one return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam); }
移除HK_CBT鉤子:
只需挪用UnhookWindowsHookEx()函數便可以了
好了,我們將在下面的三步寫成一個函數,以下:
int MsgBoxEx(HWND hwnd, TCHAR *szText, TCHAR *szCaption, UINT uType) { int ret; // Install a thread hook, so we can customize it hMsgBoxHook = SetWindowsHookEx( WH_CBT, CBTProc, NULL, GetCurrentThreadId() ); // Display a standard message box ret = MessageBox(hwnd, szText, szCaption, uType); // remove the window hook UnhookWindowsHookEx(hMsgBoxHook); return ret; }
其實你也能夠鉤住WM_CREATE新聞,不外那樣處置要龐雜一些。在晚期的windows platform SDK中就有如許一個例子。
你能夠說,定制一個MessageBox有甚麼用途,我想有上面的用處:
1.你可以用CreateWindowEx()給MessageBox添加一個check box控件,並子類化MessageBox來處置check box的新聞
2.經由過程子類化轉變messagebox、button或icon,以便和你全部法式的界面作風相分歧
只需有了MessageBox對話框的句柄,你能做的許多,許多...
別的,假如你對形式對話框的機理很懂得,你可以本身寫出一個"MessageBox"來取代體系MessageBox用在你的法式中。你可以參考Jeffrey Richter的《Windows 95程式設計指南》,在書中給出了形式對話框的偽碼。這本書的繁體電子版可以在候捷的小我網站高低載。這類辦法也比擬簡略(添加一個新聞輪回,Enable/Disable Owner窗口),示例代碼這裡就不完成了。讀者可以參考相干材料加以完美。