a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

VC定制個性化的MessageBox解決方法

2020-01-26 15:28:51
字體:
來源:轉載
供稿:網友

相信學過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窗口),示例代碼這里就不實現了。讀者可以參考相關資料加以完善。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: www.av7788.com| 亚洲欧美一区二区三区 | 91麻豆久久久 | 国产成人免费视频网站高清观看视频 | 免费在线观看一级毛片 | 99久久国产综合精品女不卡 | 久久久久久久久久穴 | 少妇av片| 成人在线精品 | 国产成人午夜精品影院游乐网 | 欧美日韩福利视频 | 精品日韩欧美一区二区三区在线播放 | 久久精品久久久久久 | 91精品在线观看入口 | 一级片在线免费看 | 成人精品 | 一区二区三区免费 | 国产视频久久久 | 亚洲高清在线视频 | 午夜精品一区二区三区免费视频 | 亚洲呦呦 | 欧美日韩精品 | 国产情侣一区二区三区 | 国产精品第一区 | 6080亚洲精品一区二区 | 国产精品久久久99 | 日韩一区二区中文字幕 | 成人欧美一区二区三区在线播放 | 色网站免费看 | 成人免费视频网站 | 欧美视频网址 | 日本免费一区二区三区 | 精品久久一区二区 | 国产在线一级视频 | 久草视| 国产一区二区三区免费在线 | 欧美啊v | 国产精品色婷婷久久58 | www.久久久| 欧美一级片| 国产精品成人一区二区 |