CBT Message Box

A Win32 API centering enhancement for message boxes.


Environment: 32-bit Windows


Message boxes are normally placed in the center of the desktop window. It is often desirable to create messages boxes over the parent app window. This cannot be done by using the standard Win32 API call:


The code below centers a message box over a parent window by using a CBT (computer-based training) hook. All message box calls are made with a substitute function called "CBTMessageBox," which inserts the CBT hook prior to activating a message box.

The CBTProc function processes a thread-specific hook. The needed notification code is HCBT_ACTIVATE, which is issued whenever a new window is about to be activated (made visible). The wParam holds the forthcoming window handle value. The parent window handle can be found by using the GetForegroundWindow() function.

Centering is done by finding the center point of the parent window and by calculating the upper left corner starting point of the message box. The starting point will be adjusted if the message box dimensions exceed the desktop window region.

The CBT hook will remain active until the necessary HCBT_ACTIVATE code is issued. Because several other CBT codes may be waiting in the hook queue when the SetWindowsHookEx call is made, it is useful to have the CBTProc continue the hook chain if another code is issued first. The CallNextHookEx function helps to ensure proper chaining of hooks issued by other apps.

The CBT hook process can be used to center any window to another. Just declare the hhk=SetWindowsHookEx function before activating a window.

Steps to Add CBTMESSAGEBOX to WIN32 API Code

(#include <windows.h>)

//1) Declare functions


//2) Declare hook handle as global

HHOOK hhk;

//3) Add functions

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

  HWND  hParentWnd, hChildWnd;    // msgbox is "child"
  RECT  rParent, rChild, rDesktop;
  POINT pCenter, pStart;
  INT   nWidth, nHeight;

  // notification that a window is about to be activated
  // window handle is wParam
  if (nCode == HCBT_ACTIVATE)
    // set window handles
    hParentWnd = GetForegroundWindow();
    hChildWnd  = (HWND)wParam;

    if((hParentWnd != 0) &&
       (hChildWnd != 0) &&
       (GetWindowRect(GetDesktopWindow(), &rDesktop) != 0) &&
       (GetWindowRect(hParentWnd, &rParent) != 0) &&
       (GetWindowRect(hChildWnd, &rChild) != 0))
       // calculate message box dimensions
       nWidth  = (rChild.right - rChild.left);
       nHeight = (rChild.bottom - rChild.top);

       // calculate parent window center point
       pCenter.x = rParent.left+((rParent.right
                 - rParent.left)/2);
       pCenter.y = rParent.top+((rParent.bottom
                 - rParent.top)/2);

       // calculate message box starting point
       pStart.x = (pCenter.x - (nWidth/2));
       pStart.y = (pCenter.y - (nHeight/2));
       // adjust if message box is off desktop
       if(pStart.x < 0) pStart.x = 0;
       if(pStart.y < 0) pStart.y = 0;
       if(pStart.x + nWidth > rDesktop.right)
          pStart.x = rDesktop.right - nWidth;
       if(pStart.y + nHeight > rDesktop.bottom)
          pStart.y = rDesktop.bottom - nHeight;

       // move message box
                  pStart.x, pStart.y,
                  nWidth, nHeight,
    // exit CBT hook
  // otherwise, continue with any possible chained hooks
  else CallNextHookEx(hhk, nCode, wParam, lParam);
  return 0;

//instead of MessageBox(HWND,LPTEXT,LPCAPTION,UITYPE);
//to produce a centered message box.


Download source - 2 Kb


  • Neat result and Fun to learn

    Posted by Bni on 04/20/2005 04:30pm

    Make the reader discovering new usage for hook procedure

  • Nice work!

    Posted by Legacy on 01/28/2004 12:00am

    Originally posted by: Yasuhiko Yoshimura

    Thank you very much!

  • Very useful

    Posted by Legacy on 09/18/2003 12:00am

    Originally posted by: H.Danler

    I used parts of your code to center a child window over a parent window. Works very good. Thanks a lot.

  • Beautiful work!

    Posted by Legacy on 02/12/2003 12:00am

    Originally posted by: Igor Galitsky


  • A question....

    Posted by Legacy on 02/04/2003 12:00am

    Originally posted by: Time

    can I know a window is dialog or not dialog? If we can do that I think a global hook will good.

    SkinMagic SDK for C/C++

  • Good Example, Creative!!

    Posted by Legacy on 01/31/2003 12:00am

    Originally posted by: Zhefu Zhang

    Good job

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

Top White Papers and Webcasts

  • By providing developers with the right tools to detect, understand, and fix problems early, your business can simplify software development, shorten development lifecycles, and improve the quality of software code. The end result is increased innovation, secure applications, and a faster time to market — all at a lower cost.

  • Lenovo recommends Windows 8 Pro. "I dropped my laptop getting out of the taxi." This probably sounds familiar to most IT professionals. If your employees are traveling, you know their devices are in for a rough go. Whether it's a trip to the conference room or a convention out of town, any time equipment leaves a user's desk it is at risk of being put into harm's way. Stay connected at all times, whether at the office or on the go, with agile, durable, and flexible devices like the Lenovo® …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date