最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

VC定制個(gè)性化的MessageBox解決方法

 更新時(shí)間:2014年07月16日 14:54:43   投稿:shichen2014  
這篇文章主要介紹了VC定制個(gè)性化的MessageBox解決方法,有助于進(jìn)一步的了解windows應(yīng)用程序的消息機(jī)制及運(yùn)行原理,需要的朋友可以參考下

相信學(xué)過VC的人都知道MessageBox()函數(shù)的用法:

int MessageBox(
 HWND hWnd,     // handle to owner window
 LPCTSTR lpText,   // text in message box
 LPCTSTR lpCaption, // message box title
 UINT uType     // message box style
);

雖然在參數(shù)uType中可以指定一些樣式,但你在程序中能夠?qū)essageBox的外觀所做的定義卻不多。原因是當(dāng)調(diào)用MessageBox()函數(shù)后,它在內(nèi)部有自己的消息循環(huán)(所有的模式對(duì)話框都有自己的消息循環(huán)),返回時(shí)MessageBox對(duì)話框窗口已經(jīng)被Destroy,所以你沒有辦法得到MessageBox對(duì)話框的窗口句柄。但你可以根據(jù)自己的不同需求用下面的方法中去定制你的MessageBox:

如果你只是想用自己的icon去代替系統(tǒng)MessageBox提供的那幾種有限的icon,用MessageBoxIndirect()函數(shù)就可以了:

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結(jié)構(gòu)中的lpszIcon吧,在使用過程中你應(yīng)當(dāng)準(zhǔn)備一個(gè)合適的MSGBOXPARAMS結(jié)構(gòu),如果你要用自己的icon,你一定要用MB_USERICON這個(gè)flag。

上面我們也講到不能定制MessageBox對(duì)話框的原因是沒有辦法得到它的窗口句柄,但我們真的沒有辦法了嗎?當(dāng)然有辦法,那就是使用HOOK(鉤子)機(jī)制。在windows系統(tǒng)中有多種HOOK,但在這里我們只用到HK_CBT類型的鉤子。HK_CBT鉤子過程在WM_MOVE、WM_SIZE、WM_ACTIVE、WM_CREATE、WM_DESTROY時(shí)被系統(tǒng)調(diào)用,所以HK_CBT鉤子可以在這里用。下面讓我們看如何實(shí)現(xiàn)MessageBox的定制過程。

1.安裝HK_CBT鉤子;
2.調(diào)用MessageBox()函數(shù);
3.移除HK_CBT鉤子。

整個(gè)過程很簡(jiǎn)單吧?我們?cè)谶@里介紹第一步和第三步。

安裝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()函數(shù)的后邊兩個(gè)參數(shù),用它可以區(qū)別安裝是一個(gè)全局鉤子還是一個(gè)線程鉤子,在這里我們只要安裝一個(gè)線程鉤子。所以我們將Module handle設(shè)置為NULL,同時(shí)將thread ID設(shè)為本線程的ID。

在SetWindowHookEx()函數(shù)中有一個(gè)hook procedure,這是window調(diào)用的一個(gè)回調(diào)函數(shù),在windows系統(tǒng)中有一個(gè)HOOK鏈,我們?cè)诰帉慼ook procedure時(shí)要注意保證此鏈的完整,所以我們的hook procedure要調(diào)用CallNextHookEx()函數(shù)。下面就是我們的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:
    // 現(xiàn)在wParam中就是message box的句柄
    hwnd = (HWND)wParam;
    // 我們已經(jīng)有了message box的句柄,在這里我們就可以定制message box了!
    return 0;
  }
  // Call the next hook, if there is one
  return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam);
}

移除HK_CBT鉤子:

只要調(diào)用UnhookWindowsHookEx()函數(shù)就可以了

好了,我們將在上面的三步寫成一個(gè)函數(shù),如下:

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;
}

其實(shí)你也可以鉤住WM_CREATE消息,不過那樣處理要復(fù)雜一些。在早期的windows platform SDK中就有這樣一個(gè)例子。

你可能說,定制一個(gè)MessageBox有什么用處,我想有下面的用途:

1.你可以用CreateWindowEx()給MessageBox添加一個(gè)check box控件,并子類化MessageBox來處理check box的消息

2.通過子類化改變messagebox、button或icon,以便和你整個(gè)程序的界面風(fēng)格相一致

只要有了MessageBox對(duì)話框的句柄,你能做的很多,很多...

另外,如果你對(duì)模式對(duì)話框的機(jī)理很了解,你可以自己寫出一個(gè)"MessageBox"來代替系統(tǒng)MessageBox用在你的程序中。你可以參考Jeffrey Richter的《Windows 95程式設(shè)計(jì)指南》,在書中給出了模式對(duì)話框的偽碼。這本書的繁體電子版可以在候捷的個(gè)人網(wǎng)站上下載。這種方法也比較簡(jiǎn)單(添加一個(gè)消息循環(huán),Enable/Disable Owner窗口),示例代碼這里就不實(shí)現(xiàn)了。讀者可以參考相關(guān)資料加以完善。

相關(guān)文章

  • 詳解C++中對(duì)構(gòu)造函數(shù)和賦值運(yùn)算符的復(fù)制和移動(dòng)操作

    詳解C++中對(duì)構(gòu)造函數(shù)和賦值運(yùn)算符的復(fù)制和移動(dòng)操作

    這篇文章主要介紹了C++中對(duì)構(gòu)造函數(shù)和賦值運(yùn)算符的復(fù)制和移動(dòng),是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-01-01
  • Typedef在C語(yǔ)言和C++中的用法和區(qū)別

    Typedef在C語(yǔ)言和C++中的用法和區(qū)別

    在C語(yǔ)言和C++中,typedef是一個(gè)非常常用的關(guān)鍵字,用于為數(shù)據(jù)類型定義別名,盡管它在兩種語(yǔ)言中都有相似的功能,但由于C++具有更豐富的類型系統(tǒng),因此在實(shí)際應(yīng)用中,typedef在兩者間的使用存在一些微妙的差異
    2024-01-01
  • C++ 內(nèi)存管理原理分析

    C++ 內(nèi)存管理原理分析

    本章主要介紹C++的內(nèi)存管理,以C++的內(nèi)存分布作為引入,介紹C++不同于C語(yǔ)言的內(nèi)存管理方式(new delete對(duì)比 malloc free),最后為了加深讀者的理解,會(huì)介紹new和delete的底層實(shí)現(xiàn)原理
    2021-11-11
  • 嵌入式QT移植的實(shí)現(xiàn)

    嵌入式QT移植的實(shí)現(xiàn)

    本文主要介紹了嵌入式QT移植的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C++如何通過ostringstream實(shí)現(xiàn)任意類型轉(zhuǎn)string

    C++如何通過ostringstream實(shí)現(xiàn)任意類型轉(zhuǎn)string

    再使用整型轉(zhuǎn)string的時(shí)候感覺有點(diǎn)棘手,因?yàn)閕toa不是標(biāo)準(zhǔn)C里面的,而且即便是有itoa,其他類型轉(zhuǎn)string不是很方便。后來去網(wǎng)上找了一下,發(fā)現(xiàn)有一個(gè)好方法
    2013-09-09
  • C++string字符串拼接遇到的問題及解決

    C++string字符串拼接遇到的問題及解決

    這篇文章主要介紹了C++string字符串拼接遇到的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • c++ 中__declspec 的用法詳解

    c++ 中__declspec 的用法詳解

    這篇文章主要介紹了c++ 中__declspec 的用法詳解,對(duì)初學(xué)者有一定的幫助,有需要的可以了解一下。
    2016-11-11
  • C語(yǔ)言實(shí)現(xiàn)按月顯示的日歷

    C語(yǔ)言實(shí)現(xiàn)按月顯示的日歷

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)按月顯示的日歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++11 lambda表達(dá)式在回調(diào)函數(shù)中的使用方式

    C++11 lambda表達(dá)式在回調(diào)函數(shù)中的使用方式

    這篇文章主要介紹了C++11 lambda表達(dá)式在回調(diào)函數(shù)中的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語(yǔ)言實(shí)現(xiàn)strlen的三種方法小結(jié)

    C語(yǔ)言實(shí)現(xiàn)strlen的三種方法小結(jié)

    本文主要介紹了C語(yǔ)言實(shí)現(xiàn)strlen的三種方法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

固镇县| 罗山县| 吴川市| 大方县| 乌鲁木齐县| 镇赉县| 团风县| 临泉县| 临朐县| 郯城县| 临沂市| 仁寿县| 呼和浩特市| 重庆市| 玉树县| 巴彦淖尔市| 韶山市| 河南省| 武安市| 克东县| 利津县| 平和县| 青浦区| 利津县| 栾川县| 军事| 项城市| 杭州市| 曲阜市| 资阳市| 磐石市| 拜泉县| 商洛市| 卫辉市| 肃南| 蓝山县| 铜山县| 南川市| 荥阳市| 嘉荫县| 江陵县|