Windows2003-3790/inetcore/connectionwizard/icwconn/gendlg.cpp
2020-09-30 16:53:55 +02:00

699 lines
27 KiB
C++

//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1994 **
//*********************************************************************
#include "pre.h"
#include "icwaprtc.h"
#define BITMAP_WIDTH 164
#define BITMAP_HEIGHT 458
/*******************************************************************
NAME: GetDlgIDFromIndex
SYNOPSIS: For a given zero-based page index, returns the
corresponding dialog ID for the page
4/24/97 jmazner When dealing with apprentice pages, we may call
this function with dialog IDs (IDD_PAGE_*), rather
than an index (ORD_PAGE*). Added code to check
whether the number passed in is an index or dlgID.
********************************************************************/
UINT GetDlgIDFromIndex(UINT uPageIndex)
{
if( uPageIndex <= MAX_PAGE_INDEX )
{
ASSERT(uPageIndex < NUM_WIZARD_PAGES);
return PageInfo[uPageIndex].uDlgID;
}
else
{
return(uPageIndex);
}
}
//
// GENDLG.C -
// Generic DLG proc for common wizard functions
//
// HISTORY:
//
// 05/13/98 donaldm Created.
//
// ############################################################################
HRESULT MakeWizard97Title (HWND hwnd)
{
HRESULT hr = ERROR_SUCCESS;
HFONT hfont = NULL;
HFONT hnewfont = NULL;
LOGFONT *plogfont = NULL;
HDC hDC;
if (!hwnd) goto MakeWizard97TitleExit;
hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
if (!hfont)
{
hr = ERROR_GEN_FAILURE;
goto MakeWizard97TitleExit;
}
plogfont = (LOGFONT*)malloc(sizeof(LOGFONT));
if (!plogfont)
{
hr = ERROR_NOT_ENOUGH_MEMORY;
goto MakeWizard97TitleExit;
}
if (!GetObject(hfont,sizeof(LOGFONT),(LPVOID)plogfont))
{
hr = ERROR_GEN_FAILURE;
goto MakeWizard97TitleExit;
}
// We want 12 PT Veranda for Wizard 97.
hDC = GetDC(NULL);
if(hDC)
{
plogfont->lfHeight = -MulDiv(WIZ97_TITLE_FONT_PTS, GetDeviceCaps(hDC, LOGPIXELSY), 72);
ReleaseDC(NULL, hDC);
}
plogfont->lfWeight = (int) FW_BOLD;
if (!LoadString(ghInstanceResDll, IDS_WIZ97_TITLE_FONT_FACE, plogfont->lfFaceName, LF_FACESIZE))
lstrcpy(plogfont->lfFaceName, TEXT("Verdana"));
if (!(hnewfont = CreateFontIndirect(plogfont)))
{
hr = ERROR_GEN_FAILURE;
goto MakeWizard97TitleExit;
}
SendMessage(hwnd,WM_SETFONT,(WPARAM)hnewfont,MAKELPARAM(TRUE,0));
free(plogfont);
MakeWizard97TitleExit:
//if (hfont) DeleteObject(hfont);
// BUG:? Do I need to delete hnewfont at some time?
// The answer is Yes. ChrisK 7/1/96
return hr;
}
// ############################################################################
HRESULT ReleaseBold(HWND hwnd)
{
HFONT hfont = NULL;
hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
if (hfont) DeleteObject(hfont);
return ERROR_SUCCESS;
}
/*******************************************************************
Function: PaintWithPaletteBitmap
Arguments: lprc is the target rectangle.
cy is the putative dimensions of hbmpPaint.
If the target rectangle is taller than cy, then
fill the rest with the pixel in the upper left
corner of the hbmpPaint.
Returns: void
History: 10-29-98 Vyung Stole from prsht.c
********************************************************************/
void PaintWithPaletteBitmap(HDC hdc, LPRECT lprc, int cy, HBITMAP hbmpPaint)
{
HDC hdcBmp;
hdcBmp = CreateCompatibleDC(hdc);
SelectObject(hdcBmp, hbmpPaint);
BitBlt(hdc, lprc->left, lprc->top, RECTWIDTH(*lprc), cy, hdcBmp, 0, 0, SRCCOPY);
// StretchBlt does mirroring if you pass a negative height,
// so do the stretch only if there actually is unpainted space
if (RECTHEIGHT(*lprc) - cy > 0)
StretchBlt(hdc, lprc->left, cy,
RECTWIDTH(*lprc), RECTHEIGHT(*lprc) - cy,
hdcBmp, 0, 0, 1, 1, SRCCOPY);
DeleteDC(hdcBmp);
}
/*******************************************************************
//
// Function: Prsht_EraseWizBkgnd
//
// Arguments: Draw the background for wizard pages.
// hDlg is dialog handle.
// hdc is device context
//
// Returns: void
//
// History: 10-29-98 Vyung - Stole from prsht.c
//
********************************************************************/
LRESULT Prsht_EraseWizBkgnd(HWND hDlg, HDC hdc)
{
HBRUSH hbrWindow = GetSysColorBrush(COLOR_WINDOW);
RECT rc;
GetClientRect(hDlg, &rc);
FillRect(hdc, &rc, hbrWindow);
rc.right = BITMAP_WIDTH;
rc.left = 0;
PaintWithPaletteBitmap(hdc, &rc, BITMAP_HEIGHT, gpWizardState->cmnStateData.hbmWatermark);
return TRUE;
}
//-----------------------------------------------------------------------------
// Function MiscInitProc
//
// Synopsis Our generic dialog proc calls this in case any of the wizard
// dialogs have to do any sneaky stuff.
//
// Arguments: hDlg - dialog window
// fFirstInit - TRUE if this is the first time the dialog
// is initialized, FALSE if this InitProc has been called
// before (e.g. went past this page and backed up)
//
// Returns: TRUE
//
// History: 10/28/96 ValdonB Created
// 11/25/96 Jmazner copied from icwconn1\psheet.cpp
// Normandy #10586
//
//-----------------------------------------------------------------------------
BOOL CALLBACK MiscInitProc
(
HWND hDlg,
BOOL fFirstInit,
UINT uDlgID
)
{
// switch( uDlgID )
// {
// }
return TRUE;
}
/*******************************************************************
NAME: GenDlgProc
SYNOPSIS: Generic dialog proc for all wizard pages
NOTES: This dialog proc provides the following default behavior:
init: back and next buttons enabled
next btn: switches to page following current page
back btn: switches to previous page
cancel btn: prompts user to confirm, and cancels the wizard
dlg ctrl: does nothing (in response to WM_COMMANDs)
Wizard pages can specify their own handler functions
(in the PageInfo table) to override default behavior for
any of the above actions.
********************************************************************/
INT_PTR CALLBACK GenDlgProc
(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
static HCURSOR hcurOld = NULL;
PAGEINFO *pPageInfo = (PAGEINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
ASSERT(pPageInfo);
switch (uMsg)
{
case WM_ERASEBKGND:
{
if(gpWizardState->cmnStateData.bOEMCustom)
{
// Set ICW completed bit and remove the getconn icon
if (gpWizardState->cmnStateData.lpfnFillWindowWithAppBackground)
(*gpWizardState->cmnStateData.lpfnFillWindowWithAppBackground)(hDlg, (HDC) wParam);
return TRUE;
}
else
{
// Only paint the external page
if ((!pPageInfo->nIdTitle) && (IDD_PAGE_ISPSELECT != pPageInfo->uDlgID))
{
Prsht_EraseWizBkgnd(hDlg, (HDC) wParam);
return TRUE;
}
}
break;
}
GENDLG_CTLCOLOR:
case WM_CTLCOLOR:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORBTN:
case WM_CTLCOLORSCROLLBAR:
{
// Only paint the external page and except the ISP sel page
if ((!pPageInfo->nIdTitle) && (IDD_PAGE_ISPSELECT != pPageInfo->uDlgID))
{
HBRUSH hbrWindow = GetSysColorBrush(COLOR_WINDOW);
DefWindowProc(hDlg, uMsg, wParam, lParam);
SetBkMode((HDC)wParam, TRANSPARENT);
return (LRESULT)hbrWindow;
}
break;
}
// We need to make sure static controls draw transparently
// on the background bitmap. This is done by painting in
// the appropriate portion of the background, and then
// returning a NULL brush so the control just draws the text
case WM_CTLCOLORSTATIC:
if(gpWizardState->cmnStateData.bOEMCustom)
{
SetTextColor((HDC)wParam, gpWizardState->cmnStateData.clrText);
if (!(GetWindowLong((HWND)lParam, GWL_STYLE) & ES_READONLY))
{
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR) GetStockObject(NULL_BRUSH);
}
break;
}
else
{
// Not in modeless opperation so just do the default cltcolor
// handling
goto GENDLG_CTLCOLOR;
}
case WM_INITDIALOG:
{
// get propsheet page struct passed in
LPPROPSHEETPAGE lpsp = (LPPROPSHEETPAGE) lParam;
ASSERT(lpsp);
// fetch our private page info from propsheet struct
pPageInfo = (PAGEINFO *)lpsp->lParam;
ASSERT(pPageInfo);
// store pointer to private page info in window data for later
SetWindowLongPtr(hDlg,DWLP_USER,(LPARAM) pPageInfo);
// initialize 'back' and 'next' wizard buttons, if
// page wants something different it can fix in init proc below
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT | PSWIZB_BACK);
// Make the title text bold
MakeWizard97Title(GetDlgItem(hDlg,IDC_LBLTITLE));
// call init proc for this page if one is specified
if (pPageInfo->InitProc)
{
if (!( pPageInfo->InitProc(hDlg,TRUE, NULL)))
{
// If a fatal error occured, quit the wizard.
// Note: gfQuitWizard is also used to terminate the wizard
// for non-error reasons, but in that case TRUE is returned
// from the OK proc and the case is handled below.
if (gfQuitWizard)
{
// Don't reboot if error occured.
gpWizardState->fNeedReboot = FALSE;
// send a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
//
// ...Unless we're serving as an Apprentice. In which case, let
// the Wizard decide how to deal with this.
PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL);
}
}
}
// 11/25/96 jmazner Normandy #10586 (copied from icwconn1)
// Before we return, lets send another message to ourself so
// we have a second chance of initializing stuff that the
// property sheet wizard doesn't normally let us do.
PostMessage(hDlg, WM_MYINITDIALOG, 1, lParam);
return TRUE;
}
break; // WM_INITDIALOG
// 11/25/96 jmazner Normandy #10586 (copied from icwconn1)
case WM_MYINITDIALOG:
{
// reset the state so that we can download data.
gfUserCancelled = FALSE;
if (pPageInfo->PostInitProc)
{
if (!( pPageInfo->PostInitProc(hDlg,(BOOL)wParam, NULL)))
{
// If a fatal error occured, quit the wizard.
// Note: gfQuitWizard is also used to terminate the wizard
// for non-error reasons, but in that case TRUE is returned
// from the OK proc and the case is handled below.
if (gfQuitWizard)
{
// Don't reboot if error occured.
gpWizardState->fNeedReboot = FALSE;
// send a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
//
// ...Unless we're serving as an Apprentice. In which case, let
// the Wizard decide how to deal with this.
PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL);
}
}
}
// wParam tells whether this is the first initialization or not
MiscInitProc(hDlg, (BOOL)wParam, pPageInfo->uDlgID);
return TRUE;
}
case WM_DESTROY:
ReleaseBold(GetDlgItem(hDlg,IDC_LBLTITLE));
break;
#ifdef HAS_HELP
case WM_HELP:
{
DWORD dwData = 1000;
WinHelp(hDlg,"connect.hlp>proc4",HELP_CONTEXT, dwData);
break;
}
#endif
case WM_NOTIFY:
{
BOOL fRet,fKeepHistory=TRUE;
NMHDR * lpnm = (NMHDR *) lParam;
#define NEXTPAGEUNITIALIZED -1
int iNextPage = NEXTPAGEUNITIALIZED;
switch (lpnm->code)
{
case PSN_TRANSLATEACCELERATOR:
{
// If the WEBOC is active, then we should let if have a crack as
// the accelerator
if ((pPageInfo->bIsHostingWebOC) || g_bCustomPaymentActive)
{
//SUCEEDED macro will not work here cuz ret maybe S_FALSE
if (S_OK == gpWizardState->pICWWebView->HandleKey((LPMSG)((PSHNOTIFY*)lParam)->lParam))
SetWindowLongPtr(hDlg,DWLP_MSGRESULT, PSNRET_MESSAGEHANDLED);
else
SetWindowLongPtr(hDlg,DWLP_MSGRESULT, PSNRET_NOERROR);
}
else
{
SetWindowLongPtr(hDlg,DWLP_MSGRESULT, PSNRET_NOERROR);
}
return TRUE;
}
case PSN_SETACTIVE:
// If a fatal error occured in first call to init proc
// from WM_INITDIALOG, don't call init proc again.
if (FALSE == gfQuitWizard)
{
// For modeless operation, we are suppressing the painting
// of the wizard page background to get the effect of
// transparency, so we need to for an update of the
// app's client area after hiding the current page.
if(gpWizardState->cmnStateData.bOEMCustom)
{
// Set the position of the page that is being activated
SetWindowPos(hDlg, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
// Set the page title
if (pPageInfo->nIdTitle)
{
SendMessage(gpWizardState->cmnStateData.hWndApp, WUM_SETTITLE, (WPARAM)ghInstanceResDll, MAKELONG(pPageInfo->nIdTitle, 0));
}
}
// initialize 'back' and 'next' wizard buttons, if
// page wants something different it can fix in init proc below
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT | PSWIZB_BACK);
// call init proc for this page if one is specified
if (pPageInfo->InitProc)
{
pPageInfo->InitProc(hDlg,FALSE, (UINT*)&iNextPage);
if (NEXTPAGEUNITIALIZED != iNextPage)
{
// Skipping
SetPropSheetResult(hDlg,GetDlgIDFromIndex(iNextPage));
return (iNextPage);
}
}
}
// If we set the wait cursor, set the cursor back
if (hcurOld)
{
SetCursor(hcurOld);
hcurOld = NULL;
}
PostMessage(hDlg, WM_MYINITDIALOG, 0, lParam);
return TRUE;
break;
case PSN_WIZNEXT:
case PSN_WIZBACK:
case PSN_WIZFINISH:
// Change cursor to an hour glass
hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
// call OK proc for this page if one is specified
if (pPageInfo->OKProc)
{
if (!pPageInfo->OKProc(hDlg,(lpnm->code != PSN_WIZBACK), (UINT*)&iNextPage,&fKeepHistory))
{
// If a fatal error occured, quit the wizard.
// Note: gfQuitWizard is also used to terminate the wizard
// for non-error reasons, but in that case TRUE is returned
// from the OK proc and the case is handled below.
if (gfQuitWizard)
{
// Don't reboot if error occured.
gpWizardState->fNeedReboot = FALSE;
// send a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
//
// ...Unless we're serving as an Apprentice. In which case, let
// the Wizard decide how to deal with this.
PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL);
}
// stay on this page
SetPropSheetResult(hDlg,-1);
return TRUE;
}
}
if (lpnm->code != PSN_WIZBACK)
{
// 'next' pressed
ASSERT(gpWizardState->uPagesCompleted < NUM_WIZARD_PAGES);
// save the current page index in the page history,
// unless this page told us not to when we called
// its OK proc above
if (fKeepHistory)
{
gpWizardState->uPageHistory[gpWizardState->uPagesCompleted] = gpWizardState->uCurrentPage;
TraceMsg(TF_GENDLG, "GENDLG: added page %d (IDD %d) to history list",
gpWizardState->uCurrentPage, GetDlgIDFromIndex(gpWizardState->uCurrentPage));
gpWizardState->uPagesCompleted++;
}
else
{
TraceMsg(TF_GENDLG, "GENDLG: not adding %d (IDD: %d) to the history list",
gpWizardState->uCurrentPage, GetDlgIDFromIndex(gpWizardState->uCurrentPage));
}
// if no next page specified or no OK proc,
// advance page by one
if (0 > iNextPage)
iNextPage = gpWizardState->uCurrentPage + 1;
}
else
{
// 'back' pressed
// If we have completed no pages, then we are on the first page
// of the DLL process, so back really means go to the
// external prev. page.
if (0 == gpWizardState->uPagesCompleted)
{
iNextPage = g_uExternUIPrev;
}
// See if we need to get the page from the history list
if( NEXTPAGEUNITIALIZED == iNextPage )
{
ASSERT(gpWizardState->uPagesCompleted > 0);
// get the last page from the history list
gpWizardState->uPagesCompleted --;
iNextPage = gpWizardState->uPageHistory[gpWizardState->uPagesCompleted];
TraceMsg(TF_GENDLG, "GENDLG: extracting page %d (IDD %d) from history list",iNextPage, GetDlgIDFromIndex(iNextPage));
}
}
// if we need to exit the wizard now (e.g. launching
// signup app and want to terminate the wizard), send
// a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
if (gfQuitWizard)
{
//
// if we are going from manual to conn1 then
// then do not show the REBOOT dialog but
// still preserve the gpWizardState -MKarki Bug #404
//
if (lpnm->code == PSN_WIZBACK)
{
gfBackedUp = TRUE;
gfReboot = gpWizardState->fNeedReboot;
}
// send a 'cancel' message to ourselves (to keep the prop.
// page mgr happy)
//
// ...Unless we're serving as an Apprentice. In which case, let
// the Wizard decide how to deal with this.
PropSheet_PressButton(GetParent(hDlg),PSBTN_CANCEL);
SetPropSheetResult(hDlg,-1);
return TRUE;
}
// set next page, only if 'next' or 'back' button
// was pressed
if (lpnm->code != PSN_WIZFINISH)
{
// set the next current page index
gpWizardState->uCurrentPage = iNextPage;
TraceMsg(TF_GENDLG, "GENDLG: going to page %d (IDD %d)", iNextPage, GetDlgIDFromIndex(iNextPage));
// tell the prop sheet mgr what the next page to
// display is
SetPropSheetResult(hDlg,GetDlgIDFromIndex(iNextPage));
return TRUE;
}
break;
case PSN_QUERYCANCEL:
// if global flag to exit is set, then this cancel
// is us pretending to push 'cancel' so prop page mgr
// will kill the wizard. Let this through...
if (gfQuitWizard)
{
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,FALSE);
return TRUE;
}
//Dialing is a super special case cuz we wanna skip all the UI and
//go striaght to a dialing error page
if (gpWizardState->uCurrentPage == ORD_PAGE_ISPDIAL)
{
gfISPDialCancel = TRUE;
gfUserCancelled = TRUE; // Just in case
PropSheet_PressButton(GetParent(hDlg),PSBTN_NEXT);
// if this page has a special cancel proc, call it
if (pPageInfo->CancelProc)
{
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,pPageInfo->CancelProc(hDlg));
SetEvent(gpWizardState->hEventWebGateDone);
}
}
else
{
// default behavior: pop up a message box confirming
// the cancel...
// ... unless we're serving as an Apprentice, in which case
// we should let the Wizard handle things
fRet = (MsgBox(hDlg,IDS_QUERYCANCEL,
MB_ICONQUESTION,MB_YESNO |
MB_DEFBUTTON2) == IDYES);
gfUserCancelled = fRet;
if (gfUserCancelled)
{
// if this page has a special cancel proc, call it
if (pPageInfo->CancelProc)
fRet = pPageInfo->CancelProc(hDlg);
SetEvent(gpWizardState->hEventWebGateDone);
}
// return the value thru window data
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,!fRet);
}
return TRUE;
break;
default:
// See if the page has a notify proc
if (pPageInfo->NotifyProc)
{
pPageInfo->NotifyProc(hDlg,wParam,lParam);
}
break;
}
break;
}
case WM_COMMAND:
{
// if this page has a command handler proc, call it
if (pPageInfo->CmdProc)
{
pPageInfo->CmdProc(hDlg, wParam, lParam);
}
}
}
return FALSE;
}