Back to index

lightning-sunbird  0.9+nobinonly
dialogs.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Sean Su <ssu@netscape.com>
00025  *   Curt Patrick <curt@netscape.com>
00026  *   Ben Goodger <ben@mozilla.org>
00027  *   Masayuki Nakano <masayuki@d-toybox.com>
00028  *
00029  * Alternatively, the contents of this file may be used under the terms of
00030  * either the GNU General Public License Version 2 or later (the "GPL"), or
00031  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00032  * in which case the provisions of the GPL or the LGPL are applicable instead
00033  * of those above. If you wish to allow use of your version of this file only
00034  * under the terms of either the GPL or the LGPL, and not to allow others to
00035  * use your version of this file under the terms of the MPL, indicate your
00036  * decision by deleting the provisions above and replace them with the notice
00037  * and other provisions required by the GPL or the LGPL. If you do not delete
00038  * the provisions above, a recipient may use your version of this file under
00039  * the terms of any one of the MPL, the GPL or the LGPL.
00040  *
00041  * ***** END LICENSE BLOCK ***** */
00042 
00043 // needed to build with mingw
00044 #ifndef _WIN32_IE
00045 #define _WIN32_IE 0x0500
00046 #endif
00047 
00048 #include "extern.h"
00049 #include "extra.h"
00050 #include "dialogs.h"
00051 #include "ifuncns.h"
00052 #include "xpistub.h"
00053 #include "xpi.h"
00054 #include "logging.h"
00055 #include <shlobj.h>
00056 #include <shellapi.h>
00057 #include <objidl.h>
00058 #include <logkeys.h>
00059 #include <prsht.h>
00060 
00061 // commdlg.h is needed to build with WIN32_LEAN_AND_MEAN
00062 #include <commdlg.h>
00063 
00064 // re-define PSH_WIZARD97 as per latest Platform SDK (below)
00065 #ifdef PSH_WIZARD97
00066 #undef PSH_WIZARD97
00067 #endif
00068 
00069 #if (_WIN32_IE >= 0x0400)
00070 //----- New flags for wizard97 -----------
00071 #if (_WIN32_IE < 0x0500)
00072 #define PSH_WIZARD97            0x00002000
00073 #else
00074 #define PSH_WIZARD97            0x01000000
00075 #endif
00076 #endif
00077 
00078 #ifndef CSIDL_PROGRAM_FILES
00079 #define CSIDL_PROGRAM_FILES     0x0026
00080 #endif // CSIDL_PROGRAM_FILES
00081 
00082 // Turn off default to safe upgrade for 0.8... until we can guarantee that we won't be deleting other files. 
00083 #define DEFAULT_SAFE_UPGRADE FALSE
00084 
00085 static WNDPROC OldListBoxWndProc;
00086 static WNDPROC OldDialogWndProc;
00087 static DWORD   gdwACFlag;
00088 static BOOL    gDidShowUpgradePanel;
00089 
00090 // function prototype
00091 LRESULT CALLBACK NewDialogWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
00092 
00094 // INSTALL WIZARD SEQUENCER
00095 //
00096 
00097 void InitSequence(HINSTANCE hInstance)
00098 {
00099   // Wizard data structures
00100   PROPSHEETPAGE psp;
00101   HPROPSHEETPAGE pages[11] = {0};
00102   PROPSHEETHEADER psh;
00103   int count = 0;
00104 
00106   // Create the Wizard Sequence
00107   //
00108   psp.dwSize            = sizeof(psp);
00109   psp.hInstance         = hSetupRscInst;
00110   psp.lParam            = 0;
00111 
00112   // Welcome Page
00113   if (diWelcome.bShowDialog) {
00114     psp.dwFlags           = PSP_DEFAULT|PSP_HIDEHEADER;
00115     psp.pfnDlgProc        = DlgProcWelcome;
00116     psp.pszTemplate       = MAKEINTRESOURCE(DLG_WELCOME);
00117     
00118     pages[count++]        = CreatePropertySheetPage(&psp);
00119   }
00120 
00121   // License Page
00122   if (diLicense.bShowDialog) {
00123     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00124     psp.pszHeaderTitle    = diLicense.szTitle;
00125     psp.pszHeaderSubTitle = diLicense.szSubTitle;
00126     psp.pfnDlgProc        = DlgProcLicense;
00127     psp.pszTemplate       = MAKEINTRESOURCE(DLG_LICENSE);
00128 
00129     pages[count++]        = CreatePropertySheetPage(&psp);
00130   }
00131 
00132   // License Page
00133   if (diSetupType.bShowDialog) {
00134     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00135     psp.pszHeaderTitle    = diSetupType.szTitle;
00136     psp.pszHeaderSubTitle = diSetupType.szSubTitle;
00137     psp.pfnDlgProc        = DlgProcSetupType;
00138     psp.pszTemplate       = MAKEINTRESOURCE(DLG_SETUP_TYPE);
00139 
00140     pages[count++]        = CreatePropertySheetPage(&psp);
00141   }
00142 
00143   if (diSelectInstallPath.bShowDialog) {
00144     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00145     psp.pszHeaderTitle    = diSelectInstallPath.szTitle;
00146     psp.pszHeaderSubTitle = diSelectInstallPath.szSubTitle;
00147     psp.pfnDlgProc        = DlgProcSelectInstallPath;
00148     psp.pszTemplate       = MAKEINTRESOURCE(DLG_SELECT_INSTALL_PATH);
00149 
00150     pages[count++]        = CreatePropertySheetPage(&psp);
00151   }
00152 
00153   if (diUpgrade.bShowDialog) {
00154     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00155     psp.pszHeaderTitle    = diUpgrade.szTitle;
00156     psp.pszHeaderSubTitle = diUpgrade.szSubTitle;
00157     psp.pfnDlgProc        = DlgProcUpgrade;
00158     psp.pszTemplate       = MAKEINTRESOURCE(DLG_UPGRADE);
00159 
00160     pages[count++]        = CreatePropertySheetPage(&psp);
00161   }
00162   else {
00163     // If we're not showing the Upgrade dialog, we need to set some state to
00164     // tell the installer to default to a Safe Install. 
00165 
00166     sgProduct.doCleanupOnUpgrade = DEFAULT_SAFE_UPGRADE;
00167   }
00168 
00169   if (diSelectComponents.bShowDialog) {
00170     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00171     psp.pszHeaderTitle    = diSelectComponents.szTitle;
00172     psp.pszHeaderSubTitle = diSelectComponents.szSubTitle;
00173     psp.pfnDlgProc        = DlgProcSelectComponents;
00174     psp.pszTemplate       = MAKEINTRESOURCE(DLG_SELECT_COMPONENTS);
00175 
00176     pages[count++]        = CreatePropertySheetPage(&psp);
00177   }
00178 
00179   // Windows Integration Page
00180   if (diWindowsIntegration.bShowDialog) {
00181     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00182     psp.pszHeaderTitle    = diWindowsIntegration.szTitle;
00183     psp.pszHeaderSubTitle = diWindowsIntegration.szSubTitle;
00184     psp.pfnDlgProc        = DlgProcWindowsIntegration;
00185     psp.pszTemplate       = MAKEINTRESOURCE(DLG_WINDOWS_INTEGRATION);
00186     
00187     pages[count++]        = CreatePropertySheetPage(&psp);
00188   }
00189 
00190   if (diStartInstall.bShowDialog) {
00191     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00192     psp.pszHeaderTitle    = diStartInstall.szTitle;
00193     psp.pszHeaderSubTitle = diStartInstall.szSubTitle;
00194     psp.pfnDlgProc        = DlgProcSummary;
00195     psp.pszTemplate       = MAKEINTRESOURCE(DLG_START_INSTALL);
00196 
00197     pages[count++]        = CreatePropertySheetPage(&psp);
00198   }
00199 
00200   if (diDownloading.bShowDialog) {
00201     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00202     psp.pszHeaderTitle    = diDownloading.szTitle;
00203     psp.pszHeaderSubTitle = diDownloading.szSubTitle;
00204     psp.pfnDlgProc        = DlgProcDownloading;
00205     psp.pszTemplate       = MAKEINTRESOURCE(DLG_DOWNLOADING);
00206 
00207     pages[count++]        = CreatePropertySheetPage(&psp);
00208   }
00209 
00210   if (diInstalling.bShowDialog) {
00211     psp.dwFlags           = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
00212     psp.pszHeaderTitle    = diInstalling.szTitle;
00213     psp.pszHeaderSubTitle = diInstalling.szSubTitle;
00214     psp.pfnDlgProc        = DlgProcInstalling;
00215     psp.pszTemplate       = MAKEINTRESOURCE(DLG_EXTRACTING);
00216 
00217     pages[count++]        = CreatePropertySheetPage(&psp);
00218   }
00219 
00220   // Successful Install Page
00221   if (diInstallSuccessful.bShowDialog) {
00222     psp.dwFlags           = PSP_DEFAULT|PSP_HIDEHEADER;
00223     psp.pfnDlgProc        = DlgProcInstallSuccessful;
00224     psp.pszTemplate       = MAKEINTRESOURCE(DLG_INSTALL_SUCCESSFUL);
00225     
00226     pages[count++]        = CreatePropertySheetPage(&psp);
00227   }
00228 
00229   // Property Sheet
00230   psh.dwSize            = sizeof(psh);
00231   psh.hInstance         = hSetupRscInst;
00232   psh.hwndParent        = NULL;
00233   psh.phpage            = pages;
00234   psh.dwFlags           = PSH_WIZARD97|PSH_HEADER;
00235   psh.pszbmHeader       = MAKEINTRESOURCE(IDB_HEADER);
00236   psh.nStartPage        = 0;
00237   psh.nPages            = count;
00238 
00239 
00240   // Start the Wizard.
00241   if (psh.nPages > 1) {
00242     PropertySheet(&psh);
00243   } else {
00244     if (psh.nPages == 1) {
00245       // Auto install
00246       CreateDialog(hSetupRscInst, MAKEINTRESOURCE(DLG_EXTRACTING), NULL, DlgProcInstalling);
00247     } else {
00248       // Silent install
00249       InstallFiles(NULL);
00250     }
00251 
00252     gbIgnoreRunAppX = TRUE;
00253     // Apply settings and close. 
00254     if (sgProduct.bInstallFiles)
00255       UpdateJSProxyInfo();
00256 
00257     /* POST_SMARTUPDATE process file manipulation functions */
00258     ProcessFileOpsForAll(T_POST_SMARTUPDATE);
00259 
00260     if (sgProduct.bInstallFiles) {
00261       /* PRE_LAUNCHAPP process file manipulation functions */
00262       ProcessFileOpsForAll(T_PRE_LAUNCHAPP);
00263 
00264       LaunchApps();
00265 
00266       // Refresh system icons if necessary
00267       if (gSystemInfo.bRefreshIcons)
00268         RefreshIcons();
00269 
00270       UnsetSetupState(); // clear setup state
00271       if (!gbIgnoreProgramFolderX)
00272         ProcessProgramFolderShowCmd();
00273 
00274       CleanupArgsRegistry();
00275       CleanupPreviousVersionRegKeys();
00276 
00277       /* POST_LAUNCHAPP process file manipulation functions */
00278       ProcessFileOpsForAll(T_POST_LAUNCHAPP);
00279       /* DEPEND_REBOOT process file manipulation functions */
00280       ProcessFileOpsForAll(T_DEPEND_REBOOT);
00281     }
00282   }
00283 }
00284 
00285 HFONT MakeFont(TCHAR* aFaceName, int aFontSize, LONG aWeight) 
00286 {
00287   // Welcome Page Header font data
00288   NONCLIENTMETRICS ncm = {0};
00289   LOGFONT lf;
00290   HDC hDC;
00291 
00292   ncm.cbSize = sizeof(ncm);
00293   SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
00294 
00295   if (aFaceName) 
00296     lstrcpy(lf.lfFaceName, aFaceName); 
00297 
00298   lf = ncm.lfMessageFont;
00299   lf.lfWeight = aWeight;
00300 
00301   hDC = GetDC(NULL); 
00302   lf.lfHeight = 0 - GetDeviceCaps(hDC, LOGPIXELSY) * aFontSize / 72;
00303   ReleaseDC(NULL, hDC);
00304 
00305   return CreateFontIndirect(&lf);
00306 }
00307 
00309 // DIALOG: EXIT SETUP
00310 //
00311 
00312 BOOL ShouldExitSetup(HWND hDlg)
00313 {
00314   char szDlgQuitTitle[MAX_BUF];
00315   char szDlgQuitMsg[MAX_BUF];
00316   char szMsg[MAX_BUF];
00317   BOOL rv = FALSE;
00318 
00319   if (sgProduct.mode != SILENT && sgProduct.mode != AUTO) {
00320     if (!GetPrivateProfileString("Messages", "DLGQUITTITLE", "", szDlgQuitTitle, 
00321                                  sizeof(szDlgQuitTitle), szFileIniInstall) ||
00322         !GetPrivateProfileString("Messages", "DLGQUITMSG", "", szDlgQuitMsg, 
00323                                       sizeof(szDlgQuitMsg), szFileIniInstall))
00324       PostQuitMessage(1);
00325 
00326     
00327     rv = MessageBox(GetParent(hDlg), szDlgQuitMsg, szDlgQuitTitle, 
00328                     MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 | MB_APPLMODAL | 
00329                     MB_SETFOREGROUND) == IDYES;
00330   }
00331   else {
00332     GetConfigIniProfileString("Strings", "Message Cancel Setup AUTO mode",
00333                               "", szMsg, sizeof(szMsg));
00334     ShowMessage(szMsg, TRUE);
00335     Delay(5);
00336     ShowMessage(szMsg, FALSE);
00337     rv = TRUE;
00338   }
00339 
00340   if (!rv) 
00341     SetWindowLong(hDlg, DWL_MSGRESULT, (LONG)TRUE);
00342 
00343   return rv;
00344 }
00345 
00346 
00348 // DIALOG: WELCOME
00349 //
00350 
00351 LRESULT CALLBACK DlgProcWelcome(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
00352 {
00353   char szBuf[MAX_BUF];
00354   LPNMHDR notifyMessage;
00355 
00356   switch(msg) {
00357   case WM_INITDIALOG:
00358     // UI Text, from localized config files
00359     wsprintf(szBuf, diWelcome.szMessageWelcome, sgProduct.szProductName);
00360     SetDlgItemText(hDlg, IDC_STATIC_TITLE, szBuf);
00361     wsprintf(szBuf, diWelcome.szMessage0, sgProduct.szProductName);
00362     SetDlgItemText(hDlg, IDC_STATIC0, szBuf);
00363     SetDlgItemText(hDlg, IDC_STATIC1, diWelcome.szMessage1);
00364     SetDlgItemText(hDlg, IDC_STATIC2, diWelcome.szMessage2);
00365     wsprintf(szBuf, diWelcome.szMessage3, sgProduct.szProductName);
00366     SetDlgItemText(hDlg, IDC_STATIC3, szBuf);
00367 
00368     // The header on the welcome page uses another font.
00369     SendDlgItemMessage(hDlg, IDC_STATIC_TITLE, WM_SETFONT, (WPARAM)sgInstallGui.welcomeTitleFont, 0L);
00370 
00371     SendDlgItemMessage(hDlg, IDC_STATIC0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00372     SendDlgItemMessage(hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00373     SendDlgItemMessage(hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00374     SendDlgItemMessage(hDlg, IDC_STATIC3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00375 
00376     // Subclass dialog to paint all static controls white.
00377     OldDialogWndProc = SubclassWindow(hDlg, (WNDPROC)NewDialogWndProc);
00378     break;
00379 
00380   case WM_NOTIFY:
00381     notifyMessage = (LPNMHDR)lParam;
00382     switch (notifyMessage->code) {
00383     case PSN_SETACTIVE:
00384       // Wizard dialog title
00385       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diWelcome.szTitle); 
00386 
00387       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT);
00388       break;
00389 
00390     case PSN_QUERYCANCEL:
00391       return !ShouldExitSetup(hDlg);
00392     }
00393     break;
00394   }
00395 
00396   return 0;
00397 }
00398 
00400 // DIALOG: LICENSE
00401 //
00402 
00403 LRESULT CALLBACK DlgProcLicense(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
00404 {
00405   char            szBuf[MAX_BUF];
00406   LPSTR           szLicenseFilenameBuf = NULL;
00407   WIN32_FIND_DATA wfdFindFileData;
00408   DWORD           dwFileSize;
00409   DWORD           dwBytesRead;
00410   HANDLE          hFLicense;
00411   FILE            *fLicense;
00412   LPNMHDR         notifyMessage;
00413  
00414   switch(msg) {
00415   case WM_INITDIALOG:
00416     SetDlgItemText(hDlg, IDC_MESSAGE0, diLicense.szMessage0);
00417     SetDlgItemText(hDlg, IDC_RADIO_ACCEPT, diLicense.szRadioAccept);
00418     SetDlgItemText(hDlg, IDC_RADIO_DECLINE, diLicense.szRadioDecline);
00419 
00420     SendDlgItemMessage(hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00421     SendDlgItemMessage(hDlg, IDC_RADIO_ACCEPT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00422     SendDlgItemMessage(hDlg, IDC_RADIO_DECLINE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00423 
00424     // Check the "Decline" Radio button by default. 
00425     CheckDlgButton(hDlg, IDC_RADIO_DECLINE, BST_CHECKED);
00426     SendMessage(GetDlgItem(hDlg, IDC_RADIO_DECLINE), BM_SETCHECK, BST_CHECKED, 0);
00427     SendDlgItemMessage(hDlg, IDC_RADIO_DECLINE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00428 
00429     // License Text
00430     lstrcpy(szBuf, szSetupDir);
00431     AppendBackSlash(szBuf, sizeof(szBuf));
00432     lstrcat(szBuf, diLicense.szLicenseFilename);
00433 
00434     if((hFLicense = FindFirstFile(szBuf, &wfdFindFileData)) != INVALID_HANDLE_VALUE)
00435     {
00436       dwFileSize = (wfdFindFileData.nFileSizeHigh * MAXDWORD) + wfdFindFileData.nFileSizeLow + 1;
00437       FindClose(hFLicense);
00438       if((szLicenseFilenameBuf = NS_GlobalAlloc(dwFileSize)) != NULL)
00439       {
00440         if((fLicense = fopen(szBuf, "rb")) != NULL)
00441         {
00442           dwBytesRead = fread(szLicenseFilenameBuf, sizeof(char), dwFileSize, fLicense);
00443           fclose(fLicense);
00444           SetDlgItemText(hDlg, IDC_EDIT_LICENSE, szLicenseFilenameBuf);
00445         }
00446 
00447         FreeMemory(&szLicenseFilenameBuf);
00448       }
00449     }
00450     SendDlgItemMessage(hDlg, IDC_EDIT_LICENSE, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L);
00451     break;
00452 
00453   case WM_COMMAND:
00454     switch (wParam) {
00455     case IDC_RADIO_ACCEPT:
00456       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
00457       break;
00458     case IDC_RADIO_DECLINE:
00459       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK);
00460       break;
00461     }
00462     break;
00463 
00464   case WM_NOTIFY:
00465     notifyMessage = (LPNMHDR)lParam;
00466     switch (notifyMessage->code) {
00467     case PSN_SETACTIVE:
00468       // Wizard dialog title
00469       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diLicense.szTitle); 
00470 
00471       if (IsDlgButtonChecked(hDlg, IDC_RADIO_DECLINE) == BST_CHECKED) 
00472         PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK);  
00473       else
00474         PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
00475       
00476       SendDlgItemMessage(hDlg, IDC_EDIT_LICENSE, EM_SETSEL, 0, 0);
00477 
00478       break;
00479 
00480     case PSN_QUERYCANCEL:
00481       return !ShouldExitSetup(hDlg);
00482     }
00483     break;
00484   }
00485 
00486   return 0;
00487 }
00488 
00490 // DIALOG: SETUP TYPE
00491 //
00492 
00493 LRESULT CALLBACK DlgProcSetupType(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
00494 {
00495   HWND    hRadioSt0, hStaticSt0, hRadioSt1, hStaticSt1;
00496   LPNMHDR notifyMessage;
00497   BOOL    skipNext = FALSE;
00498   static  char defaultPath[MAX_BUF];
00499 
00500   hRadioSt0   = GetDlgItem(hDlg, IDC_RADIO_ST0);
00501   hStaticSt0  = GetDlgItem(hDlg, IDC_STATIC_ST0_DESCRIPTION);
00502   hRadioSt1   = GetDlgItem(hDlg, IDC_RADIO_ST1);
00503   hStaticSt1  = GetDlgItem(hDlg, IDC_STATIC_ST1_DESCRIPTION);
00504 
00505   switch(msg) {
00506   case WM_INITDIALOG:
00507     lstrcpy(defaultPath, sgProduct.szPath);
00508 
00509     SetDlgItemText(hDlg, IDC_STATIC_MSG0, diSetupType.szMessage0);
00510     SendDlgItemMessage(hDlg, IDC_STATIC_MSG0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00511 
00512     if(diSetupType.stSetupType0.bVisible) {
00513       SetDlgItemText(hDlg, IDC_RADIO_ST0, diSetupType.stSetupType0.szDescriptionShort);
00514       SetDlgItemText(hDlg, IDC_STATIC_ST0_DESCRIPTION, diSetupType.stSetupType0.szDescriptionLong);
00515       SendDlgItemMessage(hDlg, IDC_RADIO_ST0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00516       SendDlgItemMessage(hDlg, IDC_STATIC_ST0_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00517       ShowWindow(hRadioSt0, SW_SHOW);
00518       ShowWindow(hStaticSt0, SW_SHOW);
00519     }
00520     else {
00521       ShowWindow(hRadioSt0, SW_HIDE);
00522       ShowWindow(hStaticSt0, SW_HIDE);
00523     }
00524 
00525     if(diSetupType.stSetupType1.bVisible) {
00526       SetDlgItemText(hDlg, IDC_RADIO_ST1, diSetupType.stSetupType1.szDescriptionShort);
00527       SetDlgItemText(hDlg, IDC_STATIC_ST1_DESCRIPTION, diSetupType.stSetupType1.szDescriptionLong);
00528       SendDlgItemMessage(hDlg, IDC_RADIO_ST1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00529       SendDlgItemMessage(hDlg, IDC_STATIC_ST1_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00530       ShowWindow(hRadioSt1, SW_SHOW);
00531       ShowWindow(hStaticSt1, SW_SHOW);
00532     }
00533     else {
00534       ShowWindow(hRadioSt1, SW_HIDE);
00535       ShowWindow(hStaticSt1, SW_HIDE);
00536     }
00537 
00538     break;
00539 
00540   case WM_NOTIFY:
00541     notifyMessage = (LPNMHDR)lParam;
00542 
00543     switch (notifyMessage->code) {
00544     case PSN_SETACTIVE:
00545       // Wizard dialog title
00546       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diSetupType.szTitle); 
00547 
00548       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
00549 
00550       switch(dwTempSetupType) {
00551       case ST_RADIO0:
00552         CheckDlgButton(hDlg, IDC_RADIO_ST0, BST_CHECKED);
00553         SetFocus(hRadioSt0);
00554         break;
00555 
00556       case ST_RADIO1:
00557         CheckDlgButton(hDlg, IDC_RADIO_ST1, BST_CHECKED);
00558         SetFocus(hRadioSt1);
00559         break;
00560       }
00561       break;
00562 
00563     case PSN_WIZNEXT:
00564     case PSN_WIZBACK:
00565       // retrieve and save the state of the selected radio button 
00566       if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST0) == BST_CHECKED)
00567         dwSetupType = ST_RADIO0;
00568       else if(IsDlgButtonChecked(hDlg, IDC_RADIO_ST1) == BST_CHECKED)
00569         dwSetupType = ST_RADIO1;
00570       SiCNodeSetItemsSelected(dwSetupType);
00571 
00572       dwTempSetupType = dwSetupType;
00573 
00574       // If the user has selected "Standard" (easy install) no further data 
00575       // collection is required, go right to the end. 
00576       if (notifyMessage->code == PSN_WIZNEXT && 
00577           dwSetupType == ST_RADIO0) {
00578         // Reset the path to the default value. 
00579         lstrcpy(sgProduct.szPath, defaultPath);
00580 
00581         CheckForUpgrade(hDlg, DLG_START_INSTALL);
00582         skipNext = TRUE;
00583       }
00584       
00585       break;
00586 
00587     case PSN_QUERYCANCEL:
00588       return !ShouldExitSetup(hDlg);
00589     }
00590 
00591     break;
00592   }
00593 
00594   return skipNext;
00595 }
00596 
00598 // DIALOG: SELECT INSTALL PATH
00599 //
00600 
00601 #ifndef BIF_USENEWUI
00602 // BIF_USENEWUI isn't defined in the platform SDK that comes with
00603 // MSVC6.0. 
00604 #define BIF_USENEWUI 0x50
00605 #endif
00606 
00607 int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
00608 {
00609   if (uMsg == BFFM_INITIALIZED)
00610   {
00611     char * filePath = (char *) lpData;
00612     if (filePath)
00613     {
00614       SendMessage(hwnd, BFFM_SETSELECTION, TRUE /* true because lpData is a path string */, lpData);
00615       free(filePath);
00616     }
00617   }
00618 
00619   return 0;
00620 }
00621 
00622 void BrowseForDirectory(HWND hParent)
00623 { 
00624   LPITEMIDLIST  itemIDList;
00625   BROWSEINFO    browseInfo;
00626   char          currDir[MAX_PATH];
00627 
00628   if(SHGetSpecialFolderLocation(hParent, CSIDL_PROGRAM_FILES, &itemIDList) == S_OK)
00629     SHGetPathFromIDList(itemIDList, (LPTSTR) currDir);
00630   else
00631     strncpy(currDir, "C:\\", sizeof(currDir));
00632 
00633   browseInfo.hwndOwner               = hParent;
00634   browseInfo.pidlRoot                       = NULL;
00635   browseInfo.pszDisplayName = currDir;
00636   browseInfo.lpszTitle               = sgInstallGui.szBrowseInfo;
00637   browseInfo.ulFlags                 = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
00638   browseInfo.lpfn                             = NULL;
00639   browseInfo.lParam                    = 0;
00640 
00641   if (currDir[0]) {
00642     browseInfo.lParam = (LPARAM) strdup(currDir);
00643     browseInfo.lpfn = &BrowseCallbackProc;
00644   }
00645   else
00646     browseInfo.lParam = 0;
00647        
00648        // Show the dialog
00649        itemIDList = SHBrowseForFolder(&browseInfo);
00650 
00651   if (itemIDList) {
00652     if (SHGetPathFromIDList(itemIDList, currDir)) {
00653       InitPathDisplay(hParent, currDir, IDC_FOLDER_ICON, IDC_EDIT_DESTINATION);
00654 
00655       SetCurrentDirectory(currDir);
00656 
00657       lstrcpy(szTempSetupPath, currDir);
00658     }
00659 
00660 #if 0
00661     // XXXben LEAK!!!! but this code won't compile for some unknown reason- 
00662     // "Free is not a member of IMalloc, see objidl.h for details"
00663     // but that's a bald-faced lie!
00664               // The shell allocated an ITEMIDLIST, we need to free it. 
00665     // I guess we'll just leak shell objects for now :-D
00666     LPMALLOC shellMalloc;
00667     if (SUCCEEDED(SHGetMalloc(&shellMalloc))) {
00668       shellMalloc->Free(itemIDList);
00669       shellMalloc->Release();
00670               }
00671 #endif
00672        }
00673 }
00674 
00675 void RecoverFromPathError(HWND aPanel)
00676 {
00677   // Reset the displayed path to the previous, valid value. 
00678   InitPathDisplay(aPanel, sgProduct.szPath, IDC_FOLDER_ICON, IDC_EDIT_DESTINATION);
00679 
00680   // Reset the temporary path string so we don't get stuck receiving 
00681   // the error message.
00682   lstrcpy(szTempSetupPath, sgProduct.szPath);
00683 
00684   // Prevent the Wizard from advancing because of this error. 
00685   SetWindowLong(aPanel, DWL_MSGRESULT, -1);
00686 }
00687 
00688 void CheckForUpgrade(HWND aPanel, int aNextPanel)
00689 {
00690   char buf[MAX_BUF];
00691   int nextPanel = aNextPanel;
00692 
00693   // Check to see if we should show the "Safe Upgrade" dialog
00694   // The second part of the test is to see if the flag in config.ini
00695   // specifies whether or not this should be shown *specifically* in the
00696   // "Easy Install" mode. If that flag is set to FALSE, the Upgrade 
00697   // panel is shown only in the "Custom"/"Advanced" pass. 
00698   if (sgProduct.checkCleanupOnUpgrade && 
00699       !(dwSetupType == ST_RADIO0 && !diUpgrade.bShowInEasyInstall) && 
00700       !(dwSetupType == ST_RADIO1 && !diUpgrade.bShowDialog)) {
00701 
00702     // Found destination folder.  check to see if we're upgrading ontop
00703     // of a previous installation.  If so, we need to prompt the user
00704     // about removing the entire dir before installation happens.
00705     MozCopyStr(sgProduct.szPath, buf, sizeof(buf));
00706     AppendBackSlash(buf, sizeof(buf));
00707     lstrcat(buf, sgProduct.szProgramName);
00708     if (FileExists(buf)) {
00709       // Prompt user if deleting target path is okay. Only show
00710       // prompt if the setup is running in normal mode, else
00711       // assume user wants deletion.
00712       if(sgProduct.mode == NORMAL)
00713         nextPanel = DLG_UPGRADE;
00714       else {
00715         sgProduct.doCleanupOnUpgrade = DEFAULT_SAFE_UPGRADE;
00716         nextPanel = aNextPanel;
00717       }
00718     }
00719     else
00720       nextPanel = aNextPanel;
00721   }
00722 
00723   /* SiCNodeSetItemsSelected() is called from within DlgProcUpgrade().
00724    * If DlgProcUpgrade is not called (in the case of a !NORMAL install),
00725    * then we need to call it here. */
00726   if (sgProduct.mode != NORMAL)
00727     SiCNodeSetItemsSelected(dwSetupType);
00728 
00729   gDidShowUpgradePanel = nextPanel == DLG_UPGRADE;
00730 
00731   SetWindowLong(aPanel, DWL_MSGRESULT, nextPanel);
00732 }
00733 
00734 LRESULT CALLBACK DlgProcSelectInstallPath(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
00735 {
00736   char    szBuf[MAX_BUF];
00737   char    szBufTemp[MAX_BUF];
00738   LPNMHDR notifyMessage;
00739   BOOL    rv = FALSE;
00740 
00741   switch(msg) {
00742   case WM_INITDIALOG:
00743     SetDlgItemText(hDlg, IDC_STATIC_MSG0, diSelectInstallPath.szMessage0);
00744 
00745     EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_BROWSE), !sgProduct.bLockPath);
00746 
00747     SetCurrentDirectory(szTempSetupPath);
00748 
00749     InitPathDisplay(hDlg, szTempSetupPath, IDC_FOLDER_ICON, IDC_EDIT_DESTINATION);
00750 
00751     SetDlgItemText(hDlg, IDC_BUTTON_BROWSE, sgInstallGui.szBrowse_);
00752 
00753     SendDlgItemMessage(hDlg, IDC_STATIC_MSG0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00754     SendDlgItemMessage(hDlg, IDC_EDIT_DESTINATION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00755     SendDlgItemMessage(hDlg, IDC_BUTTON_BROWSE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00756 
00757     break;
00758 
00759   case WM_COMMAND:
00760     switch(LOWORD(wParam)) {
00761     case IDC_BUTTON_BROWSE:
00762       BrowseForDirectory(hDlg);
00763       break;
00764     }
00765     break;
00766 
00767   case WM_NOTIFY:
00768     notifyMessage = (LPNMHDR)lParam;
00769 
00770     switch (notifyMessage->code) {
00771     case PSN_SETACTIVE:
00772       // Wizard dialog title
00773       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diSelectInstallPath.szTitle); 
00774 
00775       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
00776 
00777       break;
00778 
00779     case PSN_WIZNEXT:
00780       /* Make sure that the path is not within the windows dir */
00781       if(IsPathWithinWindir(szTempSetupPath)) {
00782         char errorMsg[MAX_BUF];
00783         char errorMsgTitle[MAX_BUF];
00784 
00785         GetPrivateProfileString("Messages", "ERROR_PATH_WITHIN_WINDIR",
00786             "", errorMsg, sizeof(errorMsg), szFileIniInstall);
00787         GetPrivateProfileString("Messages", "ERROR_MESSAGE_TITLE", "",
00788             errorMsgTitle, sizeof(errorMsgTitle), szFileIniInstall);
00789         MessageBox(hDlg, errorMsg, errorMsgTitle, MB_OK | MB_ICONERROR);
00790 
00791         RecoverFromPathError(hDlg);
00792 
00793         return TRUE;
00794       }
00795 
00796       lstrcpy(sgProduct.szPath, szTempSetupPath);
00797       /* append a backslash to the path because CreateDirectoriesAll()
00798          uses a backslash to determine directories */
00799       lstrcpy(szBuf, sgProduct.szPath);
00800       AppendBackSlash(szBuf, sizeof(szBuf));
00801 
00802       CheckForUpgrade(hDlg, DLG_SELECT_COMPONENTS);
00803 
00804       /* Create the path if it does not exist */
00805       if (FileExists(szBuf) == FALSE) {
00806         char szBuf2[MAX_PATH];
00807 
00808         if (CreateDirectoriesAll(szBuf, ADD_TO_UNINSTALL_LOG) != WIZ_OK) {
00809           char szECreateDirectory[MAX_BUF];
00810           char szEMessageTitle[MAX_BUF];
00811 
00812           lstrcpy(szBufTemp, "\n\n");
00813           lstrcat(szBufTemp, sgProduct.szPath);
00814           RemoveBackSlash(szBufTemp);
00815           lstrcat(szBufTemp, "\n\n");
00816 
00817           if (GetPrivateProfileString("Messages", "ERROR_CREATE_DIRECTORY", "", 
00818                                       szECreateDirectory, sizeof(szECreateDirectory), 
00819                                       szFileIniInstall))
00820             wsprintf(szBuf, szECreateDirectory, szBufTemp);
00821 
00822           GetPrivateProfileString("Messages", "ERROR_MESSAGE_TITLE", "", 
00823                                   szEMessageTitle, sizeof(szEMessageTitle), 
00824                                   szFileIniInstall);
00825 
00826           MessageBox(hDlg, szBuf, szEMessageTitle, MB_OK | MB_ICONERROR);
00827           
00828           RecoverFromPathError(hDlg);
00829 
00830           // Prevent the page change if we failed to create the directory. 
00831           SetWindowLong(hDlg, DWL_MSGRESULT, -1);
00832           return TRUE;
00833         }
00834 
00835         if(*sgProduct.szSubPath != '\0') {
00836            /* log the subpath for uninstallation.  This subpath does not normally get logged
00837             * for uninstallation due to a chicken and egg problem with creating the log file
00838             * and the directory its in */
00839           lstrcpy(szBuf2, szBuf);
00840           AppendBackSlash(szBuf2, sizeof(szBuf2));
00841           lstrcat(szBuf2, sgProduct.szSubPath);
00842           UpdateInstallLog(KEY_CREATE_FOLDER, szBuf2, FALSE);
00843         }
00844 
00845       }
00846 
00847       // Need to return TRUE so we override the default wizard sequence. 
00848       rv = TRUE;
00849 
00850       break;
00851 
00852     case PSN_QUERYCANCEL:
00853       return !ShouldExitSetup(hDlg);
00854     }
00855 
00856     break;
00857   }
00858 
00859   return rv;
00860 }
00861 
00863 // DIALOG: UPGRADE CONFIRMATION
00864 //
00865 void UpdateUpgradeModeMessage(HWND aPanel)
00866 {
00867   if (IsDlgButtonChecked(aPanel, IDC_CHECK_SAFE_INSTALL) == BST_CHECKED)
00868     SetDlgItemText(aPanel, IDC_MESSAGE_INFO, diUpgrade.szSafeInstallInfo);
00869   else
00870     SetDlgItemText(aPanel, IDC_MESSAGE_INFO, diUpgrade.szUnsafeInstallInfo);
00871 }
00872 
00873 LRESULT CALLBACK DlgProcUpgrade(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
00874 {
00875   LPNMHDR notifyMessage;
00876   BOOL pathInWinDir = FALSE;
00877   BOOL rv = FALSE;
00878 
00879   switch (msg) {
00880   case WM_INITDIALOG:
00881     SetDlgItemText(hDlg, IDC_MESSAGE_UPGRADE, diUpgrade.szMessageCleanup);
00882     SetDlgItemText(hDlg, IDC_CHECK_SAFE_INSTALL, diUpgrade.szCheckboxSafeInstall);
00883 
00884     SendDlgItemMessage(hDlg, IDC_MESSAGE_UPGRADE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00885     SendDlgItemMessage(hDlg, IDC_CHECK_SAFE_INSTALL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
00886 
00887     // Default to "Safe Upgrade".
00888     CheckDlgButton(hDlg, IDC_CHECK_SAFE_INSTALL, BST_CHECKED);
00889 
00890     break;
00891 
00892   case WM_COMMAND:
00893     switch (LOWORD(wParam)) {
00894     case IDC_CHECK_SAFE_INSTALL:
00895       UpdateUpgradeModeMessage(hDlg);
00896       
00897       break;
00898     }
00899 
00900     break;
00901 
00902   case WM_NOTIFY:
00903     notifyMessage = (LPNMHDR)lParam;
00904 
00905     switch (notifyMessage->code) {
00906     case PSN_SETACTIVE:
00907       // Wizard dialog title
00908       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diUpgrade.szTitle); 
00909 
00910       InitPathDisplay(hDlg, sgProduct.szPath, IDC_FOLDER_ICON, IDC_EDIT_DESTINATION);
00911 
00912       pathInWinDir = IsPathWithinWindir(sgProduct.szPath);
00913       if(pathInWinDir) {
00914         // Do not clean up 
00915         sgProduct.doCleanupOnUpgrade = FALSE;
00916 
00917         // Disable UI and show an explanation. 
00918         EnableWindow(GetDlgItem(hDlg, IDC_CHECK_SAFE_INSTALL), FALSE);
00919         SetDlgItemText(hDlg, IDC_MESSAGE_INFO, diUpgrade.szNoSafeUpgradeWindir);
00920       }
00921 
00922       CheckDlgButton(hDlg, IDC_CHECK_SAFE_INSTALL, sgProduct.doCleanupOnUpgrade ? BST_CHECKED : BST_UNCHECKED);
00923       
00924       if (!pathInWinDir)
00925         UpdateUpgradeModeMessage(hDlg);
00926 
00927       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
00928 
00929       break;
00930 
00931     case PSN_WIZNEXT:
00932       if (dwSetupType == ST_RADIO0) {
00933         SetWindowLong(hDlg, DWL_MSGRESULT, DLG_START_INSTALL);
00934         rv = TRUE;
00935       }
00936 
00937       sgProduct.doCleanupOnUpgrade = IsDlgButtonChecked(hDlg, IDC_CHECK_SAFE_INSTALL) == BST_CHECKED;
00938 
00939       SiCNodeSetItemsSelected(dwSetupType);
00940 
00941       break;
00942 
00943     case PSN_WIZBACK:
00944       if (dwSetupType == ST_RADIO0) {
00945         SetWindowLong(hDlg, DWL_MSGRESULT, DLG_SETUP_TYPE);
00946         rv = TRUE;
00947       }
00948 
00949       sgProduct.doCleanupOnUpgrade = IsDlgButtonChecked(hDlg, IDC_CHECK_SAFE_INSTALL) == BST_CHECKED;
00950 
00951       SiCNodeSetItemsSelected(dwSetupType);
00952 
00953       break;
00954 
00955     case PSN_QUERYCANCEL:
00956       return !ShouldExitSetup(hDlg);
00957     }
00958 
00959     break;
00960   
00961   }
00962   return rv;
00963 }
00964 
00966 // DIALOG: SELECT COMPONENTS
00967 //
00968 
00969 void DrawLBText(LPDRAWITEMSTRUCT lpdis, DWORD dwACFlag)
00970 {
00971   siC     *siCTemp  = NULL;
00972   TCHAR   tchBuffer[MAX_BUF];
00973   TEXTMETRIC tm;
00974   DWORD      y;
00975 
00976   siCTemp = SiCNodeGetObject(lpdis->itemID, FALSE, dwACFlag);
00977   if(siCTemp != NULL)
00978   {
00979     SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)tchBuffer);
00980 
00981     if((lpdis->itemAction & ODA_FOCUS) && (lpdis->itemState & ODS_SELECTED))
00982     {
00983       // remove the focus rect on the previous selected item
00984       DrawFocusRect(lpdis->hDC, &(lpdis->rcItem));
00985     }
00986 
00987     siCTemp = SiCNodeGetObject(lpdis->itemID, FALSE, dwACFlag);
00988     if(lpdis->itemAction & ODA_FOCUS)
00989     {
00990       if((lpdis->itemState & ODS_SELECTED) &&
00991         !(lpdis->itemState & ODS_FOCUS))
00992       {
00993         if(siCTemp->dwAttributes & SIC_DISABLED)
00994           SetTextColor(lpdis->hDC,        GetSysColor(COLOR_GRAYTEXT));
00995         else
00996         {
00997           SetTextColor(lpdis->hDC,        GetSysColor(COLOR_WINDOWTEXT));
00998           SetBkColor(lpdis->hDC,          GetSysColor(COLOR_WINDOW));
00999         }
01000       }
01001       else
01002       {
01003         if(siCTemp->dwAttributes & SIC_DISABLED)
01004           SetTextColor(lpdis->hDC,        GetSysColor(COLOR_GRAYTEXT));
01005         else
01006         {
01007           SetTextColor(lpdis->hDC,        GetSysColor(COLOR_HIGHLIGHTTEXT));
01008           SetBkColor(lpdis->hDC,          GetSysColor(COLOR_HIGHLIGHT));
01009         }
01010       }
01011     }
01012     else if(lpdis->itemAction & ODA_DRAWENTIRE)
01013     {
01014       if(siCTemp->dwAttributes & SIC_DISABLED)
01015         SetTextColor(lpdis->hDC, GetSysColor(COLOR_GRAYTEXT));
01016       else
01017         SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
01018     }
01019 
01020     // If a screen reader is being used we want to redraw the text whether
01021     //   it has focus or not because the text changes whenever the checkbox
01022     //   changes.
01023     if( gSystemInfo.bScreenReader || (lpdis->itemAction & (ODA_DRAWENTIRE | ODA_FOCUS)) )
01024     {
01025       // Display the text associated with the item.
01026       GetTextMetrics(lpdis->hDC, &tm);
01027       y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2;
01028 
01029       ExtTextOut(lpdis->hDC,
01030                  CX_CHECKBOX + 5,
01031                  y,
01032                  ETO_OPAQUE | ETO_CLIPPED,
01033                  &(lpdis->rcItem),
01034                  tchBuffer,
01035                  strlen(tchBuffer),
01036                  NULL);
01037     }
01038   }
01039 }
01040 
01041 void DrawCheck(LPDRAWITEMSTRUCT lpdis, DWORD dwACFlag)
01042 {
01043   siC     *siCTemp  = NULL;
01044   HDC     hdcMem;
01045   HBITMAP hbmpCheckBox;
01046 
01047   siCTemp = SiCNodeGetObject(lpdis->itemID, FALSE, dwACFlag);
01048   if(siCTemp != NULL)
01049   {
01050     if(!(siCTemp->dwAttributes & SIC_SELECTED))
01051       /* Component is not selected.  Use the unchecked bitmap regardless if the 
01052        * component is disabled or not.  The unchecked bitmap looks the same if
01053        * it's disabled or enabled. */
01054       hbmpCheckBox = hbmpBoxUnChecked;
01055     else if(siCTemp->dwAttributes & SIC_DISABLED)
01056       /* Component is checked and disabled */
01057       hbmpCheckBox = hbmpBoxCheckedDisabled;
01058     else
01059       /* Component is checked and enabled */
01060       hbmpCheckBox = hbmpBoxChecked;
01061 
01062     SendMessage(lpdis->hwndItem, LB_SETITEMDATA, lpdis->itemID, (LPARAM)hbmpCheckBox);
01063     if((hdcMem = CreateCompatibleDC(lpdis->hDC)) != NULL)
01064     {
01065       SelectObject(hdcMem, hbmpCheckBox);
01066 
01067       // BitBlt() is used to prepare the checkbox icon into the list box item's device context.
01068       // The SendMessage() function using LB_SETITEMDATA performs the drawing.
01069       BitBlt(lpdis->hDC,
01070              lpdis->rcItem.left + 2,
01071              lpdis->rcItem.top + 2,
01072              lpdis->rcItem.right - lpdis->rcItem.left,
01073              lpdis->rcItem.bottom - lpdis->rcItem.top,
01074              hdcMem,
01075              0,
01076              0,
01077              SRCCOPY);
01078 
01079       DeleteDC(hdcMem);
01080     }
01081   }
01082 }
01083 
01084 void lbAddItem(HWND hList, siC *siCComponent)
01085 {
01086   DWORD dwItem;
01087   TCHAR tchBuffer[MAX_BUF];
01088 
01089   lstrcpy(tchBuffer, siCComponent->szDescriptionShort);
01090   if(gSystemInfo.bScreenReader)
01091   {
01092     lstrcat(tchBuffer, " - ");
01093     if(!(siCComponent->dwAttributes & SIC_SELECTED))
01094       lstrcat(tchBuffer, sgInstallGui.szUnchecked);
01095     else
01096       lstrcat(tchBuffer, sgInstallGui.szChecked);
01097   }
01098   dwItem = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)tchBuffer);
01099 
01100   if(siCComponent->dwAttributes & SIC_DISABLED)
01101     SendMessage(hList, LB_SETITEMDATA, dwItem, (LPARAM)hbmpBoxCheckedDisabled);
01102   else if(siCComponent->dwAttributes & SIC_SELECTED)
01103     SendMessage(hList, LB_SETITEMDATA, dwItem, (LPARAM)hbmpBoxChecked);
01104   else
01105     SendMessage(hList, LB_SETITEMDATA, dwItem, (LPARAM)hbmpBoxUnChecked);
01106 } 
01107 
01108 void InvalidateLBCheckbox(HWND hwndListBox)
01109 {
01110   RECT rcCheckArea;
01111 
01112   // retrieve the rectangle of all list items to update.
01113   GetClientRect(hwndListBox, &rcCheckArea);
01114 
01115   // Set the right coordinate of the rectangle to be the same
01116   //   as the right edge of the bitmap drawn.
01117   // But if a screen reader is being used we want to redraw the text
01118   //   as well as the checkbox so we do not set the right coordinate.
01119   if(!gSystemInfo.bScreenReader)
01120     rcCheckArea.right = CX_CHECKBOX;
01121 
01122   // It then invalidates the checkbox region to be redrawn.
01123   // Invalidating the region sends a WM_DRAWITEM message to
01124   // the dialog, which redraws the region given the
01125   // node attirbute, in this case it is a bitmap of a
01126   // checked/unchecked checkbox.
01127   InvalidateRect(hwndListBox, &rcCheckArea, TRUE);
01128 }
01129   
01130 void ToggleCheck(HWND hwndListBox, DWORD dwIndex, DWORD dwACFlag)
01131 {
01132   BOOL  bMoreToResolve;
01133   LPSTR szToggledReferenceName = NULL;
01134   DWORD dwAttributes;
01135 
01136   // Checks to see if the checkbox is checked or not checked, and
01137   // toggles the node attributes appropriately.
01138   dwAttributes = SiCNodeGetAttributes(dwIndex, FALSE, dwACFlag);
01139   if(!(dwAttributes & SIC_DISABLED))
01140   {
01141     if(dwAttributes & SIC_SELECTED)
01142     {
01143       SiCNodeSetAttributes(dwIndex, SIC_SELECTED, FALSE, FALSE, dwACFlag, hwndListBox);
01144 
01145       szToggledReferenceName = SiCNodeGetReferenceName(dwIndex, FALSE, dwACFlag);
01146       ResolveDependees(szToggledReferenceName, hwndListBox);
01147     }
01148     else
01149     {
01150       SiCNodeSetAttributes(dwIndex, SIC_SELECTED, TRUE, FALSE, dwACFlag, hwndListBox);
01151       bMoreToResolve = ResolveDependencies(dwIndex, hwndListBox);
01152 
01153       while(bMoreToResolve)
01154         bMoreToResolve = ResolveDependencies(-1, hwndListBox);
01155 
01156       szToggledReferenceName = SiCNodeGetReferenceName(dwIndex, FALSE, dwACFlag);
01157       ResolveDependees(szToggledReferenceName, hwndListBox);
01158     }
01159 
01160     InvalidateLBCheckbox(hwndListBox);
01161   }
01162 }
01163 
01164 // ************************************************************************
01165 // FUNCTION : SubclassWindow( HWND, WNDPROC )
01166 // PURPOSE  : Subclasses a window procedure
01167 // COMMENTS : Returns the old window procedure
01168 // ************************************************************************
01169 WNDPROC SubclassWindow( HWND hWnd, WNDPROC NewWndProc)
01170 {
01171   WNDPROC OldWndProc;
01172 
01173   OldWndProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);
01174   SetWindowLong(hWnd, GWL_WNDPROC, (LONG) NewWndProc);
01175 
01176   return OldWndProc;
01177 }
01178 
01179 // ************************************************************************
01180 // FUNCTION : NewDialogWndProc( HWND, UINT, WPARAM, LPARAM )
01181 // PURPOSE  : Processes messages for the Welcome and Finish dialogs.
01182 // COMMENTS : Paints all static control backgrounds in white.
01183 // ************************************************************************
01184 LRESULT CALLBACK NewDialogWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
01185 {
01186   switch(uMsg)
01187   {
01188     case WM_CTLCOLORSTATIC:
01189       return (HRESULT)GetStockObject(WHITE_BRUSH);
01190   }
01191   
01192   return(CallWindowProc(OldDialogWndProc, hWnd, uMsg, wParam, lParam));
01193 }
01194 
01195 // ************************************************************************
01196 // FUNCTION : NewListBoxWndProc( HWND, UINT, WPARAM, LPARAM )
01197 // PURPOSE  : Processes messages for "LISTBOX" class.
01198 // COMMENTS : Prevents the user from moving the window
01199 //            by dragging the titlebar.
01200 // ************************************************************************
01201 LRESULT CALLBACK NewListBoxWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
01202 {
01203   DWORD   dwPosX;
01204   DWORD   dwPosY;
01205   DWORD   dwIndex;
01206   
01207   switch(uMsg)
01208   {
01209     case WM_CHAR:
01210       /* check for the space key */
01211       if((TCHAR)wParam == 32)
01212       {
01213         dwIndex = SendMessage(hWnd,
01214                               LB_GETCURSEL,
01215                               0,
01216                               0);
01217         ToggleCheck(hWnd, dwIndex, gdwACFlag);
01218       }
01219       break;
01220 
01221     case WM_LBUTTONDOWN:
01222       if(wParam == MK_LBUTTON)
01223       {
01224         dwPosX = LOWORD(lParam); // x pos
01225         dwPosY = HIWORD(lParam); // y pos
01226 
01227         if((dwPosX > 1) && (dwPosX <= CX_CHECKBOX))
01228         {
01229           dwIndex = LOWORD(SendMessage(hWnd,
01230                                        LB_ITEMFROMPOINT,
01231                                        0,
01232                                        (LPARAM)MAKELPARAM(dwPosX, dwPosY)));
01233           ToggleCheck(hWnd, dwIndex, gdwACFlag);
01234         }
01235       }
01236       break;
01237   }
01238 
01239   return(CallWindowProc(OldListBoxWndProc, hWnd, uMsg, wParam, lParam));
01240 }
01241 
01242 LRESULT CALLBACK DlgProcSelectComponents(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
01243 {
01244   siC                 *siCTemp;
01245   DWORD               dwIndex;
01246   DWORD               dwItems = MAX_BUF;
01247   HWND                hwndLBComponents;
01248   LPDRAWITEMSTRUCT    lpdis;
01249 #ifdef STUB_INSTALLER
01250   TCHAR               tchBuffer[MAX_BUF];
01251   ULONGLONG           ullDSBuf;
01252   char                szBuf[MAX_BUF];
01253 #endif
01254 
01255   LPNMHDR             notifyMessage;
01256 
01257   hwndLBComponents  = GetDlgItem(hDlg, IDC_LIST_COMPONENTS);
01258 
01259   switch(msg) {
01260   case WM_INITDIALOG:
01261     SetDlgItemText(hDlg, IDC_MESSAGE0, diSelectComponents.szMessage0);
01262     SendDlgItemMessage(hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01263 
01264     siCTemp = siComponents;
01265     if(siCTemp != NULL)
01266     {
01267       if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL)))
01268         lbAddItem(hwndLBComponents, siCTemp);
01269 
01270       siCTemp = siCTemp->Next;
01271       while((siCTemp != siComponents) && (siCTemp != NULL))
01272       {
01273         if((!(siCTemp->dwAttributes & SIC_INVISIBLE)) && (!(siCTemp->dwAttributes & SIC_ADDITIONAL)))
01274           lbAddItem(hwndLBComponents, siCTemp);
01275 
01276         siCTemp = siCTemp->Next;
01277       }
01278       SetFocus(hwndLBComponents);
01279       SendMessage(hwndLBComponents, LB_SETCURSEL, 0, 0);
01280       SetDlgItemText(hDlg, IDC_STATIC_DESCRIPTION, SiCNodeGetDescriptionLong(0, FALSE, AC_COMPONENTS));
01281       SendDlgItemMessage(hDlg, IDC_STATIC_DESCRIPTION, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01282     }
01283 
01284     SetDlgItemText(hDlg, IDC_STATIC1, sgInstallGui.szComponents_);
01285     SetDlgItemText(hDlg, IDC_STATIC2, sgInstallGui.szDescription);
01286 
01287     SendDlgItemMessage(hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01288     SendDlgItemMessage(hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01289 
01290 #ifdef STUB_INSTALLER
01291     // XXXben We don't support net stub installs yet. 
01292     SetDlgItemText(hDlg, IDC_STATIC_DOWNLOAD_SIZE, sgInstallGui.szTotalDownloadSize);
01293     SendDlgItemMessage(hDlg, IDC_STATIC_DOWNLOAD_SIZE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01294 #endif
01295 
01296     SendDlgItemMessage(hDlg, IDC_LIST_COMPONENTS, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L);
01297 
01298     gdwACFlag = AC_COMPONENTS;
01299     OldListBoxWndProc = SubclassWindow(hwndLBComponents, (WNDPROC)NewListBoxWndProc);
01300 
01301     break;
01302 
01303   case WM_DRAWITEM:
01304     lpdis = (LPDRAWITEMSTRUCT)lParam;
01305 
01306     // If there are no list box items, skip this message.
01307     if(lpdis->itemID == -1)
01308       break;
01309 
01310     DrawLBText(lpdis, AC_COMPONENTS);
01311     DrawCheck(lpdis, AC_COMPONENTS);
01312 
01313     // draw the focus rect on the selected item
01314     if((lpdis->itemAction & ODA_FOCUS) &&
01315        (lpdis->itemState & ODS_FOCUS))
01316       DrawFocusRect(lpdis->hDC, &(lpdis->rcItem));
01317 
01318     break;
01319 
01320   case WM_COMMAND:
01321     switch(LOWORD(wParam)) {
01322     case IDC_LIST_COMPONENTS:
01323       /* to update the long description for each component the user selected */
01324       if((dwIndex = SendMessage(hwndLBComponents, LB_GETCURSEL, 0, 0)) != LB_ERR) {
01325         SetDlgItemText(hDlg, IDC_STATIC_DESCRIPTION, SiCNodeGetDescriptionLong(dwIndex, FALSE, AC_COMPONENTS));
01326 
01327 #ifdef STUB_INSTALLER
01328         // update the disk space required info in the dialog.  It is already
01329         // in Kilobytes
01330         ullDSBuf = GetDiskSpaceRequired(DSR_DOWNLOAD_SIZE);
01331         _ui64toa(ullDSBuf, tchBuffer, 10);
01332         wsprintf(szBuf, sgInstallGui.szDownloadSize, tchBuffer);
01333    
01334         // XXXben We don't support net stub installs yet. 
01335         // SetDlgItemText(hDlg, IDC_STATIC_DOWNLOAD_SIZE, szBuf);
01336 #endif
01337       }
01338 
01339       break;
01340     }
01341     break;
01342 
01343   case WM_NOTIFY:
01344     notifyMessage = (LPNMHDR)lParam;
01345 
01346     switch (notifyMessage->code) {
01347     case PSN_SETACTIVE:
01348       // Wizard dialog title
01349       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diSelectComponents.szTitle); 
01350 
01351       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
01352 
01353       break;
01354 
01355     case PSN_WIZBACK:
01356       // If we showed the "Upgrade" panel, be sure to show it again in the sequence 
01357       // on the way back, to not do so "feels" wrong/confusing. 
01358       if (gDidShowUpgradePanel)
01359         SetWindowLong(hDlg, DWL_MSGRESULT, DLG_UPGRADE);
01360       else 
01361         SetWindowLong(hDlg, DWL_MSGRESULT, DLG_SELECT_INSTALL_PATH);
01362       
01363       return TRUE;
01364       break;
01365 
01366     case PSN_QUERYCANCEL:
01367       return !ShouldExitSetup(hDlg);
01368     }
01369 
01370     break;
01371   }
01372 
01373   return 0;
01374 }
01375 
01377 // DIALOG: SUMMARY
01378 //
01379 
01380 BOOL IsSelectableComponent(siC* aComponent)
01381 {
01382   return !(aComponent->dwAttributes & SIC_INVISIBLE) && 
01383          !(aComponent->dwAttributes & SIC_ADDITIONAL);
01384 }
01385 
01386 BOOL IsComponentSelected(siC* aComponent)
01387 {
01388   return aComponent->dwAttributes & SIC_SELECTED;
01389 }
01390 
01391 void GetRelativeRect(HWND aWindow, int aResourceID, RECT* aRect)
01392 {
01393   HWND ctrl;
01394   POINT pt;
01395 
01396   ctrl = GetDlgItem(aWindow, aResourceID);
01397 
01398   GetWindowRect(ctrl, aRect);
01399 
01400   pt.x = aRect->left;
01401   pt.y = aRect->top;
01402   ScreenToClient(aWindow, &pt);
01403   aRect->left = pt.x;
01404   aRect->top = pt.y;
01405 
01406   pt.x = aRect->right;
01407   pt.y = aRect->bottom;
01408   ScreenToClient(aWindow, &pt);
01409   aRect->right = pt.x;
01410   aRect->bottom = pt.y;
01411 }
01412 
01413 void PositionControl(HWND aWindow, int aResourceIDRelative, int aResourceIDControl, int aOffset)
01414 {
01415   HWND ctrl;
01416   RECT r1, r2;
01417 
01418   GetRelativeRect(aWindow, aResourceIDRelative, &r1);
01419   GetRelativeRect(aWindow, aResourceIDControl, &r2);
01420 
01421   ctrl = GetDlgItem(aWindow, aResourceIDControl);
01422   SetWindowPos(ctrl, NULL, r2.left, r1.bottom + aOffset, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
01423 }
01424 
01425 
01426 LRESULT CALLBACK DlgProcSummary(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
01427 {
01428   LPSTR szMessage = NULL;
01429   LPNMHDR notifyMessage;
01430   char szAddtlComps[MAX_BUF];
01431   char szTemp[MAX_BUF];
01432   char szFormat[MAX_BUF_TINY];
01433   BOOL hasAddtlComps = FALSE;
01434   BOOL skipNext = FALSE;
01435   siC *currComponent, *mainComponent;
01436   HICON largeIcon, smallIcon;
01437   DWORD result;
01438   HKEY theKey;
01439 
01440   switch(msg) {
01441   case WM_INITDIALOG:
01442     SetDlgItemText(hDlg, IDC_MESSAGE1, diStartInstall.szMessage0);
01443     SetDlgItemText(hDlg, IDC_MESSAGE2, sgInstallGui.szProxyMessage);
01444     SetDlgItemText(hDlg, IDC_CONNECTION_SETTINGS, sgInstallGui.szProxyButton);
01445     SetDlgItemText(hDlg, IDC_INSTALL_FOLDER_LABEL, sgInstallGui.szInstallFolder);
01446 
01447     SendDlgItemMessage(hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01448     SendDlgItemMessage(hDlg, IDC_MESSAGE1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01449     SendDlgItemMessage(hDlg, IDC_MESSAGE2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01450     SendDlgItemMessage(hDlg, IDC_CONNECTION_SETTINGS, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01451     SendDlgItemMessage(hDlg, IDC_INSTALL_FOLDER_LABEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01452     SendDlgItemMessage(hDlg, IDC_INSTALL_FOLDER, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01453     SendDlgItemMessage(hDlg, IDC_PRIMARY_COMPONENT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01454     SendDlgItemMessage(hDlg, IDC_OPTIONAL_COMPONENTS, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01455 
01456     ExtractIconEx("setuprsc.dll", 1, &largeIcon, &smallIcon, 1);
01457     SendMessage(GetDlgItem(hDlg, IDC_APP_ICON), STM_SETICON, (LPARAM)smallIcon, 0);
01458 
01459     break;
01460   
01461   case WM_NOTIFY:
01462     notifyMessage = (LPNMHDR)lParam;
01463 
01464     switch (notifyMessage->code) {
01465     case PSN_SETACTIVE:
01466       // Wizard dialog title
01467       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diSelectComponents.szTitle); 
01468 
01469       // Set the user-determined fields here in case they go back and change
01470       // options - WM_INITDIALOG only gets called once, not every time the
01471       // panel is displayed.
01472 
01473 #ifdef STUB_INSTALLER
01474       // Update strings that relate to whether or not files will be downloaded. 
01475       // The user may have selected additional components that require a download.
01476       if ((diAdvancedSettings.bShowDialog == FALSE) || (GetTotalArchivesToDownload() == 0)) {
01477 #endif
01478         SetDlgItemText(hDlg, IDC_MESSAGE0, diStartInstall.szMessageInstall);
01479 
01480         // Hide Download-related UI:
01481         ShowWindow(GetDlgItem(hDlg, IDC_MESSAGE2), SW_HIDE);
01482         ShowWindow(GetDlgItem(hDlg, IDC_CONNECTION_SETTINGS), SW_HIDE);
01483 #ifdef STUB_INSTALLER
01484       }
01485       else
01486         SetDlgItemText(hDlg, IDC_MESSAGE0, diStartInstall.szMessageDownload);
01487 #endif
01488 
01489       // Update the registry keys that the installer scripts use to determine
01490       // what shortcuts to create
01491       result = RegCreateKeyEx(HKEY_CURRENT_USER, diWindowsIntegration.szRegistryKey, 0, NULL,
01492                               0, KEY_READ | KEY_WRITE, NULL, &theKey, NULL);
01493       if (result == ERROR_SUCCESS) {
01494         RegSetValueEx(theKey, "Create Desktop Shortcut", 0, REG_DWORD, 
01495                       (LPBYTE)&(diWindowsIntegration.wiCB0.bCheckBoxState), 
01496                       sizeof(DWORD));
01497         RegSetValueEx(theKey, "Create Start Menu Shortcut", 0, REG_DWORD, 
01498                       (LPBYTE)&(diWindowsIntegration.wiCB1.bCheckBoxState), 
01499                       sizeof(DWORD));
01500         RegSetValueEx(theKey, "Create Quick Launch Shortcut", 0, REG_DWORD, 
01501                       (LPBYTE)&(diWindowsIntegration.wiCB2.bCheckBoxState), 
01502                       sizeof(DWORD));
01503         RegCloseKey(theKey);
01504       }
01505 
01506       // Show the components we're going to install
01507       szAddtlComps[0] = '\0';
01508       currComponent = siComponents;
01509       do {
01510         if (!currComponent)
01511           break;
01512 
01513         if (currComponent->dwAttributes & SIC_MAIN_COMPONENT)
01514           mainComponent = currComponent;
01515         else if (IsSelectableComponent(currComponent) && 
01516                  IsComponentSelected(currComponent)) {
01517           wsprintf(szFormat, "%s\r\n", sgInstallGui.szAddtlCompWrapper);
01518           wsprintf(szTemp, szFormat, currComponent->szDescriptionShort);
01519           lstrcat(szAddtlComps, szTemp);
01520 
01521           hasAddtlComps = TRUE;
01522         }
01523 
01524         currComponent = currComponent->Next;
01525       }
01526       while (currComponent && currComponent != siComponents);
01527 
01528       // Update the display to reflect whether or not additional components are going to 
01529       // be installed. If none are, we shift the install folder detail up so that it's
01530       // neatly under the Primary Component name. 
01531       if (hasAddtlComps) {
01532         wsprintf(szTemp, sgInstallGui.szPrimCompOthers, mainComponent->szDescriptionShort);
01533 
01534         ShowWindow(GetDlgItem(hDlg, IDC_OPTIONAL_COMPONENTS), SW_SHOW);
01535 
01536         SetDlgItemText(hDlg, IDC_OPTIONAL_COMPONENTS, szAddtlComps);
01537 
01538         PositionControl(hDlg, IDC_OPTIONAL_COMPONENTS, IDC_INSTALL_FOLDER_LABEL, 10);
01539       }
01540       else {
01541         wsprintf(szTemp, sgInstallGui.szPrimCompNoOthers, mainComponent->szDescriptionShort);
01542 
01543         ShowWindow(GetDlgItem(hDlg, IDC_OPTIONAL_COMPONENTS), SW_HIDE);
01544 
01545         // Shift the "Install Folder" text up in the "No Components" case
01546         PositionControl(hDlg, IDC_PRIMARY_COMPONENT, IDC_INSTALL_FOLDER_LABEL, 10);
01547       }
01548       PositionControl(hDlg, IDC_INSTALL_FOLDER_LABEL, IDC_INSTALL_FOLDER, 10);
01549       PositionControl(hDlg, IDC_INSTALL_FOLDER_LABEL, IDC_FOLDER_ICON, 7);
01550 
01551       SetDlgItemText(hDlg, IDC_PRIMARY_COMPONENT, szTemp);
01552 
01553       // Update the install folder. 
01554       InitPathDisplay(hDlg, sgProduct.szPath, IDC_FOLDER_ICON, IDC_INSTALL_FOLDER);
01555       
01556       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
01557 
01558       break;
01559       
01560     case PSN_WIZNEXT:
01561       SaveUserChanges();
01562 
01563       if (!IsDownloadRequired()) {
01564         // No download required, bypass the download step and go directly to 
01565         // the installing stage. 
01566         SetWindowLong(hDlg, DWL_MSGRESULT, DLG_EXTRACTING);
01567         skipNext = TRUE;
01568       }
01569       break;
01570 
01571     case PSN_WIZBACK:
01572       // If the user selected Easy Install, go right back to the setup type
01573       // selection page, bypassing the advanced configuration steps. 
01574       if (dwSetupType == ST_RADIO0) {
01575         // If we showed the "Upgrade" panel, be sure to show it again in the sequence 
01576         // on the way back, to not do so "feels" wrong/confusing. 
01577         if (gDidShowUpgradePanel) 
01578           SetWindowLong(hDlg, DWL_MSGRESULT, DLG_UPGRADE);
01579         else  
01580           SetWindowLong(hDlg, DWL_MSGRESULT, DLG_SETUP_TYPE);
01581         skipNext = TRUE;
01582       }
01583       break;
01584 
01585     case PSN_QUERYCANCEL:
01586       return !ShouldExitSetup(hDlg);
01587     }
01588     break;
01589   case WM_COMMAND:
01590     switch(LOWORD(wParam)) {
01591     case IDC_CONNECTION_SETTINGS:
01592       break;
01593     }
01594     break;
01595   }
01596 
01597   return skipNext;
01598 }
01599 
01600 void SaveUserChanges()
01601 {
01602   char szDestPath[MAX_BUF];
01603   char szInstallLogFile[MAX_BUF];
01604 
01605   LogISShared();
01606   LogISDestinationPath();
01607   LogISSetupType();
01608   LogISComponentsSelected();
01609   LogISComponentsToDownload();
01610   LogISDiskSpace(gdsnComponentDSRequirement);
01611 
01612   lstrcpy(szDestPath, sgProduct.szPath);
01613   if(*sgProduct.szSubPath != '\0')
01614   {
01615     AppendBackSlash(szDestPath, sizeof(szDestPath));
01616     lstrcat(szDestPath, sgProduct.szSubPath);
01617   }
01618   AppendBackSlash(szDestPath, sizeof(szDestPath));
01619 
01620   // Create the destination path here in case it had not been created,
01621   // as in the case of silent or auto mode installs 
01622   if(CreateDirectoriesAll(szDestPath, ADD_TO_UNINSTALL_LOG) != WIZ_OK)
01623   {
01624     char buf[MAX_BUF];
01625     char errorCreateDir[MAX_BUF];
01626     char pathToShow[MAX_PATH];
01627 
01628     // reformat the path to display so that it'll be readable in the
01629     // error dialog shown 
01630     _snprintf(pathToShow, sizeof(pathToShow), "\"%s\" ", szDestPath);
01631     pathToShow[sizeof(pathToShow) - 1] = '\0';
01632     if(GetPrivateProfileString("Messages", "ERROR_CREATE_DIRECTORY", "", errorCreateDir, sizeof(errorCreateDir), szFileIniInstall))
01633       wsprintf(buf, errorCreateDir, pathToShow);
01634     assert(*buf != '\0');
01635     PrintError(buf, ERROR_CODE_HIDE);
01636     PostQuitMessage(1);
01637     return;
01638   }
01639 
01640   // Set global var, that determines where the log file is to update, to
01641   // not use the TEMP dir *before* the FileCopy() calls because we want
01642   // to log the FileCopy() calls to where the log files were copied to.
01643   // This is possible because the logging, that is done within the
01644   // FileCopy() function, is done after the actual copy
01645   //
01646   gbILUseTemp = FALSE;
01647 
01648   // copy the install_wizard.log file from the temp\ns_temp dir to
01649   // the destination dir and use the new destination file to continue
01650   // logging.
01651   //
01652   lstrcpy(szInstallLogFile, szTempDir);
01653   AppendBackSlash(szInstallLogFile, sizeof(szInstallLogFile));
01654   lstrcat(szInstallLogFile, FILE_INSTALL_LOG);
01655   FileCopy(szInstallLogFile, szDestPath, FALSE, FALSE);
01656   DeleteFile(szInstallLogFile);
01657 
01658   // copy the install_status.log file from the temp\ns_temp dir to
01659   // the destination dir and use the new destination file to continue
01660   // logging.
01661   //
01662   lstrcpy(szInstallLogFile, szTempDir);
01663   AppendBackSlash(szInstallLogFile, sizeof(szInstallLogFile));
01664   lstrcat(szInstallLogFile, FILE_INSTALL_STATUS_LOG);
01665   FileCopy(szInstallLogFile, szDestPath, FALSE, FALSE);
01666   DeleteFile(szInstallLogFile);
01667 }
01668 
01669 BOOL IsDownloadRequired()
01670 {
01671   DWORD dwIndex0;
01672   DWORD dwFileCounter;
01673   siC   *siCObject = NULL;
01674   long  result;
01675   char  szFileIdiGetArchives[MAX_BUF];
01676   char  szSection[MAX_BUF];
01677   char  szCorruptedArchiveList[MAX_BUF];
01678   char  szPartiallyDownloadedFilename[MAX_BUF];
01679 
01680   ZeroMemory(szCorruptedArchiveList, sizeof(szCorruptedArchiveList));
01681   lstrcpy(szFileIdiGetArchives, szTempDir);
01682   AppendBackSlash(szFileIdiGetArchives, sizeof(szFileIdiGetArchives));
01683   lstrcat(szFileIdiGetArchives, FILE_IDI_GETARCHIVES);
01684   GetSetupCurrentDownloadFile(szPartiallyDownloadedFilename,
01685                               sizeof(szPartiallyDownloadedFilename));
01686 
01687   gbDownloadTriggered= FALSE;
01688   result            = WIZ_OK;
01689   dwIndex0           = 0;
01690   dwFileCounter      = 0;
01691   siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01692   
01693   while (siCObject) {
01694     if (siCObject->dwAttributes & SIC_SELECTED) {
01695       // If a previous unfinished setup was detected, then
01696       // include the TEMP dir when searching for archives.
01697       // Only download jars if not already in the local machine.
01698       // Also if the last file being downloaded should be resumed.
01699       // The resume detection is done automatically.
01700       if ((LocateJar(siCObject, NULL, 0, 
01701                     gbPreviousUnfinishedDownload) == AP_NOT_FOUND) ||
01702           (lstrcmpi(szPartiallyDownloadedFilename,
01703                     siCObject->szArchiveName) == 0)) {
01704         wsprintf(szSection, "File%d", dwFileCounter);
01705 
01706         result = AddArchiveToIdiFile(siCObject,
01707                                      szSection,
01708                                      szFileIdiGetArchives);
01709         if (result)
01710           return result;
01711 
01712         ++dwFileCounter;
01713       }
01714     }
01715 
01716     ++dwIndex0;
01717     siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL);
01718   }
01719 
01720   // The existence of the getarchives.idi file determines if there are
01721   // any archives needed to be downloaded.
01722   return FileExists(szFileIdiGetArchives);
01723 }
01724 
01725 #ifdef STUB_INSTALLER
01726 
01727 // DIALOG: CONNECTION SETTINGS
01728 //
01729 
01730 void SaveDownloadProtocolOption(HWND hDlg)
01731 {
01732   if(IsDlgButtonChecked(hDlg, IDC_USE_FTP) == BST_CHECKED)
01733     diAdditionalOptions.dwUseProtocol = UP_FTP;
01734   else if(IsDlgButtonChecked(hDlg, IDC_USE_HTTP) == BST_CHECKED)
01735     diAdditionalOptions.dwUseProtocol = UP_HTTP;
01736 }
01737 
01738 LRESULT CALLBACK DlgProcAdvancedSettings(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
01739 {
01740   char  szBuf[MAX_BUF];
01741 
01742   switch(msg)
01743   {
01744     case WM_INITDIALOG:
01745       SetWindowText(hDlg, diAdvancedSettings.szTitle);
01746       SetDlgItemText(hDlg, IDC_MESSAGE0,          diAdvancedSettings.szMessage0);
01747       SetDlgItemText(hDlg, IDC_EDIT_PROXY_SERVER, diAdvancedSettings.szProxyServer);
01748       SetDlgItemText(hDlg, IDC_EDIT_PROXY_PORT,   diAdvancedSettings.szProxyPort);
01749       SetDlgItemText(hDlg, IDC_EDIT_PROXY_USER,   diAdvancedSettings.szProxyUser);
01750       SetDlgItemText(hDlg, IDC_EDIT_PROXY_PASSWD, diAdvancedSettings.szProxyPasswd);
01751 
01752       GetIniConfigProfileString("Strings", "IDC Use Ftp", "", szBuf, sizeof(szBuf));
01753       SetDlgItemText(hDlg, IDC_USE_FTP, szBuf);
01754       GetIniConfigProfileString("Strings", "IDC Use Http", "", szBuf, sizeof(szBuf));
01755       SetDlgItemText(hDlg, IDC_USE_HTTP, szBuf);
01756 
01757       SetDlgItemText(hDlg, IDC_STATIC, sgInstallGui.szProxySettings);
01758       SetDlgItemText(hDlg, IDC_STATIC1, sgInstallGui.szServer);
01759       SetDlgItemText(hDlg, IDC_STATIC2, sgInstallGui.szPort);
01760       SetDlgItemText(hDlg, IDC_STATIC3, sgInstallGui.szUserId);
01761       SetDlgItemText(hDlg, IDC_STATIC4, sgInstallGui.szPassword);
01762       SetDlgItemText(hDlg, IDWIZNEXT, sgInstallGui.szOk_);
01763       SetDlgItemText(hDlg, IDCANCEL, sgInstallGui.szCancel_);
01764       SendDlgItemMessage (hDlg, IDC_STATIC, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01765       SendDlgItemMessage (hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01766       SendDlgItemMessage (hDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01767       SendDlgItemMessage (hDlg, IDC_STATIC3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01768       SendDlgItemMessage (hDlg, IDC_STATIC4, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01769       SendDlgItemMessage (hDlg, IDWIZNEXT, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01770       SendDlgItemMessage (hDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01771       SendDlgItemMessage (hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01772       SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_SERVER, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L);
01773       SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_PORT, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L);
01774       SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_USER, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L);
01775       SendDlgItemMessage (hDlg, IDC_EDIT_PROXY_PASSWD, WM_SETFONT, (WPARAM)sgInstallGui.systemFont, 0L);
01776       SendDlgItemMessage (hDlg, IDC_USE_FTP, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01777       SendDlgItemMessage (hDlg, IDC_USE_HTTP, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01778 
01779       switch(diAdditionalOptions.dwUseProtocol)
01780       {
01781         case UP_HTTP:
01782           CheckDlgButton(hDlg, IDC_USE_FTP,  BST_UNCHECKED);
01783           CheckDlgButton(hDlg, IDC_USE_HTTP, BST_CHECKED);
01784           break;
01785 
01786         case UP_FTP:
01787         default:
01788           CheckDlgButton(hDlg, IDC_USE_FTP,  BST_CHECKED);
01789           CheckDlgButton(hDlg, IDC_USE_HTTP, BST_UNCHECKED);
01790           break;
01791 
01792       }
01793 
01794       if((diAdditionalOptions.bShowProtocols) && (diAdditionalOptions.bUseProtocolSettings))
01795       {
01796         ShowWindow(GetDlgItem(hDlg, IDC_USE_FTP),  SW_SHOW);
01797         ShowWindow(GetDlgItem(hDlg, IDC_USE_HTTP), SW_SHOW);
01798       }
01799       else
01800       {
01801         ShowWindow(GetDlgItem(hDlg, IDC_USE_FTP),  SW_HIDE);
01802         ShowWindow(GetDlgItem(hDlg, IDC_USE_HTTP), SW_HIDE);
01803       }
01804 
01805       break;
01806 
01807     case WM_COMMAND:
01808       switch(LOWORD(wParam))
01809       {
01810         case IDWIZNEXT:
01811           /* get the proxy server and port information */
01812           GetDlgItemText(hDlg, IDC_EDIT_PROXY_SERVER, diAdvancedSettings.szProxyServer, MAX_BUF);
01813           GetDlgItemText(hDlg, IDC_EDIT_PROXY_PORT,   diAdvancedSettings.szProxyPort,   MAX_BUF);
01814           GetDlgItemText(hDlg, IDC_EDIT_PROXY_USER,   diAdvancedSettings.szProxyUser,   MAX_BUF);
01815           GetDlgItemText(hDlg, IDC_EDIT_PROXY_PASSWD, diAdvancedSettings.szProxyPasswd, MAX_BUF);
01816 
01817           SaveDownloadProtocolOption(hDlg);
01818           DestroyWindow(hDlg);
01819           break;
01820 
01821         case IDWIZBACK:
01822         case IDCANCEL:
01823           DestroyWindow(hDlg);
01824           break;
01825 
01826         default:
01827           break;
01828       }
01829       break;
01830   }
01831   return(0);
01832 }
01833 #endif
01834 
01836 // DIALOG: DOWNLOADING FILES
01837 //
01838 
01839 LRESULT CALLBACK DlgProcDownloading(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
01840 {
01841 #ifdef STUB_INSTALLER
01842   switch(msg)
01843   {
01844     case WM_INITDIALOG:
01845       SetWindowText(hDlg, diDownloading.szTitle);
01846 
01847       SetDlgItemText(hDlg, IDC_MESSAGE0, diDownloading.szBlurb);
01848       SetDlgItemText(hDlg, IDC_STATIC0, diDownloading.szFileNameKey);
01849       SetDlgItemText(hDlg, IDC_STATIC1, diDownloading.szTimeRemainingKey);
01850 
01851       SendDlgItemMessage(hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01852       SendDlgItemMessage(hDlg, IDC_STATIC0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01853       SendDlgItemMessage(hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01854 
01855       break;
01856 
01857     case WM_COMMAND:
01858       switch(LOWORD(wParam))
01859       {
01860         default:
01861           break;
01862       }
01863       break;
01864   }
01865 #endif
01866 
01867   return 0;
01868 }
01869 
01871 // DIALOG: INSTALLING FILES
01872 //
01873 
01874 #define BTN_CLSNAME_LEN 7
01875 #define BTN_CANCEL_OFFSET 4
01876 BOOL CALLBACK DisableCancelButton(HWND aWindow, LPARAM aData)
01877 {
01878   static int offset = 0;
01879   char className[BTN_CLSNAME_LEN];
01880   char text[MAX_BUF];
01881 
01882   GetClassName(aWindow, className, BTN_CLSNAME_LEN);
01883   if (!strcmp(className, "Button") && 
01884       GetParent(aWindow) == (HWND)aData) {
01885     GetWindowText(aWindow, text, MAX_BUF-1);
01886     if (++offset == BTN_CANCEL_OFFSET) {
01887       offset = 0;
01888       EnableWindow(aWindow, FALSE);
01889       return FALSE;
01890     }
01891   }
01892 
01893   return TRUE;
01894 }
01895 
01896 LRESULT CALLBACK DlgProcInstalling(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
01897 {
01898   LPNMHDR notifyMessage;
01899   static BOOL initialized = FALSE; 
01900   HWND parent = GetParent(hDlg);
01901   char installStart[MAX_BUF];
01902 
01903   switch(msg) {
01904   case WM_INITDIALOG:
01905     SetWindowText(hDlg, diInstalling.szTitle);
01906 
01907     SetDlgItemText(hDlg, IDC_STATUS0, diInstalling.szStatusFile);
01908     SetDlgItemText(hDlg, IDC_STATUS3, diInstalling.szStatusComponent);
01909 
01910     SendDlgItemMessage(hDlg, IDC_STATUS0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01911     SendDlgItemMessage(hDlg, IDC_STATUS3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
01912 
01913     break;
01914 
01915   case WM_PAINT:
01916     if (initialized)
01917       break;
01918 
01919     initialized = TRUE;
01920 
01921     if (InstallFiles(hDlg)) {
01922       if (sgProduct.mode != AUTO) {
01923         PropSheet_SetCurSelByID(parent, DLG_INSTALL_SUCCESSFUL);
01924       }
01925       break;
01926     }
01927     else {
01928       // XXXben TODO: handle error. 
01929       printf("Files NOT Installed...\n");
01930     }
01931     break;
01932 
01933   case WM_NOTIFY:
01934     notifyMessage = (LPNMHDR)lParam;
01935 
01936     switch (notifyMessage->code) {
01937     case PSN_SETACTIVE:
01938       // Wizard dialog title
01939       PropSheet_SetTitle(parent, 0, (LPTSTR)diInstalling.szTitle); 
01940 
01941       GetPrivateProfileString("Messages", "MSG_SMARTUPDATE_START", 
01942                               "", installStart, 
01943                               sizeof(installStart), 
01944                               szFileIniInstall);
01945 
01946       SetDlgItemText(hDlg, IDC_STATUS0, installStart);
01947 
01948       if (sgProduct.mode != AUTO) {
01949         // Disable the Cancel button. This leaves the button disabled for
01950         // this page (Installing) and the final page (Finish) because it 
01951         // is meaningless and potentially damaging in both places. 
01952         EnumChildWindows(parent, DisableCancelButton, (LPARAM)parent);
01953 
01954         PropSheet_SetWizButtons(parent, 0);
01955       }
01956 
01957       break;
01958 
01959     case PSN_QUERYCANCEL:
01960       // Do NOT let the user cancel at this point. 
01961       SetWindowLong(hDlg, DWL_MSGRESULT, (LONG)FALSE);
01962       return TRUE;
01963     }
01964   }
01965   return 0;
01966 }
01967 
01968 BOOL InstallFiles(HWND hDlg)
01969 {
01970   HRESULT err;
01971 
01972   // Clean up old versions of GRE previously installed.
01973   // These GREs should only be fully uninstalled if they were only
01974   // being used by the mozilla that we're installing over/ontop of
01975   // (upgrade scenario).
01976   // We should only do this type of cleanup if we're about to install'
01977   // GRE in shared mode.
01978   //
01979   // This should only be called when the installer is installing GRE!
01980   if (IsInstallerProductGRE())
01981     CleanupOrphanedGREs();
01982 
01983   if (sgProduct.bInstallFiles) {
01984     // POST_DOWNLOAD process file manipulation functions 
01985     ProcessFileOpsForAll(T_POST_DOWNLOAD);
01986     // PRE_XPCOM process file manipulation functions 
01987     ProcessFileOpsForAll(T_PRE_XPCOM);
01988 
01989     // save the installer files in the local machine 
01990     if (diAdditionalOptions.bSaveInstaller)
01991       SaveInstallerFiles();
01992 
01993     if (CheckInstances()) {
01994       bSDUserCanceled = TRUE;
01995       CleanupXpcomFile();
01996       return FALSE;
01997     }
01998 
01999     // Remove the previous installation of the product here.
02000     // This should be done before processing the Xpinstall engine.
02001     if(sgProduct.doCleanupOnUpgrade) {
02002       SetSetupState(SETUP_STATE_REMOVING_PREV_INST);
02003       CleanupOnUpgrade();
02004     }
02005 
02006     if(gbDownloadTriggered || gbPreviousUnfinishedDownload)
02007       SetSetupState(SETUP_STATE_UNPACK_XPCOM);
02008 
02009     if(ProcessXpinstallEngine() != WIZ_OK) {
02010       bSDUserCanceled = TRUE;
02011       CleanupXpcomFile();
02012       return FALSE;
02013     }
02014 
02015     if (gbDownloadTriggered || gbPreviousUnfinishedDownload)
02016       SetSetupState(SETUP_STATE_INSTALL_XPI); // clears and sets new setup state
02017 
02018     // POST_XPCOM process file manipulation functions
02019     ProcessFileOpsForAll(T_POST_XPCOM);
02020     // PRE_SMARTUPDATE process file manipulation functions
02021     ProcessFileOpsForAll(T_PRE_SMARTUPDATE);
02022 
02023     //XXXben TODO - process this return result!
02024     err = SmartUpdateJars(hDlg);
02025   }
02026   else
02027     err = WIZ_OK;
02028 
02029   CleanupXpcomFile();
02030 
02031   return err == WIZ_OK || err == 999;
02032 }
02033 
02035 // DIALOG: WINTEGRATION
02036 //         Not actually used yet!
02037 
02038 LRESULT CALLBACK DlgProcWindowsIntegration(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
02039 {
02040   LPNMHDR notifyMessage;
02041 
02042   switch (msg) {
02043   case WM_INITDIALOG:
02044     SetDlgItemText(hDlg, IDC_MESSAGE0, diWindowsIntegration.szMessage0);
02045     SendDlgItemMessage(hDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02046 
02047     if (diWindowsIntegration.wiCB0.bEnabled) {
02048       ShowWindow(GetDlgItem(hDlg, IDC_CHECK0), SW_SHOW);
02049       SetDlgItemText(hDlg, IDC_CHECK0, diWindowsIntegration.wiCB0.szDescription);
02050       SendDlgItemMessage(hDlg, IDC_CHECK0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02051     }
02052     else
02053       ShowWindow(GetDlgItem(hDlg, IDC_CHECK0), SW_HIDE);
02054 
02055     if (diWindowsIntegration.wiCB1.bEnabled) {
02056       ShowWindow(GetDlgItem(hDlg, IDC_CHECK1), SW_SHOW);
02057       SetDlgItemText(hDlg, IDC_CHECK1, diWindowsIntegration.wiCB1.szDescription);
02058       SendDlgItemMessage(hDlg, IDC_CHECK1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02059     }
02060     else
02061       ShowWindow(GetDlgItem(hDlg, IDC_CHECK1), SW_HIDE);
02062 
02063     if (diWindowsIntegration.wiCB2.bEnabled) {
02064       ShowWindow(GetDlgItem(hDlg, IDC_CHECK2), SW_SHOW);
02065       SetDlgItemText(hDlg, IDC_CHECK2, diWindowsIntegration.wiCB2.szDescription);
02066       SendDlgItemMessage(hDlg, IDC_CHECK2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02067     }
02068     else
02069       ShowWindow(GetDlgItem(hDlg, IDC_CHECK2), SW_HIDE);
02070 
02071     break;
02072 
02073   case WM_NOTIFY:
02074     notifyMessage = (LPNMHDR)lParam;
02075     switch (notifyMessage->code) {
02076     case PSN_SETACTIVE:
02077       // Wizard dialog title
02078       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diWindowsIntegration.szTitle); 
02079 
02080       // Restore state from default or cached value. 
02081       CheckDlgButton(hDlg, IDC_CHECK0, 
02082                      diWindowsIntegration.wiCB0.bCheckBoxState);
02083       CheckDlgButton(hDlg, IDC_CHECK1, 
02084                      diWindowsIntegration.wiCB1.bCheckBoxState);
02085       CheckDlgButton(hDlg, IDC_CHECK2, 
02086                      diWindowsIntegration.wiCB2.bCheckBoxState);
02087 
02088       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT|PSWIZB_BACK);
02089       break;
02090 
02091     case PSN_WIZNEXT:
02092       diWindowsIntegration.wiCB0.bCheckBoxState = 
02093         IsDlgButtonChecked(hDlg, IDC_CHECK0) == BST_CHECKED;
02094       diWindowsIntegration.wiCB1.bCheckBoxState = 
02095         IsDlgButtonChecked(hDlg, IDC_CHECK1) == BST_CHECKED;
02096       diWindowsIntegration.wiCB2.bCheckBoxState = 
02097         IsDlgButtonChecked(hDlg, IDC_CHECK2) == BST_CHECKED;
02098 
02099       break;
02100 
02101     case PSN_QUERYCANCEL:
02102       return !ShouldExitSetup(hDlg);
02103     }
02104       
02105     break;
02106   }
02107 
02108   return 0;
02109 }
02110 
02112 // DIALOG: SUCCESSFUL INSTALL
02113 //
02114 
02115 LRESULT CALLBACK DlgProcInstallSuccessful(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
02116 {
02117   char szBuf[MAX_BUF];
02118   LPNMHDR notifyMessage;
02119   static BOOL launchAppChecked = TRUE;
02120   DWORD result;
02121   
02122   switch(msg) {
02123   case WM_INITDIALOG:
02124     // UI Text, from localized config files
02125     SetDlgItemText(hDlg, IDC_STATIC_TITLE, diInstallSuccessful.szMessageHeader);
02126     wsprintf(szBuf, diInstallSuccessful.szMessage0, sgProduct.szProductName);
02127     SetDlgItemText(hDlg, IDC_STATIC0, szBuf);
02128     SetDlgItemText(hDlg, IDC_STATIC1, diInstallSuccessful.szMessage1);
02129     wsprintf(szBuf, diInstallSuccessful.szLaunchApp, sgProduct.szProductName);
02130     SetDlgItemText(hDlg, IDC_START_APP, szBuf);
02131 
02132     // The header on the welcome page uses another font.
02133     SendDlgItemMessage(hDlg, IDC_STATIC_TITLE, WM_SETFONT, (WPARAM)sgInstallGui.welcomeTitleFont, 0L);
02134 
02135     SendDlgItemMessage(hDlg, IDC_STATIC0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02136     SendDlgItemMessage(hDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02137     SendDlgItemMessage(hDlg, IDC_START_APP, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02138 
02139     launchAppChecked = diInstallSuccessful.bLaunchAppChecked;
02140 
02141     // Subclass dialog to paint all static controls white.
02142     OldDialogWndProc = SubclassWindow(hDlg, (WNDPROC)NewDialogWndProc);
02143     break;
02144 
02145   case WM_NOTIFY:
02146     notifyMessage = (LPNMHDR)lParam;
02147     switch (notifyMessage->code) {
02148     case PSN_SETACTIVE:
02149       // Wizard dialog title
02150       PropSheet_SetTitle(GetParent(hDlg), 0, (LPTSTR)diInstallSuccessful.szTitle); 
02151 
02152       // Restore state from default or cached value. 
02153       CheckDlgButton(hDlg, IDC_START_APP, 
02154                      launchAppChecked ? BST_CHECKED : BST_UNCHECKED);
02155 
02156       // Don't show the back button here UNLESS the previous 
02157       // page was Windows Integration - and that only happens on a custom
02158       // install. 
02159       PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_FINISH);
02160       break;
02161 
02162     case PSN_WIZBACK:
02163       // Store the checkbox state in case the user goes back to any post-install
02164       // pages that we might add.
02165       launchAppChecked = IsDlgButtonChecked(hDlg, IDC_START_APP) == BST_CHECKED;
02166       break;
02167 
02168     case PSN_WIZFINISH:
02169       // Store state from the "Run App Now" checkbox. ProcessFileOpsForAll
02170       // uses this variable to decide whether or not to launch the browser.
02171       gbIgnoreRunAppX = IsDlgButtonChecked(hDlg, IDC_START_APP) != BST_CHECKED;
02172 
02173       // Apply settings and close. 
02174       if (sgProduct.bInstallFiles)
02175         UpdateJSProxyInfo();
02176 
02177       /* POST_SMARTUPDATE process file manipulation functions */
02178       ProcessFileOpsForAll(T_POST_SMARTUPDATE);
02179 
02180       if (sgProduct.bInstallFiles) {
02181         /* PRE_LAUNCHAPP process file manipulation functions */
02182         ProcessFileOpsForAll(T_PRE_LAUNCHAPP);
02183 
02184         LaunchApps();
02185 
02186         // Refresh system icons if necessary
02187         if (gSystemInfo.bRefreshIcons)
02188           RefreshIcons();
02189 
02190         UnsetSetupState(); // clear setup state
02191         if (!gbIgnoreProgramFolderX)
02192           ProcessProgramFolderShowCmd();
02193 
02194         CleanupArgsRegistry();
02195         CleanupPreviousVersionRegKeys();
02196 
02197         /* POST_LAUNCHAPP process file manipulation functions */
02198         ProcessFileOpsForAll(T_POST_LAUNCHAPP);
02199         /* DEPEND_REBOOT process file manipulation functions */
02200         ProcessFileOpsForAll(T_DEPEND_REBOOT);
02201       }
02202 
02203       break;
02204 
02205 
02206     case PSN_QUERYCANCEL:
02207       // Cancel is meaningless and potentially harmful here (the install work
02208       // is not yet complete). If the user finds a way of cancelling, e.g. by
02209       // clicking the X button on the window, send the FINISH message. 
02210 
02211       // Assume at least that they didn't want the app to run right away. 
02212       gbIgnoreRunAppX = FALSE;
02213 
02214       // Send the PSN_WIZFINISH so we can clean up properly. 
02215       notifyMessage->code = PSN_WIZFINISH;
02216       SendMessage(hDlg, WM_NOTIFY, wParam, (LPARAM)notifyMessage);
02217 
02218       // Tell the Wizard97 framework that we don't want to hard-quit. Processing
02219       // of the PSN_WIZFINISH will cause the app to shut down. 
02220       SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
02221       return TRUE;
02222     }
02223       
02224     break;
02225   }
02226   
02227   return 0;
02228 }
02229 
02231 // DIALOG: MESSAGE (A small utility message window)
02232 //
02233 
02234 LRESULT CALLBACK DlgProcMessage(HWND hDlg, UINT msg, WPARAM wParam, LONG lParam)
02235 {
02236   RECT      rDlg;
02237   HWND      hSTMessage = GetDlgItem(hDlg, IDC_MESSAGE); /* handle to the Static Text message window */
02238   HDC       hdcSTMessage;
02239   SIZE      sizeString;
02240   LOGFONT   logFont;
02241   HFONT     hfontTmp;
02242   HFONT     hfontOld;
02243   char      szBuf[MAX_BUF];
02244   char      szBuf2[MAX_BUF];
02245 
02246   ZeroMemory(szBuf, sizeof(szBuf));
02247   ZeroMemory(szBuf2, sizeof(szBuf2));
02248 
02249   switch(msg)
02250   {
02251     case WM_INITDIALOG:
02252       if(GetPrivateProfileString("Messages", "STR_MESSAGEBOX_TITLE", "", szBuf2, sizeof(szBuf2), szFileIniInstall))
02253       {
02254         if((sgProduct.szProductName != NULL) && (*sgProduct.szProductName != '\0'))
02255           wsprintf(szBuf, szBuf2, sgProduct.szProductName);
02256         else
02257           wsprintf(szBuf, szBuf2, "");
02258       }
02259       else if((sgProduct.szProductName != NULL) && (*sgProduct.szProductName != '\0'))
02260         lstrcpy(szBuf, sgProduct.szProductName);
02261 
02262       SetWindowText(hDlg, szBuf);
02263 
02264       SendDlgItemMessage(hDlg, IDC_MESSAGE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
02265 
02266       break;
02267 
02268     case WM_COMMAND:
02269       switch(LOWORD(wParam))
02270       {
02271         case IDC_MESSAGE:
02272           hdcSTMessage = GetWindowDC(hSTMessage);
02273 
02274           SystemParametersInfo(SPI_GETICONTITLELOGFONT,
02275                                sizeof(logFont),
02276                                (PVOID)&logFont,
02277                                0);
02278           hfontTmp = CreateFontIndirect(&logFont);
02279 
02280           if(hfontTmp)
02281             hfontOld = SelectObject(hdcSTMessage, hfontTmp);
02282 
02283           GetTextExtentPoint32(hdcSTMessage, (LPSTR)lParam, lstrlen((LPSTR)lParam), &sizeString);
02284           SelectObject(hdcSTMessage, hfontOld);
02285           DeleteObject(hfontTmp);
02286           ReleaseDC(hSTMessage, hdcSTMessage);
02287 
02288           SetWindowPos(hDlg, NULL,
02289                       (gSystemInfo.lastWindowPosCenterX)-((sizeString.cx + 55)/2),
02290                       (gSystemInfo.lastWindowPosCenterY)-((sizeString.cy + 50)/2),
02291                       sizeString.cx + 55,
02292                       sizeString.cy + 50,
02293                       SWP_SHOWWINDOW|SWP_NOZORDER);
02294 
02295           if(GetClientRect(hDlg, &rDlg))
02296             SetWindowPos(hSTMessage,
02297                          HWND_TOP,
02298                          rDlg.left,
02299                          rDlg.top,
02300                          rDlg.right,
02301                          rDlg.bottom,
02302                          SWP_SHOWWINDOW|SWP_NOZORDER);
02303 
02304           SetDlgItemText(hDlg, IDC_MESSAGE, (LPSTR)lParam);
02305           break;
02306       }
02307       break;
02308   }
02309   return(0);
02310 }
02311 
02312 void ShowMessage(LPSTR szMessage, BOOL bShow)
02313 {
02314   if(sgProduct.mode != SILENT)
02315   {
02316     if(bShow && szMessage)
02317     {
02318       char szBuf[MAX_BUF];
02319  
02320       ZeroMemory(szBuf, sizeof(szBuf));
02321       GetPrivateProfileString("Messages", "MB_MESSAGE_STR", "", szBuf, sizeof(szBuf), szFileIniInstall);
02322       hDlgMessage = InstantiateDialog(hWndMain, DLG_MESSAGE, szBuf, DlgProcMessage);
02323       SendMessage(hDlgMessage, WM_COMMAND, IDC_MESSAGE, (LPARAM)szMessage);
02324     }
02325     else
02326     {
02327       DestroyWindow(hDlgMessage);
02328       hDlgMessage = NULL;
02329     }
02330   }
02331 }
02332 
02334 // UTILITY FUNCTIONS
02335 
02336 void ProcessWindowsMessages()
02337 {
02338   MSG msg;
02339 
02340   while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
02341   {
02342     TranslateMessage(&msg);
02343     DispatchMessage(&msg);
02344   }
02345 }
02346 
02347 HWND InstantiateDialog(HWND hParent, DWORD dwDlgID, LPSTR szTitle, WNDPROC wpDlgProc)
02348 {
02349   char szBuf[MAX_BUF];
02350   HWND hDlg = NULL;
02351 
02352 
02353   if((hDlg = CreateDialog(hSetupRscInst, MAKEINTRESOURCE(dwDlgID), hParent, wpDlgProc)) == NULL)
02354   {
02355     char szEDialogCreate[MAX_BUF];
02356 
02357     if(GetPrivateProfileString("Messages", "ERROR_DIALOG_CREATE", "", szEDialogCreate, sizeof(szEDialogCreate), szFileIniInstall))
02358     {
02359       wsprintf(szBuf, szEDialogCreate, szTitle);
02360       PrintError(szBuf, ERROR_CODE_SHOW);
02361     }
02362     PostQuitMessage(1);
02363   }
02364 
02365   return(hDlg);
02366 }
02367 
02368 void TruncateString(HWND hWnd, LPSTR szInURL, LPSTR szOutString, DWORD dwOutStringBufSize)
02369 {
02370   HDC           hdcWnd;
02371   LOGFONT       logFont;
02372   HFONT         hfontNew;
02373   HFONT         hfontOld;
02374   RECT          rWndRect;
02375   SIZE          sizeString;
02376   char          *ptr = NULL;
02377   int           iHalfLen;
02378   int           iOutStringLen;
02379 
02380   if((DWORD)lstrlen(szInURL) > dwOutStringBufSize)
02381     return;
02382 
02383   ZeroMemory(szOutString, dwOutStringBufSize);
02384   lstrcpy(szOutString, szInURL);
02385   iOutStringLen = lstrlen(szOutString);
02386   hdcWnd        = GetWindowDC(hWnd);
02387   GetClientRect(hWnd, &rWndRect);
02388   SystemParametersInfo(SPI_GETICONTITLELOGFONT,
02389                        sizeof(logFont),
02390                        (PVOID)&logFont,
02391                        0);
02392 
02393   hfontNew = CreateFontIndirect(&logFont);
02394   if(hfontNew)
02395   {
02396     hfontOld = (HFONT)SelectObject(hdcWnd, hfontNew);
02397 
02398     GetTextExtentPoint32(hdcWnd, szOutString, iOutStringLen, &sizeString);
02399     while(sizeString.cx > rWndRect.right)
02400     {
02401       iHalfLen = iOutStringLen / 2;
02402       if(iHalfLen == 2)
02403         break;
02404 
02405       ptr = szOutString + iHalfLen;
02406       memmove(ptr - 1, ptr, lstrlen(ptr) + 1);
02407       szOutString[iHalfLen - 2] = '.';
02408       szOutString[iHalfLen - 1] = '.';
02409       szOutString[iHalfLen]     = '.';
02410       iOutStringLen = lstrlen(szOutString);
02411       GetTextExtentPoint32(hdcWnd, szOutString, iOutStringLen, &sizeString);
02412     }
02413   }
02414 
02415   SelectObject(hdcWnd, hfontOld);
02416   DeleteObject(hfontNew);
02417   ReleaseDC(hWnd, hdcWnd);
02418 }
02419 
02420 void InitPathDisplay (HWND aWindow, char* aPath, int aFolderIcon, int aFolderField)
02421 {
02422   HICON largeIcon, smallIcon;
02423   char buf[MAX_BUF];
02424 
02425    // Folder Icon
02426   ExtractIconEx("shell32.dll", 3, &largeIcon, &smallIcon, 1);
02427   SendMessage(GetDlgItem(aWindow, aFolderIcon), STM_SETICON, (LPARAM)smallIcon, 0);
02428  
02429   TruncateString(GetDlgItem(aWindow, aFolderField), 
02430                  aPath, buf, sizeof(buf));
02431   SetDlgItemText(aWindow, aFolderField, buf);
02432 }
02433 
02434 
02435 
02436 
02437 
02438 
02439