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

  • Hybrid cloud platforms need to think in terms of sweet spots when it comes to application platform interface (API) integration. Cloud Velocity has taken a unique approach to tight integration with the API sweet spot; enough to support the agility of physical and virtual apps, including multi-tier environments and databases, while reducing capital and operating costs. Read this case study to learn how a global-level Fortune 1000 company was able to deploy an entire 6+ TB Oracle eCommerce stack in Amazon Web …

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today makes data protection a must-have, as we live in a data-driven society -- the digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join Seagate Cloud …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds