Custom MessageBox -- hook

Source: Internet
Author: User

Hook has very few contacts, so he never dared to talk about anything. This MessageBox has really studied several hour, so I am afraid of being laughed at by the experts. Today, I am not ashamed of myself, let me talk about some of my views. You are welcome to throw bricks and tomatoes.

As we all know, a standard MessageBox box is usually not a custom style, because we can never find its handle. the API function MessageBox can be returned only when the MessageBox box is destroyed. Therefore, our program never saw messages in the MessageBox window, the MessageBox API calls the message loop, which is similar to the API function of dialogbox for creating the non-modal dialog box.

First, let's talk about how to modify the text on the standard OK button.

The best way to intercept messages in the messagbox box is to install a hook, which is very easy to implement-setwindowshookex. There are many different types of hooks, each of which is designed for different purposes. Here, I am not so arrogant.

Wm_cbt hook is used here. This hook is called only for a few messages, such as wm_activate, wm_create, wm_destroy, wm_size, and wm_move. Because we want to implement our custom style during window creation, this hook is in line with our purpose.

Install a hook

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!!! );

 

Please note that getcurrentthreadid () is only installed in this thread.

Remove a hook

UnhookWindowsHookEx(hMsgBoxHook);

 

Core Part-hook Process

As mentioned above, a CBT event occurs whenever wm_activate and wm_create messages are sent to our application.

 

 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:// Get handle to the message box!hwnd = (HWND)wParam;// Do customization!return 0;}// Call the next hook, if there is onereturn CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam);}

 

Complete integration

Around MessageBox, we write a function that hides the details of the hook. When we want to display a custom MessageBox, we can replace it with this function.

static HHOOK hMsgBoxHook;...int MsgBoxEx(HWND hwnd, TCHAR *szText, TCHAR *szCaption, UINT uType){int retval;hMsgBoxHook = SetWindowsHookEx(WH_CBT, CBTProc, NULL, GetCurrentThreadId() );retval = MessageBox(hwnd, szText, szCaption, uType);UnhookWindowsHookEx(hMsgBoxHook);return retval;}

 

So far, we have changed the font of the OK button to our own.

The running effect is as follows:

Here, I added the max. Minimization button to MessageBox by the way. Of course, the icon can also be replaced, and so on. The rest will look at the imagination. To put it simply, I thought I could add the maximum and minimum buttons at first, so the code written is as follows:

Case hcbt_createwnd: cbt_createwnd = (lpcbt_createwnd) lparam; cbt_createwnd-> lpcs-> style | = ws_minimizebox; // The description in msdn is clear, cbt_createwnd-> lpcs-> Cx = 300; cbt_createwnd-> lpcs-> Cy = 300;

 

I found that there was no effect. I saw msdn and found that it was clear. The evidence is here:

Hcbt_createwnd Specifies the handle to the new window. Specifies a long pointer toCbt_createwndStructure Containing initialization parameters for the window. The parameters include the coordinates and dimensions of the window. By changing these parameters,CbtprocHook procedure can set the initial size and position of the window.

Only coordinates and dimensions can be set here. It is impossible to set the style.

If you want to think about it, you still need to subclass the window, because this guy is indeed very practical. Idea: Use setwindowlong to subclass the window in the wm_activate message of the window, in the window process function, I implemented a response to the button in the MessageBox box and asked him to continue to pop up a MessageBox box ..... Let's list some msdn records:

Hcbt_activate Specifies the handle to the window about to be activated. Specifies a long pointer to Structure Containing the handle to the active window and specifies whether the activation is changing because of a mouse click.

Let's talk about the rest. The Code is as follows:

# Include <windows. h> # include <tchar. h> tchar szcontents [] = _ T ("I really miss you very much -- zxj! "); Tchar sztitle [] = _ T (" hello "); # define idc_pzg 123 hhook hmsgboxhook; descricbt_createwnd; wndproc handler; int_ptr callback messageboxproc (hwnd, uint MSG, wparam, lparam) {Switch (MSG) {Case wm_command: Switch (loword (wparam) {Case idc_pzg: MessageBox (hwnd, "example", "example ", mb_ OK | mb_iconinformation); break;} case wm_destroy: postquitmessage (0); Return 0; default: Return callwindowproc (oldw Ndproc, hwnd, MSG, wparam, lparam);} return 0;} lresult callback cbtproc (INT ncode, wparam, lparam) {tchar ACH [40]; hwnd; hwnd hwndbutton; If (ncode <0) return callnexthookex (hmsgboxhook, ncode, wparam, lparam); Switch (ncode) {case when: cbt_createwnd = (lpcbt_createwnd) lparam; cbt_createwnd-> lpcs-> style | = ws_minimizebox; // it is clear in msdn that cbt_createwnd-> lpcs-> Cx = 300; cbt_createwnd-> lp CS-> Cy = 300; // hwnd = (hwnd) wparam; break; Case hcbt_activate: // case hcbt_createwnd: // get handle to the message box! Hwnd = (hwnd) wparam; oldwndproc = (wndproc) setwindowlong (hwnd, callback, (long) messageboxproc); setwindowlong (hwnd, gwl_style, (long) callback); setwindowtext (hwnd, _ T ("Message from yiruirui"); hwndbutton = getdlgitem (hwnd, idok); setwindowtext (hwndbutton, _ T ("thankyou"); createwindow ("button ", "sub-account -- AV Prince", ws_child | ws_visible, 250,250, hwnd, (hmenu) idc_pzg, getmodulehandle (null), null); Return 0 ;} Return callnexthookex (hmsgboxhook, ncode, wparam, lparam);} int msgboxex (hwnd, tchar * sztext, tchar * szcaption, uint utype) {int retval; // install a window hook, so we can intercept the message-box // creation, and customize ithmsgboxhook = setwindowshookex (wh_cbt, cbtproc, null, getcurrentthreadid () // only install for this thread !!!); // Display a standard message boxretval = MessageBox (hwnd, sztext, szcaption, utype); // remove the window hookunhookwindowshookex (hmsgboxhook); Return retval;} int winapi winmain (hinstance hinst, hinstance hprev, lpstr lpcmdline, int nshowcmd) {// just display a standard message box. // It doesn't matter that we have no parent window or a // message-loop, because MessageBox has it's own message loop. msgboxex (null, szcontents, sztitle, mb_ OK | mb_iconstop); Return 0 ;}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.