MessageBox with Custom Button Captions

Introduction

Have you ever wanted to change the button captions for Message Boxes? MFC does not provide any means for making this customization. The button captions (Yes, No, Ok, and so forth) are changed according the system language installed in the machine.

The following code shows how to change button captions in standard windows AfxMessageBoxes. The captions in the message boxes will be defined as String Tables in the program Resources. It was started from CBT Message Box from Tony Varnas: http://www.codeguru.com/Cpp/W-P/win32/messagebox/article.php/c4541/.

Tony's article describes how to center a Message Box; Ib'll use the same idea to change the MessageBox captions. To place the windows hook described in his article, you will need to override the application DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt). This function calls the system MessageBox function that you will replace with your own to place the hook before it's called.

Steps to Customize Message Box Captions

  1. Override your application DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt) function.
  2. Replace the call to MessageBox(hWnd,LPSTR(lpszPrompt),LPSTR(pszAppName),nType); with
    CBTMessageBox(hWnd,LPSTR(lpszPrompt),LPSTR(pszAppName),nType);
  3. Declare CBTMessageBox functions to place the windows hook before calling the MessageBox function.
  4. Override the LRESULT CALLBACK CBTProc function to catch HCBT_ACTIVATE code.
  5. Define your own captions in the string table.
#include <windows.h>
#include "afxpriv.h"

//////////////////////////////////
//1) Declare functions

INT CBTMessageBox(HWND,LPSTR,LPSTR,UINT);
LRESULT CALLBACK CBTProc(INT, WPARAM, LPARAM);

HHOOK hhk;

INT CBTMessageBox(HWND hwnd, LPSTR lpText, LPSTR lpCaption,
                  UINT uType)
{
   hhk = SetWindowsHookEx(WH_CBT, &CBTProc, 0,
                          GetCurrentThreadId());
   return MessageBox(hwnd, lpText, lpCaption, uType);
}

LRESULT CALLBACK CBTProc(INT nCode, WPARAM wParam, LPARAM lParam)
{
   HWND hChildWnd;    // msgbox is "child"
   CString s=_T("");
   // notification that a window is about to be activated
   // window handle is wParam
   if (nCode == HCBT_ACTIVATE)
   {
      // set window handles
      hChildWnd = (HWND)wParam;
      //to get the text of the Yes button
      UINT result;
      if (GetDlgItem(hChildWnd,IDYES)!=NULL)
      {
         s.LoadString(IDS_Yes);
         result= SetDlgItemText(hChildWnd,IDYES,s);
      }
      if (GetDlgItem(hChildWnd,IDOK)!=NULL)
      {
         s.LoadString(IDS_OK);
         result= SetDlgItemText(hChildWnd,IDOK,s);
      }
      //Continue changing other button captions

      // exit CBT hook
      UnhookWindowsHookEx(hhk);
   }
   // otherwise, continue with any possible chained hooks
   else CallNextHookEx(hhk, nCode, wParam, lParam);
   return 0;
}


Downloads

Comments

  • Great! Thanks.

    Posted by Ron on 01/29/2013 06:40am

    Any way to maybe autosize the buttons so long-ish captions will fit?

    Reply
  • Why doesn't this technique work for ordinary dialog boxes?

    Posted by John E on 05/19/2008 01:29pm

    Hi Miguel - this is a useful article but I'm curious to know why it only works for message boxes and not other types of dialog. As a simple example, I took your original code, thus:-
    
    INT CBTMessageBox(HWND hwnd, LPSTR lpText, LPSTR lpCaption,
                      UINT uType)
    {
       hhk = SetWindowsHookEx(WH_CBT, &CBTProc, 0, GetCurrentThreadId());
       return MessageBox(hwnd, lpText, lpCaption, uType);
    }
    
    and I modified that function just to display an 'About' box instead of the message box, like this:-
    
    INT CBTMessageBox(HWND hwnd, LPSTR lpText, LPSTR lpCaption,
                      UINT uType)
    {
       hhk = SetWindowsHookEx(WH_CBT, &CBTProc, 0, GetCurrentThreadId());
       CAboutDlg dlg(CWnd::FromHandle(hwnd));
       return dlg.DoModal();
    }
    
    However, I got numerous assertion errors when I tried that. I know it's not a good example - but I'm curious to know why it doesn't work..??
    
    John.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The latest release of SugarCRM's flagship product gives users new tools to build extraordinary customer relationships. Read an in-depth analysis of SugarCRM's enhanced ability to help companies execute their customer-facing initiatives from Ovum, a leading technology research firm.

  • The impact of a data loss event can be significant. Real-time data is essential to remaining competitive. Many companies can no longer afford to rely on a truck arriving each day to take backup tapes offsite. For most companies, a cloud backup and recovery solution will eliminate, or significantly reduce, IT resources related to the mundane task of backup and allow your resources to be redeployed to more strategic projects. The cloud - can now be comfortable for you – with 100% recovery from anywhere all …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds