The following short program inserts a thread-specific CBT hook inside the standard message box. The notification code HCBT_ACTIVATE, is sent whenever a new messagebox is activated and used to set up a timer which counts down from 10 to 0 before the messagebox is terminated.
#include <windows.h>
#include <tchar.h>
#define MY_TIMER 1
HWND staticbox;
TCHAR countdown[2]=TEXT("\0");
int nTimer;
HHOOK hMsgBoxHook;
//process countdown timer event
VOID CALLBACK MyTimerProc( HWND hWnd, UINT uTimerMsg, UINT uTimerID, DWORD dwTime )
{
static int timercount=9;
wsprintf(countdown,TEXT("%d"),timercount);
SetWindowText(staticbox, countdown);
if (timercount==0)
{
PostQuitMessage(0);
}
--timercount;
}
//customised windows procedure for handling message box bahaviour
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
HWND hwnd;
HFONT font;
switch(nCode)
{
//detects creation of new messagebox window.
case HCBT_ACTIVATE:
// Get handle to the message box!
hwnd = (HWND)wParam;
//create messagebox contents
staticbox=CreateWindow(TEXT("static"), TEXT("10"),WS_CHILD | WS_VISIBLE ,5, 5, 35, 35,hwnd, (HMENU) 1, NULL, NULL);//static control
font = CreateFont(25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,TEXT("Times New Roman"));
SendMessage(staticbox,WM_SETFONT,(WPARAM)font,0);
nTimer = SetTimer( hwnd, MY_TIMER, 1000,(TIMERPROC)MyTimerProc );
return 0;
}
return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd)
{
// Window hook allows the application to intercept message-box creation, and customise it
hMsgBoxHook = SetWindowsHookEx(WH_CBT, CBTProc, NULL, GetCurrentThreadId() );
// Display a standard message box
MessageBox(NULL, NULL, TEXT("Self terminating message box"),NULL);
// remove the window hook
UnhookWindowsHookEx(hMsgBoxHook);
return 0;
}