Assuming that this is within Windows and the Win32 API, one option is to look for messages in your main GetMessage
, TranslateMessage
, DispatchMessage
loop. You can special-case any message within this loop, irrespective of which window it's aimed at.
You should probably use IsChild
to check that the message is intended for a control on your main window (as opposed to some dialog box or message box that might be displayed separately). Getting the logic right can be fiddly, too. It would be best to only intercept messages when you know your control has lost the focus, and only intercept the exact messages you need to.
Years ago, I wrote a library message loop with a lot of this built in. I had a simple manager class that held pointers to instances of my own little window class. The loop knew the difference between dialogs and normal windows, gave each window class a chance to spy on its childrens messages, and so on. You won't be able to run this directly and the conventions are a bit strange, but you might find this useful...
int c_Window_List::Message_Loop (void)
{
MSG msg;
bool l_Handled;
while (GetMessage (&msg, NULL, 0, 0))
{
l_Handled = false;
c_Windows::c_Cursor l_Cursor;
bool ok;
for (ok = l_Cursor.Find_First (g_Windows); ok; ok = l_Cursor.Step_Next ())
{
if (IsChild (l_Cursor.Key (), msg.hwnd))
{
if (l_Cursor.Data ().f_Accelerators != NULL)
{
l_Handled = TranslateAccelerator (l_Cursor.Key (), l_Cursor.Data ().f_Accelerators, &msg);
if (l_Handled) break;
}
if (l_Cursor.Data ().f_Manager != 0)
{
l_Handled = l_Cursor.Data ().f_Manager->Spy_Msg (l_Cursor.Key (), msg);
}
if (l_Handled) break;
if (l_Cursor.Data ().f_Is_Dialog)
{
l_Handled = IsDialogMessage (l_Cursor.Key (), &msg);
if (l_Handled) break;
}
}
}
if (!l_Handled)
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
if (g_Windows.Size () == 0)
{
// When all windows have closed, exit
PostQuitMessage (0);
}
}
return msg.wParam;
}
The f_
prefixes mean field - I picked up the m_
convention later, but this code hasn't been revisited in a very long time. f_Manager
in particular points to an instance of my c_Window_Base
class. The c_Cursor
class is a kind of iterator, used to step through all the windows stored in the g_Windows
variable (actually a static class member rather than a global).