Search code examples
windowsuser-interfacemfccdialog

Intercept CDialog creation


I have a rather large app that displays many different MFC CDialog-derived dialog windows. All of the dialogs are displayed from a central function that is similar to this:

void ShowDialog(CDialog& dlg)
{
  dlg.DoModal();
}

Now I need to essentially call a function in every dialog's OnInitDialog method. It doesn't technically need to be within OnInitDialog, but preferably before the dialog is visible.

The brute force method would be to go through the code and find every last dialog and add the function call to the OnInitDialog method (if it has one, and if it doesn't, add one). But it seems like there must be a more elegant way...

Note that dlg is not actually a CDialog, but something that derives from it.

Any thoughts, tricks or hacks? I'm not above patching the message map, but hope to find something cleaner/safer.


Solution

  • Turns out it is quite easy to do:

    HHOOK gPrevHook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookProc, NULL, myGUIThreadID);
    
    
    LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if(NULL != wParam)
        {
             CWPRETSTRUCT* pS = (CWPRETSTRUCT*)lParam;
             if(WM_INITDIALOG == pS->message)
                 CallFuncOnWindow(pS->hwnd);
        }
    
        return CallNextHookEx(gPrevHook, nCode, wParam, lParam);
    }
    

    Probably not the thing to do for a high performance app, but for something that is a simple GUI it works perfectly. No other code changes required.