Extending a custom property page by overriding its Window Procedure

I am currently working on a personal project which requires to extend the operating system shell via a custom property page (IShellPropSheetExt interface), however, this customization has to behave differently to the default behaviour of the Shell, therefore I have to intercept the click event of any of the property page buttons (e.g.: Ok, Cancel or Apply). In order to do that, I must “override” the Wndproc of the original dialog and then run my custom code. This is shown in the code snippet below.

/// <summary>    Original WndProc. </summary>

WNDPROC pWndProc;

 

LRESULT CALLBACK CustomWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {

    FindChild* findChildWnd;

    auto retval = CallWindowProc(pWndProc, hwndDlg, msg, wParam, lParam);

 

    switch (msg) {

    case WM_COMMAND:

        auto selectedButton = LOWORD(wParam);

        if (selectedButton == IDOK || selectedButton == IDAPPLY || selectedButton == IDCANCEL) {

            auto enumChildProc = [](HWND hwnd, LPARAM lParam)-> BOOL {

                auto retval = TRUE;

                wchar_t buffer[MAX_PATH];

                auto lParamValues(reinterpret_cast<FindChild*>(lParam));

 

                if (GetClassName(hwnd, buffer, wcslen(buffer)) > 0) {

                    wstring className(buffer);

                    if (className.find(lParamValues->windowName) != wstring::npos) {

                        lParamValues->nMatchCount++;

 

                        if (lParamValues->FoundTargetIndex()) {

                            lParamValues->hFound = hwnd;

                            retval = FALSE;

                        }

                    }

                }

                return retval;

            };

 

            EnumChildWindows(hwndDlg, enumChildProc, reinterpret_cast<LPARAM>((findChildWnd = new FindChild)));

 

            switch (selectedButton) {

            case IDOK:

                SendMessage(findChildWnd->hFound, WM_APP, IDOK, NULL);

                break;

            case IDAPPLY:

                SendMessage(findChildWnd->hFound, WM_APP, IDAPPLY, NULL);

                break;

            case IDCANCEL:

                SendMessage(findChildWnd->hFound, WM_APP, IDCANCEL, NULL);

                break;

            }

 

            delete findChildWnd;

        }

        break;

    }

 

    return retval;

}

Leave a Reply

Your email address will not be published. Required fields are marked *