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