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

  • Live Event Date: November 20, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Are you wanting to target two or more platforms such as iOS, Android, and/or Windows? You are not alone. 90% of enterprises today are targeting two or more platforms. Attend this eSeminar to discover how mobile app developers can rely on one IDE to create applications across platforms and approaches (web, native, and/or hybrid), saving time, money, and effort and introducing apps to market faster. You'll learn the trade-offs for gaining long …

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds