238 lines
6.9 KiB
C++
238 lines
6.9 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Fake.c
|
|
//
|
|
// this code gives OEMs a bogus Settings page to patch/modify
|
|
//
|
|
// OEM display pages patch the snot out of the Settings page
|
|
// the problem is that we have changed the setting page, and
|
|
// even if the OEM code could deal with our changes, the
|
|
// settings page is not even on the same property sheet
|
|
// as the extensions.
|
|
//
|
|
// some OEMs hook the setting page by hooking the TabContol and
|
|
// watching for a mouse click to activate the Settings page
|
|
// then they modify the page. NOTE they dont patch the page
|
|
// if it is activated via the keyboard only the mouse!
|
|
//
|
|
// some OEM pages find the Setting page by name.
|
|
// we have named the real settings page "Settings " and
|
|
// the fake page is "Settings"
|
|
//
|
|
// some OEM pages assume the last page is the Settings page.
|
|
// we make sure the fake settings is always last.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "priv.h"
|
|
#include "winuser.h"
|
|
#pragma hdrstop
|
|
#include "cplext.h"
|
|
|
|
#ifndef TCIS_HIDDEN
|
|
#define TCIS_HIDDEN 0x0004
|
|
#pragma message("using local version of TCIS_HIDDEN")
|
|
#endif
|
|
|
|
#undef MATROX_HACK
|
|
|
|
/*
|
|
* Global stuff
|
|
*/
|
|
static LONG_PTR TabWndProc; // SysTabControl WndProc
|
|
static LONG_PTR DlgWndProc; // Dialog WndProc
|
|
|
|
#ifdef MATROX_HACK
|
|
static PROPSHEETHEADER psh; // saved prop sheet header
|
|
#endif
|
|
|
|
/*
|
|
* Local Constant Declarations
|
|
*/
|
|
int CALLBACK DeskPropSheetCallback(HWND hDlg, UINT code, LPARAM lParam);
|
|
INT_PTR CALLBACK FakeSettingsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
IThemeUIPages *g_pThemeUI;
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// AddFakeSettingsPage
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void AddFakeSettingsPage(IThemeUIPages *pThemeUI, PROPSHEETHEADER * ppsh)
|
|
{
|
|
g_pThemeUI = pThemeUI;
|
|
PROPSHEETPAGE psp;
|
|
HPROPSHEETPAGE hpsp;
|
|
|
|
ZeroMemory(&psp, sizeof(psp));
|
|
|
|
psp.dwSize = sizeof(psp);
|
|
psp.dwFlags = PSP_DEFAULT;
|
|
psp.hInstance = HINST_THISDLL;
|
|
psp.pszTemplate = MAKEINTRESOURCE(DLG_FAKE_SETTINGS);
|
|
psp.pfnDlgProc = FakeSettingsDlgProc;
|
|
psp.lParam = 0L;
|
|
|
|
//
|
|
// some OEMs find the Property sheet by window title
|
|
// so make sure we have the title they expect.
|
|
//
|
|
#ifdef MATROX_HACK
|
|
if (ppsh->hwndParent && IsWindowVisible(ppsh->hwndParent))
|
|
{
|
|
psh = *ppsh;
|
|
ppsh->pszCaption = MAKEINTRESOURCE(IDS_DISPLAY_TITLE);
|
|
psp.dwFlags |= PSP_PREMATURE;
|
|
}
|
|
#endif
|
|
|
|
hpsp = CreatePropertySheetPage(&psp);
|
|
if (hpsp)
|
|
{
|
|
ppsh->phpage[ppsh->nPages++] = hpsp;
|
|
|
|
ppsh->pfnCallback = DeskPropSheetCallback;
|
|
ppsh->dwFlags |= PSH_USECALLBACK;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// FakeSettingsDlgProc
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR CALLBACK FakeSettingsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (hDlg && DlgWndProc)
|
|
{
|
|
if (GetWindowLongPtr(hDlg, GWLP_WNDPROC) != DlgWndProc)
|
|
{
|
|
SetWindowLongPtr(hDlg, GWLP_WNDPROC, DlgWndProc);
|
|
}
|
|
|
|
if (GetWindowLongPtr(hDlg, DWLP_DLGPROC) != (LONG_PTR)FakeSettingsDlgProc)
|
|
{
|
|
SetWindowLongPtr(hDlg, DWLP_DLGPROC, (LONG_PTR)FakeSettingsDlgProc);
|
|
}
|
|
}
|
|
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDC_CHANGEDRV)
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// HideFakeSettingsPage
|
|
//
|
|
// hide the bogus settings page from view so the user cant see it.
|
|
//
|
|
// this code uses a new TabCtrl item style TCIS_HIDDEN that is only
|
|
// in the Win98/NT5/IE4.01 COMMCTRL
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void HideFakeSettingsPage(HWND hDlg)
|
|
{
|
|
HWND hwnd = PropSheet_GetTabControl(hDlg);
|
|
if (hwnd)
|
|
{
|
|
TCITEM tci;
|
|
tci.mask = TCIF_STATE;
|
|
tci.dwStateMask = TCIS_HIDDEN;
|
|
tci.dwState = TCIS_HIDDEN;
|
|
TabCtrl_SetItem(hwnd, TabCtrl_GetItemCount(hwnd)-1, &tci);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// DeskPropSheetCallback
|
|
//
|
|
// what this callback does is look for someone subclassing the
|
|
// tab control, if we detect this we put the correct WndProc
|
|
// back.
|
|
//
|
|
// we also hide the fake settings page after all the entensions
|
|
// have initialized
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int CALLBACK DeskPropSheetCallback(HWND hDlg, UINT code, LPARAM lParam)
|
|
{
|
|
HWND hwnd;
|
|
|
|
WNDCLASS wc;
|
|
|
|
switch (code)
|
|
{
|
|
case PSCB_INITIALIZED:
|
|
TraceMsg(TF_GENERAL, "DeskPropSheetCallback: PSCB_INITIALIZED");
|
|
|
|
hwnd = PropSheet_GetTabControl(hDlg);
|
|
if (hwnd && TabWndProc)
|
|
{
|
|
if (GetWindowLongPtr(hwnd, GWLP_WNDPROC) != TabWndProc)
|
|
{
|
|
SetWindowLongPtr(hwnd, GWLP_WNDPROC, TabWndProc);
|
|
}
|
|
}
|
|
|
|
if (hDlg && DlgWndProc)
|
|
{
|
|
if (GetWindowLongPtr(hDlg, GWLP_WNDPROC) != DlgWndProc)
|
|
{
|
|
SetWindowLongPtr(hDlg, GWLP_WNDPROC, DlgWndProc);
|
|
}
|
|
}
|
|
|
|
#ifdef MATROX_HACK
|
|
//
|
|
// restore the caption
|
|
//
|
|
if (psh.pszCaption)
|
|
{
|
|
ShowWindow(hDlg, SW_SHOW);
|
|
Sleep(10);
|
|
PropSheet_SetTitle(hDlg, psh.dwFlags, psh.pszCaption);
|
|
PropSheet_SetTitle(GetParent(psh.hwndParent),
|
|
PSH_PROPTITLE, MAKEINTRESOURCE(IDS_DISPLAY_TITLE));
|
|
psh.pszCaption = 0;
|
|
}
|
|
#endif
|
|
//
|
|
// hide the settings page so the user cant see it.
|
|
//
|
|
HideFakeSettingsPage(hDlg);
|
|
break;
|
|
|
|
case PSCB_PRECREATE:
|
|
TraceMsg(TF_GENERAL, "DeskPropSheetCallback: PSCB_PRECREATE");
|
|
|
|
ZeroMemory(&wc, sizeof(wc));
|
|
SHFusionGetClassInfo(NULL, WC_DIALOG, &wc);
|
|
DlgWndProc = (LONG_PTR)wc.lpfnWndProc;
|
|
|
|
ZeroMemory(&wc, sizeof(wc));
|
|
SHFusionGetClassInfo(NULL, WC_TABCONTROL, &wc);
|
|
TabWndProc = (LONG_PTR)wc.lpfnWndProc;
|
|
break;
|
|
|
|
case PSCB_BUTTONPRESSED:
|
|
if ((PSBTN_OK == lParam) || (PSBTN_APPLYNOW == lParam))
|
|
{
|
|
DWORD dwFlags = ((PSBTN_OK == lParam) ? (TUIAP_WAITFORAPPLY | TUIAP_NONE) : TUIAP_NONE);
|
|
if (g_pThemeUI)
|
|
{
|
|
g_pThemeUI->ApplyPressed(dwFlags);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|