CBT Message Box | CodeGuru

CBT Message Box

A Win32 API centering enhancement for message boxes. . Environment: 32-bit Windows Introduction 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: INT MessageBox(HWND,LPTEXT,LPCAPTION,UITYPE); The code below centers […]

Written By
CodeGuru Staff
CodeGuru Staff
Feb 10, 2003
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

A Win32 API centering enhancement for message boxes.

.

Environment: 32-bit Windows

Introduction

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:

INT MessageBox(HWND,LPTEXT,LPCAPTION,UITYPE);

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

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

//////////////////////////////////
//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,
                         GetCurrentThreadId());
  return MessageBox(hwnd, lpText, lpCaption, uType);
}

LRESULT CALLBACK CBTProc(INT nCode, WPARAM wParam, LPARAM lParam)
{
  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
       MoveWindow(hChildWnd,
                  pStart.x, pStart.y,
                  nWidth, nHeight,
                  FALSE);
    }
    // exit CBT hook
    UnhookWindowsHookEx(hhk);
  }
  // otherwise, continue with any possible chained hooks
  else CallNextHookEx(hhk, nCode, wParam, lParam);
  return 0;
}

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

Downloads


Download source – 2 Kb

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.