Click here to Skip to main content
15,881,638 members
Articles / Desktop Programming / MFC
Article

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

Rate me:
Please Sign up or sign in to vote.
4.52/5 (21 votes)
6 Apr 2005CPOL4 min read 118.9K   5.7K   70   11
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.

<h>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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
I started Visual C++ on 2003 and I am a beginner now,I am working on a Network program and I am searching for some partners.I am intrested in DLLs and GUI in programing.

Comments and Discussions

 
QuestionHow do I change the background color of AfxMessageBox and Open/Save dialogs? Pin
kajitams27-Jan-07 6:35
kajitams27-Jan-07 6:35 
Hi,

I was wondering if it is possible to change the background color of AfxMessageBoxes and any Open/Save/Save As dialogs that pops up from my applications.

Is there an easy way to change the background color of all the controls and dialogs on only my application?

kajitams
GeneralCheck this function Pin
leochou072920-Dec-06 19:35
leochou072920-Dec-06 19:35 
QuestionHow can I change lParam value ??? Pin
san123pune16-Nov-06 4:47
san123pune16-Nov-06 4:47 
Generalsubclassing an MFC instance Pin
ivan françois11-Apr-06 3:02
ivan françois11-Apr-06 3:02 
GeneralRe: subclassing an MFC instance Pin
dSolariuM30-Apr-06 11:57
dSolariuM30-Apr-06 11:57 
QuestionAvailable for VC6 ?? Pin
andrewtruckle17-Apr-05 19:49
andrewtruckle17-Apr-05 19:49 
AnswerRe: Available for VC6 ?? Pin
ThatsAlok19-Apr-05 19:37
ThatsAlok19-Apr-05 19:37 
GeneralYour sample message box Pin
andrewtruckle17-Apr-05 19:48
andrewtruckle17-Apr-05 19:48 
GeneralRe: Your sample message box Pin
dSolariuM19-Apr-05 5:26
dSolariuM19-Apr-05 5:26 
Generalformatting &amp; indentation Pin
RancidCrabtree15-Apr-05 6:20
RancidCrabtree15-Apr-05 6:20 
GeneralRe: formatting &amp; indentation Pin
dSolariuM18-Apr-05 4:25
dSolariuM18-Apr-05 4:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.