windows-nt/Source/XPSP1/NT/shell/osshell/accessib/accwiz/pgbase.cpp
2020-09-26 16:20:57 +08:00

344 lines
7.7 KiB
C++

//Copyright (c) 1997-2000 Microsoft Corporation
#include "pch.hxx"
#pragma hdrstop
#include "pgbase.h"
#include "resource.h"
#include "DlgFonts.h"
/***************************************************************************
* Use the following define if for some reason we have to go back to using
* a message loop to let shell have time to update the UI
*
#define NEED_MSG_PUMP
**************************************************************************/
// Initialization of static members
CWizardPageOrder WizardPage::sm_WizPageOrder;
WizardPage::WizardPage(
LPPROPSHEETPAGE ppsp,
int nIdTitle,
int nIdSubTitle
) : m_hwnd(NULL), m_dwPageId(0)
{
_ASSERTE(NULL != ppsp);
// If we have a subtitle, we must have a title
_ASSERTE(nIdSubTitle?nIdTitle:TRUE);
//
// Many of the members are 0 or NULL.
//
ZeroMemory(ppsp, sizeof(PROPSHEETPAGE));
ppsp->dwSize = sizeof(PROPSHEETPAGE);
ppsp->dwFlags = PSP_DEFAULT;
ppsp->hInstance = g_hInstDll;
// If we are using a title/subtitle, include the flags
// Otherwise, hide the header
if(nIdTitle)
{
ppsp->dwFlags |= PSP_USEHEADERTITLE | (nIdSubTitle?PSP_USEHEADERSUBTITLE:0);
ppsp->pszHeaderTitle = MAKEINTRESOURCE(nIdTitle);
ppsp->pszHeaderSubTitle = MAKEINTRESOURCE(nIdSubTitle);
// ppsp->pszbmHeader = MAKEINTRESOURCE(IDB_ACCMARK);
}
else
ppsp->dwFlags |= PSP_HIDEHEADER;
//
// Callback is a base class function. The derived page
// classes need to implement OnPropSheetPageCreate() and
// OnPropSheetPageRelease() if they want to handle this callback.
// By WizardPage::OnPropSheetPageCreate() returns 1.
//
ppsp->pfnCallback = WizardPage::PropSheetPageCallback;
ppsp->dwFlags |= (PSP_USECALLBACK /*| PSP_USEREFPARENT*/); // JMC: TODO: Do we want PSP_USEREFPARENT
//
// Store "this" in the page struct so we can call member functions
// from the page's message proc.
//
_ASSERTE(NULL != this);
ppsp->lParam = (LPARAM)this;
//
// All dialog messages first go through the base class' message proc.
// Virtual functions are called for some messages. If not processed
// using a message-specific virtual function, the message is passed
// to the derived class instance through the virtual funcion HandleMsg.
//
ppsp->pfnDlgProc = WizardPage::DlgProc;
}
WizardPage::~WizardPage(
VOID
)
{
}
UINT
WizardPage::PropSheetPageCallback(
HWND hwnd,
UINT uMsg,
LPPROPSHEETPAGE ppsp
)
{
UINT uResult = 0;
WizardPage *pThis = (WizardPage *)ppsp->lParam;
_ASSERTE(NULL != pThis);
switch(uMsg)
{
case PSPCB_CREATE:
uResult = pThis->OnPropSheetPageCreate(hwnd, ppsp);
break;
case PSPCB_RELEASE:
uResult = pThis->OnPropSheetPageRelease(hwnd, ppsp);
//
// IMPORTANT:
// This is where we delete each property sheet page.
// HERE and ONLY HERE.
//
// delete pThis; // We won't do this since we'll keep our own list
// The reason it won't work is because if you never get to a page, you
// will never get this message
break;
}
return uResult;
}
//
// This is a static method.
//
INT_PTR
WizardPage::DlgProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
INT_PTR bResult = FALSE;
PROPSHEETPAGE *ppsp = NULL;
if (WM_INITDIALOG == uMsg)
ppsp = (PROPSHEETPAGE *)lParam;
else
ppsp = (PROPSHEETPAGE *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (NULL != ppsp)
{
WizardPage *pThis = (WizardPage *)ppsp->lParam;
_ASSERTE(NULL != pThis);
switch(uMsg)
{
case WM_INITDIALOG:
{
// The following will set fonts for 'known' controls,
DialogFonts_InitWizardPage(hwnd);
//
// Store address of PROPSHEETPAGE struct for this page
// in window's user data.
//
SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
pThis->m_hwnd = hwnd;
bResult = pThis->OnInitDialog(hwnd, wParam, lParam);
}
break;
case WM_NOTIFY:
bResult = pThis->OnNotify(hwnd, wParam, lParam);
break;
case PSM_QUERYSIBLINGS:
bResult = pThis->OnPSM_QuerySiblings(hwnd, wParam, lParam);
break;
case WM_COMMAND:
bResult = pThis->OnCommand(hwnd, wParam, lParam);
break;
case WM_TIMER:
bResult = pThis->OnTimer(hwnd, wParam, lParam);
break;
case WM_DRAWITEM:
bResult = pThis->OnDrawItem(hwnd, wParam, lParam);
break;
default:
//
// Let derived class instance handle any other messages
// as needed.
//
bResult = pThis->HandleMsg(hwnd, uMsg, wParam, lParam);
break;
}
}
return bResult;
}
LRESULT
WizardPage::OnNotify(
HWND hwnd,
WPARAM wParam,
LPARAM lParam
)
{
INT idCtl = (INT)wParam;
LPNMHDR pnmh = (LPNMHDR)lParam;
LRESULT lResult = 0;
switch(pnmh->code)
{
case PSN_APPLY:
lResult = OnPSN_Apply(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_HELP:
lResult = OnPSN_Help(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_KILLACTIVE:
lResult = OnPSN_KillActive(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_QUERYCANCEL:
lResult = OnPSN_QueryCancel(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_RESET:
lResult = OnPSN_Reset(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_SETACTIVE:
lResult = OnPSN_SetActive(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_WIZBACK:
lResult = OnPSN_WizBack(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_WIZNEXT:
lResult = OnPSN_WizNext(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case PSN_WIZFINISH:
lResult = OnPSN_WizFinish(hwnd, idCtl, (LPPSHNOTIFY)pnmh);
break;
case NM_CLICK:
case NM_RETURN:
OnMsgNotify(hwnd, idCtl, (LPNMHDR) pnmh);
break;
default:
break;
}
return lResult;
}
LRESULT
WizardPage::OnPSN_SetActive(
HWND hwnd,
INT idCtl,
LPPSHNOTIFY pnmh
)
{
// JMC: TODO: Maybe put this in the OnNotify Code so the overrided class does
// not have to call this
//
// By default, each wizard page has a BACK and NEXT button.
//
DWORD dwFlags = 0;
if(sm_WizPageOrder.GetPrevPage(m_dwPageId))
dwFlags |= PSWIZB_BACK;
if(sm_WizPageOrder.GetNextPage(m_dwPageId))
dwFlags |= PSWIZB_NEXT;
else
dwFlags |= PSWIZB_FINISH;
PropSheet_SetWizButtons(GetParent(hwnd), dwFlags);
// Tell the wizard that it's ok to go to this page
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0);
return TRUE;
}
LRESULT
WizardPage::OnPSM_QuerySiblings(
HWND hwnd,
WPARAM wParam,
LPARAM lParam
)
{
return 0;
}
LRESULT
WizardPage::OnPSN_QueryCancel(
HWND hwnd,
INT idCtl,
LPPSHNOTIFY pnmh
)
{
//If nothing has changed just exit...
if ( memcmp( &g_Options.m_schemePreview, &g_Options.m_schemeOriginal, sizeof(WIZSCHEME)) == 0)
{
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0);
return TRUE;
}
// if (
switch(StringTableMessageBox(hwnd, IDS_WIZSAVECHANGESMESSAGETEXT, IDS_WIZSAVECHANGESMESSAGETITLE, MB_YESNO))
{
case IDYES:
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0);
break;
case IDNO:
{
// Restore all settings to the original settings
g_Options.ApplyOriginal();
#if NEED_MSG_PUMP
if (SetTimer(hwnd, 1, 4000, NULL))
{
// Wait for messages to be processed
BOOL fKeepChecking = TRUE;
while (fKeepChecking)
{
MSG msg;
while (PeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
{
if (msg.message == WM_TIMER)
{
KillTimer(hwnd, 1);
fKeepChecking = FALSE;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
#endif
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0);
}
break;
case IDCANCEL:
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 1);
break;
}
return TRUE;
}