Click here to Skip to main content
15,867,835 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.7K   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 
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 
Confused | :confused: Sorry to be so picky, but your use of indentation made reading your code to be too much like work.
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.