程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> VC定制特性化的MessageBox處理辦法

VC定制特性化的MessageBox處理辦法

編輯:關於C++

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窗口),示例代碼這裡就不完成了。讀者可以參考相干材料加以完美。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved