0

As I found out by searching, it is not possible to create a MessageBox() with center-aligned text.

So is there some simple alternative providing the MessageBox() functionality (including program wait for closing/accepting the box) that has an option to center-align the text?

Thanks for suggestions/examples.

PS: On Windows7+, using C++ Windows API (compiled in MS Visual Studio 2012)

EDIT:
Some useful tips:
1) Express version of Visual Studio does NOT have a resource editor/file create option:

2) Visual Studio C++ how to display a dynamic message (i.e., string) in my About box?

Community
  • 1
  • 1
jave.web
  • 13,880
  • 12
  • 91
  • 125

2 Answers2

3

As I found out by searching, it is not possible to create a MessageBox() with center-aligned text.

It is not possible to create a center-aligned MessageBox() dialog, as the API does not expose an option for that. But it is possible to manipulate the standard MessageBox()` dialog with some slight trickery to force it to be center-aligned.

Use SetWindowsHookEx() to create a WH_CBT hook for the thread that is calling MessageBox() (no DLL needed). The hook callback allows you to discover the HWND of the dialog that MessageBox() creates. With that, you can manipulate it however you want. In this case, you can use FindWindowEx() to get the HWND of the STATIC control for the dialog's text and then apply the SS_CENTER style to it using SetWindowLong(). For example:

LRESULT CALLBACK CenterMsgBoxTextProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_ACTIVATE)
    {
        HWND hDlg = (HWND) wParam;
        HWND hTxt = FindWindowEx(hDlg, NULL, TEXT("STATIC"), NULL);
        if (hTxt)
            SetWindowLong(hTxt, GWL_STYLE, GetWindowLong(hTxt, GWL_STYLE) | SS_CENTER);
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

HHOOK hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC) &CenterMsgBoxTextProc, NULL, GetCurrentThreadId());
MessageBox(...);
if (hHook) UnhookWindowsHookEx(hHook);

Alternatively, you can use SetWinEventHook() instead of SetWindowsHookEx():

void CALLBACK CenterMsgBoxTextProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
    HWND hTxt = FindWindowEx(hwnd, NULL, TEXT("STATIC"), NULL);
    if (hTxt)
        SetWindowLong(hTxt, GWL_STYLE, GetWindowLong(hTxt, GWL_STYLE) | SS_CENTER);
}

HWINEVENTHOOK hHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, &CenterMsgBoxTextProc, GetCurrentProcessId(), GetCurrentThreadId(), 0);
MessageBox(NULL, TEXT("test"), TEXT("test"), MB_OK);
if (hHook) UnhookWinEvent(hHook);

Here is what the result looks like in both cases:

proof

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Tricky, but useful, is it just me or is it a bit off-center? (that would not matter though...) Anyway I was i fact right at all , you can't create such MessageBox but you can force it after creation :) – jave.web Mar 03 '15 at 02:38
  • 1
    The text is centered within the width of the `STATIC` control, but the control itself does not stretch across the entire width of the dialog by default. However, since you can obtain both HWNDs, you can query the dialog's client width and adjust the control's width as needed. – Remy Lebeau Mar 03 '15 at 03:00
  • 1
    Manipulating the `MessageBox()` HWND in this manner is how people used to implement `MessageBoxTimeout()` before it was a standard function, or add custom controls to the dialog (such as a "remember this option" type of checkbox), or customize the button texts, etc. – Remy Lebeau Mar 03 '15 at 03:04
1

Afaik there is not. But it is actually quite easy to create such a dialog using Win32 resources and the DialogBox function.

Felix Bytow
  • 345
  • 1
  • 6
  • Yes, I ment something like that, could you provide and example how to center the text in DialogBox? – jave.web Mar 02 '15 at 10:15
  • You simply put a STATIC control in your dialog and give it the [Style](https://msdn.microsoft.com/en-us/library/windows/desktop/bb760773%28v=vs.85%29.aspx) SS_CENTER. Searching for "Win32 example rc" should give you an example. Also if you use MSVC you can just click your dialog together and set that style on the Static control. – Felix Bytow Mar 02 '15 at 10:20
  • Sorry but I'm a bit lost here, how would I add a STATIC control to a dialogBox ? I just can't find it, – jave.web Mar 02 '15 at 10:46
  • http://www.transmissionzero.co.uk/computing/win32-apps-with-mingw/ look for the "About Dialog" section. [This](https://msdn.microsoft.com/en-us/library/windows/desktop/aa381043%28v=vs.85%29.aspx) tells me there is also a CTEXT element for centered texts. Also I cannot give you a concrete example as I am currently on Linux. – Felix Bytow Mar 02 '15 at 10:50
  • Scroll to "About Dialog" section in JS: `document.getElementsByTagName('h3')[9].scrollIntoView()` :) – jave.web Mar 02 '15 at 11:45
  • 1
    Sorry, but no, it's not at all easy to write your own version of a `MessageBox`. There's more to it than simply showing a dialog. For example, when pressing [Ctrl]+C, a standard `MessageBox` will render a text version of its contents to the clipboard. There's more than meets the eye. – IInspectable Mar 02 '15 at 11:55