Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to change the MessageBox window (Add controls and change texts)?

0.00/5 (No votes)
6 Apr 2005 1  
This article describes how to change the MessageBox window (Add controls and change texts).

Sample Image - dMsgBox.jpg

Introduction

In this article we will learn how to add controls to a MessageBox or how to change its button texts. You can use this method to create (full) Multilanguage programs (Just a suggestion!). There are some ways to do this and I chose the hooking method.

Steps of Hooking a MessageBox

To hook a MessageBox:

  • Use SetWindowsHookEx () function with WH_CALLWIND and pass it to a hookproc.
  • Declare a hook procedure.
  • In the hookproc use the SetWindowLong () function to handle the MessageBox window Creation process (Maybe it is a good name for this).
  • Declare a CALLBACK function to handle the MessageBox window creation process.
  • Pass the CALLBACK function as the new long parameter in the SetWindowLong () function.
  • And at the end, place your codes in the CALLBACK function (codes for window creation).

SetWindowsHookEx () function

This function installs a hook procedure. Using this function you can hook windows events. In other words when you install a hook procedure you tell the system to notify you when the wanted event is called.

As MSDN says: The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.

How to Install a hook procedure using SetWindowsHookEx () function?

g_hHook = SetWindowsHookEx (WH_CALLWNDPROC,
                               (HOOKPROC)SetHook,
                               NULL,
                               GetCurrentThreadId ());

Where g_hHook is a global variable and the SetHook is my HookProc;

What is WH_CALLWNDPROC?

Use this parameter to install a hook procedure that monitors messages before the system sends them to the destination window procedure (MSDN).

Declaring a HookProcedure

Use the following declarations in your header file:

LRESULT CALLBACK SetHook(int nCode,WPARAM wParam,LPARAM lParam);

This will declare a hook procedure by name SetHook. See this code snippet:

LRESULT CALLBACK SetHook(int nCode,WPARAM wParam,LPARAM lParam)
{
if (nCode==HC_ACTION)
{
    CWPSTRUCT* pwp = (CWPSTRUCT*)lParam;
    
    if (pwp->message==WM_INITDIALOG)
        
    oldProc=(WNDPROC)SetWindowLong(pwp>hwnd,
GWL_WNDPROC,(LONG)HookWndProc); 
}
return CallNextHookEx(g_hHook,nCode,wParam,lParam);
}

This code snippet is my SetHook procedure.

What is GWL_WNDPROC?

This parameter sets a new address for the window procedure. (I think it is enough).

What is CWPSTRUCT?

This is a structure that contains information about window messages like a handle to that window (hwnd). We pass a pointer of this structure to use the hwnd member in the callback function.

And the HookWndProc is a function that processes the window creation codes.

Handling the window creation process

To do this, you must declare a CALLBACK function.

LRESULT CALLBACK HookWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

This is my HookWndProc procedure.

LRESULT CALLBACK HookWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    //Let OS to perform basic operation

    LRESULT rc = CallWindowProc( oldProc, hWnd, uMsg, wParam, lParam );

    //If MessageBox wanted to initialized, do something

    if (uMsg==WM_INITDIALOG)
    {
        if (m_hIcon)
            SetIcon(hWnd,m_hIcon);
            CreateButton(hWnd);    

        if (m_strCaption)
            SetCaption(hWnd);
    }
    if (uMsg==WM_COMMAND&&wParam==IDC_CHECKBOX)
        //If user clicked the check box handle it!

        SetOut(wParam);
    if (uMsg==WM_NCDESTROY)
        //On exit Uninstall the hook procedure

        //If we don't do that every message box will have 

        //A check box on it!

        UnInstallHook(g_hHook);
return rc;
}

The main operations are done. I mean the hwnd. After having this hwnd, we can do everything to the MessageBox window. But don�t forget to call CallWindowProc function.

What does the CallWindowProc do?

According to MSDN: The CallWindowProc function passes message information to the specified window procedure.

I used this function because I didn�t want to paint the MessageBox window myself and I wanted only to change some texts. If you want to paint the main window, I think you shouldn�t call this function!

For more information about SetWindowsHookEx, SetWindowLong and CallWindowProc use MSDN Library. (I think it is the best reference to revert).

And at last I want to warn you: Call the CallNextHookEx () function because if you don�t do this, other applications that may have installed a hook chain will not receive the hook information and I know you don�t want it.

And like always, according to MSDN that says: Calling the CallNextHookEx function to chain to the next hook procedure is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.

Last Words

First of all, I want to thanks to Mr. Nicolas Bonamy. His article helped me a lot.

There is a demo app which if you want, can download. In that project I have a class that contains some codes for adding a CheckBox to the MessageBox and to change the text of buttons and some functions to place the controls in a right and good place.

And I want to say that my English is not very well and it is a reason to write MSDN Library definitions for some functions (Excuse me for bad grammar).

And at last I suggest you to use Visual Assist X because it is a helpful plug-in for Visual Studio.

Please vote this article if you find it interesting and informative. Opinions and comments are welcome.

G.K.Z - King Zoser.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here