void CreateMainWindow() { gHwndFrame = CreateWindow( INSTALLER_FRAME_CLASS_NAME, TAPP L" " CURR_VERSION_STR L" Uninstaller", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, dpiAdjust(INSTALLER_WIN_DX), dpiAdjust(INSTALLER_WIN_DY), NULL, NULL, ghinst, NULL); }
void CreateMainWindow() { ScopedMem<WCHAR> title(str::Format(_TR("SumatraPDF %s Uninstaller"), CURR_VERSION_STR)); gHwndFrame = CreateWindow( INSTALLER_FRAME_CLASS_NAME, title.Get(), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, dpiAdjust(INSTALLER_WIN_DX), dpiAdjust(INSTALLER_WIN_DY), NULL, NULL, ghinst, NULL); }
void CreateMainWindow() { ScopedMem<WCHAR> title(str::Format(_TR("SumatraPDF %s Installer"), CURR_VERSION_STR)); gHwndFrame = CreateWindowEx( trans::IsCurrLangRtl() ? WS_EX_LAYOUTRTL : 0, INSTALLER_FRAME_CLASS_NAME, title.Get(), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, dpiAdjust(INSTALLER_WIN_DX), dpiAdjust(INSTALLER_WIN_DY), nullptr, nullptr, GetModuleHandle(nullptr), nullptr); }
static void OnButtonInstall() { CrashAlwaysIf(gForceCrash); if (gShowOptions) OnButtonOptions(); KillSumatra(); if (!CheckInstallUninstallPossible()) return; WCHAR *userInstallDir = win::GetText(gHwndTextboxInstDir); if (!str::IsEmpty(userInstallDir)) str::ReplacePtr(&gGlobalData.installDir, userInstallDir); free(userInstallDir); // note: this checkbox isn't created if we're already registered as default // (in which case we're just going to re-register) gGlobalData.registerAsDefault = gHwndCheckboxRegisterDefault == nullptr || IsCheckboxChecked(gHwndCheckboxRegisterDefault); // note: this checkbox isn't created when running inside Wow64 gGlobalData.installPdfFilter = gHwndCheckboxRegisterPdfFilter != nullptr && IsCheckboxChecked(gHwndCheckboxRegisterPdfFilter); // note: this checkbox isn't created on Windows 2000 and XP gGlobalData.installPdfPreviewer = gHwndCheckboxRegisterPdfPreviewer != nullptr && IsCheckboxChecked(gHwndCheckboxRegisterPdfPreviewer); // note: this checkbox isn't created if the browser plugin hasn't been installed before gGlobalData.keepBrowserPlugin = gHwndCheckboxKeepBrowserPlugin != nullptr && IsCheckboxChecked(gHwndCheckboxKeepBrowserPlugin); // create a progress bar in place of the Options button RectI rc(0, 0, dpiAdjust(INSTALLER_WIN_DX / 2), gButtonDy); rc = MapRectToWindow(rc, gHwndButtonOptions, gHwndFrame); gHwndProgressBar = CreateWindow(PROGRESS_CLASS, nullptr, WS_CHILD | WS_VISIBLE, rc.x, rc.y, rc.dx, rc.dy, gHwndFrame, 0, GetModuleHandle(nullptr), nullptr); SendMessage(gHwndProgressBar, PBM_SETRANGE32, 0, GetInstallationStepCount()); SendMessage(gHwndProgressBar, PBM_SETSTEP, 1, 0); // disable the install button and remove all the installation options SafeDestroyWindow(&gHwndStaticInstDir); SafeDestroyWindow(&gHwndTextboxInstDir); SafeDestroyWindow(&gHwndButtonBrowseDir); SafeDestroyWindow(&gHwndCheckboxRegisterDefault); SafeDestroyWindow(&gHwndCheckboxRegisterPdfFilter); SafeDestroyWindow(&gHwndCheckboxRegisterPdfPreviewer); SafeDestroyWindow(&gHwndCheckboxKeepBrowserPlugin); SafeDestroyWindow(&gHwndButtonOptions); EnableWindow(gHwndButtonInstUninst, FALSE); SetMsg(_TR("Installation in progress..."), COLOR_MSG_INSTALLATION); InvalidateFrame(); gGlobalData.hThread = CreateThread(nullptr, 0, InstallerThread, nullptr, 0, 0); }
//[ ACCESSKEY_GROUP Installer void OnCreateWindow(HWND hwnd) { ClientRect r(hwnd); gHwndButtonInstUninst = CreateDefaultButton(hwnd, _TR("Install SumatraPDF"), IDOK); SIZE btnSize; gHwndButtonOptions = CreateButton(hwnd, _TR("&Options"), ID_BUTTON_OPTIONS, BS_PUSHBUTTON, btnSize); int x = WINDOW_MARGIN; int y = r.dy - btnSize.cy - WINDOW_MARGIN; SetWindowPos(gHwndButtonOptions, nullptr, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW); gButtonDy = btnSize.cy; gBottomPartDy = gButtonDy + (WINDOW_MARGIN * 2); SizeI size = TextSizeInHwnd(hwnd, L"Foo"); int staticDy = size.dy + dpiAdjust(4); y = r.dy - gBottomPartDy; int dx = r.dx - (WINDOW_MARGIN * 2) - dpiAdjust(2); x += dpiAdjust(2); // build options controls going from the bottom y -= (staticDy + WINDOW_MARGIN); ScopedMem<WCHAR> defaultViewer(GetDefaultPdfViewer()); BOOL hasOtherViewer = !str::EqI(defaultViewer, APP_NAME_STR); BOOL isSumatraDefaultViewer = defaultViewer && !hasOtherViewer; // only show this checkbox if the CPU arch of DLL and OS match // (assuming that the installer has the same CPU arch as its content!) if (IsProcessAndOsArchSame()) { // only show this checkbox if the browser plugin has been installed before if (IsBrowserPluginInstalled()) { gHwndCheckboxKeepBrowserPlugin = CreateWindowExW( 0, WC_BUTTON, _TR("Keep the PDF &browser plugin installed (no longer supported)"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, x, y, dx, staticDy, hwnd, (HMENU) ID_CHECKBOX_BROWSER_PLUGIN, GetModuleHandle(nullptr), nullptr); SetWindowFont(gHwndCheckboxKeepBrowserPlugin, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxKeepBrowserPlugin, gGlobalData.keepBrowserPlugin); y -= staticDy; } // for Windows XP, this means only basic thumbnail support gHwndCheckboxRegisterPdfPreviewer = CreateWindowExW( 0, WC_BUTTON, _TR("Let Windows show &previews of PDF documents"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, x, y, dx, staticDy, hwnd, (HMENU) ID_CHECKBOX_PDF_PREVIEWER, GetModuleHandle(nullptr), nullptr); SetWindowFont(gHwndCheckboxRegisterPdfPreviewer, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterPdfPreviewer, gGlobalData.installPdfPreviewer || IsPdfPreviewerInstalled()); y -= staticDy; gHwndCheckboxRegisterPdfFilter = CreateWindowEx( 0, WC_BUTTON, _TR("Let Windows Desktop Search &search PDF documents"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, x, y, dx, staticDy, hwnd, (HMENU) ID_CHECKBOX_PDF_FILTER, GetModuleHandle(nullptr), nullptr); SetWindowFont(gHwndCheckboxRegisterPdfFilter, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterPdfFilter, gGlobalData.installPdfFilter || IsPdfFilterInstalled()); y -= staticDy; } // only show the checbox if Sumatra is not already a default viewer. // the alternative (disabling the checkbox) is more confusing if (!isSumatraDefaultViewer) { gHwndCheckboxRegisterDefault = CreateWindowExW( 0, WC_BUTTON, _TR("Use SumatraPDF as the &default PDF reader"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, x, y, dx, staticDy, hwnd, (HMENU) ID_CHECKBOX_MAKE_DEFAULT, GetModuleHandle(nullptr), nullptr); SetWindowFont(gHwndCheckboxRegisterDefault, gFontDefault, TRUE); // only check the "Use as default" checkbox when no other PDF viewer // is currently selected (not going to intrude) Button_SetCheck(gHwndCheckboxRegisterDefault, !hasOtherViewer || gGlobalData.registerAsDefault); y -= staticDy; } // a bit more space between text box and checkboxes y -= (dpiAdjust(4) + WINDOW_MARGIN); const WCHAR *s = L"&..."; SizeI btnSize2 = TextSizeInHwnd(hwnd, s); btnSize.cx += dpiAdjust(4); gHwndButtonBrowseDir = CreateButton(hwnd, s, ID_BUTTON_BROWSE, BS_PUSHBUTTON, btnSize); x = r.dx - WINDOW_MARGIN - btnSize2.dx; SetWindowPos(gHwndButtonBrowseDir, nullptr, x, y, btnSize2.dx, staticDy, SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_FRAMECHANGED); x = WINDOW_MARGIN; dx = r.dx - (2 * WINDOW_MARGIN) - btnSize2.dx - dpiAdjust(4); gHwndTextboxInstDir = CreateWindowExW(0, WC_EDIT, gGlobalData.installDir, WS_CHILD | WS_TABSTOP | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL, x, y, dx, staticDy, hwnd, nullptr, GetModuleHandle(nullptr), nullptr); SetWindowFont(gHwndTextboxInstDir, gFontDefault, TRUE); y -= staticDy; gHwndStaticInstDir = CreateWindowExW( 0, WC_STATIC, _TR("Install SumatraPDF in &folder:"),WS_CHILD, x, y, r.dx, staticDy, hwnd, nullptr, GetModuleHandle(nullptr), nullptr); SetWindowFont(gHwndStaticInstDir, gFontDefault, TRUE); gShowOptions = !gShowOptions; OnButtonOptions(); SetFocus(gHwndButtonInstUninst); if (gGlobalData.autoUpdate) { // click the Install button PostMessage(hwnd, WM_COMMAND, IDOK, 0); } }
// TODO: since we have a variable UI, for better layout (anchored to the bottom, // not the top), we should layout controls starting at the bottom and go up void OnCreateWindow(HWND hwnd) { // TODO: this button might be too narrow for some translations gHwndButtonInstUninst = CreateDefaultButton(hwnd, _TR("Install SumatraPDF"), 140); RectI rc(WINDOW_MARGIN, 0, dpiAdjust(96), PUSH_BUTTON_DY); ClientRect r(hwnd); rc.y = r.dy - rc.dy - WINDOW_MARGIN; gHwndButtonOptions = CreateWindow(WC_BUTTON, _TR("&Options"), BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, rc.x, rc.y, rc.dx, rc.dy, hwnd, (HMENU)ID_BUTTON_OPTIONS, ghinst, NULL); SetWindowFont(gHwndButtonOptions, gFontDefault, TRUE); int staticDy = dpiAdjust(20); rc.y = TITLE_PART_DY + WINDOW_MARGIN; gHwndStaticInstDir = CreateWindow(WC_STATIC, _TR("Install SumatraPDF in &folder:"), WS_CHILD, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, NULL, ghinst, NULL); SetWindowFont(gHwndStaticInstDir, gFontDefault, TRUE); rc.y += staticDy; gHwndTextboxInstDir = CreateWindow(WC_EDIT, gGlobalData.installDir, WS_CHILD | WS_TABSTOP | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL, rc.x, rc.y, r.dx - 3 * rc.x - staticDy, staticDy, hwnd, NULL, ghinst, NULL); SetWindowFont(gHwndTextboxInstDir, gFontDefault, TRUE); gHwndButtonBrowseDir = CreateWindow(WC_BUTTON, L"&...", BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, r.dx - rc.x - staticDy, rc.y, staticDy, staticDy, hwnd, (HMENU)ID_BUTTON_BROWSE, ghinst, NULL); SetWindowFont(gHwndButtonBrowseDir, gFontDefault, TRUE); rc.y += 2 * staticDy; ScopedMem<WCHAR> defaultViewer(GetDefaultPdfViewer()); BOOL hasOtherViewer = !str::EqI(defaultViewer, APP_NAME_STR); BOOL isSumatraDefaultViewer = defaultViewer && !hasOtherViewer; // only show the checbox if Sumatra is not already a default viewer. // the alternative (disabling the checkbox) is more confusing if (!isSumatraDefaultViewer) { gHwndCheckboxRegisterDefault = CreateWindow( WC_BUTTON, _TR("Use SumatraPDF as the &default PDF reader"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_MAKE_DEFAULT, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterDefault, gFontDefault, TRUE); // only check the "Use as default" checkbox when no other PDF viewer // is currently selected (not going to intrude) Button_SetCheck(gHwndCheckboxRegisterDefault, !hasOtherViewer || gGlobalData.registerAsDefault); rc.y += staticDy; } gHwndCheckboxRegisterBrowserPlugin = CreateWindow( WC_BUTTON, _TR("Install PDF &browser plugin for Firefox, Chrome and Opera"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_BROWSER_PLUGIN, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterBrowserPlugin, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterBrowserPlugin, gGlobalData.installBrowserPlugin || IsBrowserPluginInstalled()); rc.y += staticDy; // only show this checkbox if the CPU arch of DLL and OS match // (assuming that the installer has the same CPU arch as its content!) #ifndef _WIN64 if (!IsRunningInWow64()) #endif { gHwndCheckboxRegisterPdfFilter = CreateWindow( WC_BUTTON, _TR("Let Windows Desktop Search &search PDF documents"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_PDF_FILTER, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterPdfFilter, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterPdfFilter, gGlobalData.installPdfFilter || IsPdfFilterInstalled()); rc.y += staticDy; } // for Windows XP, this means only basic thumbnail support gHwndCheckboxRegisterPdfPreviewer = CreateWindow( WC_BUTTON, _TR("Let Windows show &previews of PDF documents"), WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP, rc.x, rc.y, r.dx - 2 * rc.x, staticDy, hwnd, (HMENU)ID_CHECKBOX_PDF_PREVIEWER, ghinst, NULL); SetWindowFont(gHwndCheckboxRegisterPdfPreviewer, gFontDefault, TRUE); Button_SetCheck(gHwndCheckboxRegisterPdfPreviewer, gGlobalData.installPdfPreviewer || IsPdfPreviewerInstalled()); rc.y += staticDy; gShowOptions = !gShowOptions; OnButtonOptions(); SetFocus(gHwndButtonInstUninst); }