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;
}