1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/embedding/components/printingui/src/win/nsPrintDialogUtil.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1081 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* ------------------------------------------------------------------- 1.10 +To Build This: 1.11 + 1.12 + You need to add this to the the makefile.win in mozilla/content/base/src: 1.13 + 1.14 + .\$(OBJDIR)\nsFlyOwnPrintDialog.obj \ 1.15 + 1.16 + 1.17 + And this to the makefile.win in mozilla/content/build: 1.18 + 1.19 +WIN_LIBS= \ 1.20 + winspool.lib \ 1.21 + comctl32.lib \ 1.22 + comdlg32.lib 1.23 + 1.24 +---------------------------------------------------------------------- */ 1.25 + 1.26 +#define NOMINMAX 1 1.27 + 1.28 +#include "plstr.h" 1.29 +#include <windows.h> 1.30 +#include <tchar.h> 1.31 + 1.32 +#include <unknwn.h> 1.33 +#include <commdlg.h> 1.34 + 1.35 +#include "nsIWebBrowserPrint.h" 1.36 +#include "nsString.h" 1.37 +#include "nsIServiceManager.h" 1.38 +#include "nsReadableUtils.h" 1.39 +#include "nsIPrintSettings.h" 1.40 +#include "nsIPrintSettingsWin.h" 1.41 +#include "nsIPrintOptions.h" 1.42 + 1.43 +#include "nsRect.h" 1.44 + 1.45 +#include "nsIPrefService.h" 1.46 +#include "nsIPrefBranch.h" 1.47 + 1.48 +#include "nsCRT.h" 1.49 +#include "prenv.h" /* for PR_GetEnv */ 1.50 + 1.51 +#include <windows.h> 1.52 +#include <winspool.h> 1.53 + 1.54 +// For Localization 1.55 +#include "nsIStringBundle.h" 1.56 + 1.57 +// For NS_CopyUnicodeToNative 1.58 +#include "nsNativeCharsetUtils.h" 1.59 + 1.60 +// This is for extending the dialog 1.61 +#include <dlgs.h> 1.62 + 1.63 +// Default labels for the radio buttons 1.64 +static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen"; 1.65 +static const char* kTheSelectedFrameStr = "The selected &frame"; 1.66 +static const char* kEachFrameSeparately = "&Each frame separately"; 1.67 + 1.68 + 1.69 +//----------------------------------------------- 1.70 +// Global Data 1.71 +//----------------------------------------------- 1.72 +// Identifies which new radio btn was cliked on 1.73 +static UINT gFrameSelectedRadioBtn = 0; 1.74 + 1.75 +// Indicates whether the native print dialog was successfully extended 1.76 +static bool gDialogWasExtended = false; 1.77 + 1.78 +#define PRINTDLG_PROPERTIES "chrome://global/locale/printdialog.properties" 1.79 + 1.80 +static HWND gParentWnd = nullptr; 1.81 + 1.82 +//****************************************************** 1.83 +// Define native paper sizes 1.84 +//****************************************************** 1.85 +typedef struct { 1.86 + short mPaperSize; // native enum 1.87 + double mWidth; 1.88 + double mHeight; 1.89 + bool mIsInches; 1.90 +} NativePaperSizes; 1.91 + 1.92 +// There are around 40 default print sizes defined by Windows 1.93 +const NativePaperSizes kPaperSizes[] = { 1.94 + {DMPAPER_LETTER, 8.5, 11.0, true}, 1.95 + {DMPAPER_LEGAL, 8.5, 14.0, true}, 1.96 + {DMPAPER_A4, 210.0, 297.0, false}, 1.97 + {DMPAPER_TABLOID, 11.0, 17.0, true}, 1.98 + {DMPAPER_LEDGER, 17.0, 11.0, true}, 1.99 + {DMPAPER_STATEMENT, 5.5, 8.5, true}, 1.100 + {DMPAPER_EXECUTIVE, 7.25, 10.5, true}, 1.101 + {DMPAPER_A3, 297.0, 420.0, false}, 1.102 + {DMPAPER_A5, 148.0, 210.0, false}, 1.103 + {DMPAPER_CSHEET, 17.0, 22.0, true}, 1.104 + {DMPAPER_DSHEET, 22.0, 34.0, true}, 1.105 + {DMPAPER_ESHEET, 34.0, 44.0, true}, 1.106 + {DMPAPER_LETTERSMALL, 8.5, 11.0, true}, 1.107 + {DMPAPER_A4SMALL, 210.0, 297.0, false}, 1.108 + {DMPAPER_B4, 250.0, 354.0, false}, 1.109 + {DMPAPER_B5, 182.0, 257.0, false}, 1.110 + {DMPAPER_FOLIO, 8.5, 13.0, true}, 1.111 + {DMPAPER_QUARTO, 215.0, 275.0, false}, 1.112 + {DMPAPER_10X14, 10.0, 14.0, true}, 1.113 + {DMPAPER_11X17, 11.0, 17.0, true}, 1.114 + {DMPAPER_NOTE, 8.5, 11.0, true}, 1.115 + {DMPAPER_ENV_9, 3.875, 8.875, true}, 1.116 + {DMPAPER_ENV_10, 40.125, 9.5, true}, 1.117 + {DMPAPER_ENV_11, 4.5, 10.375, true}, 1.118 + {DMPAPER_ENV_12, 4.75, 11.0, true}, 1.119 + {DMPAPER_ENV_14, 5.0, 11.5, true}, 1.120 + {DMPAPER_ENV_DL, 110.0, 220.0, false}, 1.121 + {DMPAPER_ENV_C5, 162.0, 229.0, false}, 1.122 + {DMPAPER_ENV_C3, 324.0, 458.0, false}, 1.123 + {DMPAPER_ENV_C4, 229.0, 324.0, false}, 1.124 + {DMPAPER_ENV_C6, 114.0, 162.0, false}, 1.125 + {DMPAPER_ENV_C65, 114.0, 229.0, false}, 1.126 + {DMPAPER_ENV_B4, 250.0, 353.0, false}, 1.127 + {DMPAPER_ENV_B5, 176.0, 250.0, false}, 1.128 + {DMPAPER_ENV_B6, 176.0, 125.0, false}, 1.129 + {DMPAPER_ENV_ITALY, 110.0, 230.0, false}, 1.130 + {DMPAPER_ENV_MONARCH, 3.875, 7.5, true}, 1.131 + {DMPAPER_ENV_PERSONAL, 3.625, 6.5, true}, 1.132 + {DMPAPER_FANFOLD_US, 14.875, 11.0, true}, 1.133 + {DMPAPER_FANFOLD_STD_GERMAN, 8.5, 12.0, true}, 1.134 + {DMPAPER_FANFOLD_LGL_GERMAN, 8.5, 13.0, true}, 1.135 +}; 1.136 +const int32_t kNumPaperSizes = 41; 1.137 + 1.138 +//---------------------------------------------------------------------------------- 1.139 +// Map an incoming size to a Windows Native enum in the DevMode 1.140 +static void 1.141 +MapPaperSizeToNativeEnum(LPDEVMODEW aDevMode, 1.142 + int16_t aType, 1.143 + double aW, 1.144 + double aH) 1.145 +{ 1.146 + 1.147 +#ifdef DEBUG_rods 1.148 + BOOL doingOrientation = aDevMode->dmFields & DM_ORIENTATION; 1.149 + BOOL doingPaperSize = aDevMode->dmFields & DM_PAPERSIZE; 1.150 + BOOL doingPaperLength = aDevMode->dmFields & DM_PAPERLENGTH; 1.151 + BOOL doingPaperWidth = aDevMode->dmFields & DM_PAPERWIDTH; 1.152 +#endif 1.153 + 1.154 + const double kThreshold = 0.05; 1.155 + for (int32_t i=0;i<kNumPaperSizes;i++) { 1.156 + double width = kPaperSizes[i].mWidth; 1.157 + double height = kPaperSizes[i].mHeight; 1.158 + if (aW < width+kThreshold && aW > width-kThreshold && 1.159 + aH < height+kThreshold && aH > height-kThreshold) { 1.160 + aDevMode->dmPaperSize = kPaperSizes[i].mPaperSize; 1.161 + aDevMode->dmFields &= ~DM_PAPERLENGTH; 1.162 + aDevMode->dmFields &= ~DM_PAPERWIDTH; 1.163 + aDevMode->dmFields |= DM_PAPERSIZE; 1.164 + return; 1.165 + } 1.166 + } 1.167 + 1.168 + short width = 0; 1.169 + short height = 0; 1.170 + if (aType == nsIPrintSettings::kPaperSizeInches) { 1.171 + width = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aW))) / 10); 1.172 + height = short(NS_TWIPS_TO_MILLIMETERS(NS_INCHES_TO_TWIPS(float(aH))) / 10); 1.173 + 1.174 + } else if (aType == nsIPrintSettings::kPaperSizeMillimeters) { 1.175 + width = short(aW / 10.0); 1.176 + height = short(aH / 10.0); 1.177 + } else { 1.178 + return; // don't set anything 1.179 + } 1.180 + 1.181 + // width and height is in 1.182 + aDevMode->dmPaperSize = 0; 1.183 + aDevMode->dmPaperWidth = width; 1.184 + aDevMode->dmPaperLength = height; 1.185 + 1.186 + aDevMode->dmFields |= DM_PAPERSIZE; 1.187 + aDevMode->dmFields |= DM_PAPERLENGTH; 1.188 + aDevMode->dmFields |= DM_PAPERWIDTH; 1.189 +} 1.190 + 1.191 +//---------------------------------------------------------------------------------- 1.192 +// Setup Paper Size & Orientation options into the DevMode 1.193 +// 1.194 +static void 1.195 +SetupDevModeFromSettings(LPDEVMODEW aDevMode, nsIPrintSettings* aPrintSettings) 1.196 +{ 1.197 + // Setup paper size 1.198 + if (aPrintSettings) { 1.199 + int16_t type; 1.200 + aPrintSettings->GetPaperSizeType(&type); 1.201 + if (type == nsIPrintSettings::kPaperSizeNativeData) { 1.202 + int16_t paperEnum; 1.203 + aPrintSettings->GetPaperData(&paperEnum); 1.204 + aDevMode->dmPaperSize = paperEnum; 1.205 + aDevMode->dmFields &= ~DM_PAPERLENGTH; 1.206 + aDevMode->dmFields &= ~DM_PAPERWIDTH; 1.207 + aDevMode->dmFields |= DM_PAPERSIZE; 1.208 + } else { 1.209 + int16_t unit; 1.210 + double width, height; 1.211 + aPrintSettings->GetPaperSizeUnit(&unit); 1.212 + aPrintSettings->GetPaperWidth(&width); 1.213 + aPrintSettings->GetPaperHeight(&height); 1.214 + MapPaperSizeToNativeEnum(aDevMode, unit, width, height); 1.215 + } 1.216 + 1.217 + // Setup Orientation 1.218 + int32_t orientation; 1.219 + aPrintSettings->GetOrientation(&orientation); 1.220 + aDevMode->dmOrientation = orientation == nsIPrintSettings::kPortraitOrientation?DMORIENT_PORTRAIT:DMORIENT_LANDSCAPE; 1.221 + aDevMode->dmFields |= DM_ORIENTATION; 1.222 + 1.223 + // Setup Number of Copies 1.224 + int32_t copies; 1.225 + aPrintSettings->GetNumCopies(&copies); 1.226 + aDevMode->dmCopies = copies; 1.227 + aDevMode->dmFields |= DM_COPIES; 1.228 + 1.229 + } 1.230 + 1.231 +} 1.232 + 1.233 +//---------------------------------------------------------------------------------- 1.234 +// Helper Function - Free and reallocate the string 1.235 +static nsresult 1.236 +SetPrintSettingsFromDevMode(nsIPrintSettings* aPrintSettings, 1.237 + LPDEVMODEW aDevMode) 1.238 +{ 1.239 + if (aPrintSettings == nullptr) { 1.240 + return NS_ERROR_FAILURE; 1.241 + } 1.242 + 1.243 + aPrintSettings->SetIsInitializedFromPrinter(true); 1.244 + if (aDevMode->dmFields & DM_ORIENTATION) { 1.245 + int32_t orientation = aDevMode->dmOrientation == DMORIENT_PORTRAIT? 1.246 + nsIPrintSettings::kPortraitOrientation:nsIPrintSettings::kLandscapeOrientation; 1.247 + aPrintSettings->SetOrientation(orientation); 1.248 + } 1.249 + 1.250 + // Setup Number of Copies 1.251 + if (aDevMode->dmFields & DM_COPIES) { 1.252 + aPrintSettings->SetNumCopies(int32_t(aDevMode->dmCopies)); 1.253 + } 1.254 + 1.255 + // Scaling 1.256 + // Since we do the scaling, grab their value and reset back to 100 1.257 + if (aDevMode->dmFields & DM_SCALE) { 1.258 + double origScale = 1.0; 1.259 + aPrintSettings->GetScaling(&origScale); 1.260 + double scale = double(aDevMode->dmScale) / 100.0f; 1.261 + if (origScale == 1.0 || scale != 1.0) { 1.262 + aPrintSettings->SetScaling(scale); 1.263 + } 1.264 + aDevMode->dmScale = 100; 1.265 + // To turn this on you must change where the mPrt->mShrinkToFit is being set in the DocumentViewer 1.266 + //aPrintSettings->SetShrinkToFit(false); 1.267 + } 1.268 + 1.269 + if (aDevMode->dmFields & DM_PAPERSIZE) { 1.270 + aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeNativeData); 1.271 + aPrintSettings->SetPaperData(aDevMode->dmPaperSize); 1.272 + for (int32_t i=0;i<kNumPaperSizes;i++) { 1.273 + if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) { 1.274 + aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches?nsIPrintSettings::kPaperSizeInches:nsIPrintSettings::kPaperSizeMillimeters); 1.275 + break; 1.276 + } 1.277 + } 1.278 + 1.279 + } else if (aDevMode->dmFields & DM_PAPERLENGTH && aDevMode->dmFields & DM_PAPERWIDTH) { 1.280 + bool found = false; 1.281 + for (int32_t i=0;i<kNumPaperSizes;i++) { 1.282 + if (kPaperSizes[i].mPaperSize == aDevMode->dmPaperSize) { 1.283 + aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined); 1.284 + aPrintSettings->SetPaperWidth(kPaperSizes[i].mWidth); 1.285 + aPrintSettings->SetPaperHeight(kPaperSizes[i].mHeight); 1.286 + aPrintSettings->SetPaperSizeUnit(kPaperSizes[i].mIsInches?nsIPrintSettings::kPaperSizeInches:nsIPrintSettings::kPaperSizeMillimeters); 1.287 + found = true; 1.288 + break; 1.289 + } 1.290 + } 1.291 + if (!found) { 1.292 + return NS_ERROR_FAILURE; 1.293 + } 1.294 + } else { 1.295 + return NS_ERROR_FAILURE; 1.296 + } 1.297 + return NS_OK; 1.298 +} 1.299 + 1.300 +//---------------------------------------------------------------------------------- 1.301 +// Return localized bundle for resource strings 1.302 +static nsresult 1.303 +GetLocalizedBundle(const char * aPropFileName, nsIStringBundle** aStrBundle) 1.304 +{ 1.305 + NS_ENSURE_ARG_POINTER(aPropFileName); 1.306 + NS_ENSURE_ARG_POINTER(aStrBundle); 1.307 + 1.308 + nsresult rv; 1.309 + nsCOMPtr<nsIStringBundle> bundle; 1.310 + 1.311 + 1.312 + // Create bundle 1.313 + nsCOMPtr<nsIStringBundleService> stringService = 1.314 + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); 1.315 + if (NS_SUCCEEDED(rv) && stringService) { 1.316 + rv = stringService->CreateBundle(aPropFileName, aStrBundle); 1.317 + } 1.318 + 1.319 + return rv; 1.320 +} 1.321 + 1.322 +//-------------------------------------------------------- 1.323 +// Return localized string 1.324 +static nsresult 1.325 +GetLocalizedString(nsIStringBundle* aStrBundle, const char* aKey, nsString& oVal) 1.326 +{ 1.327 + NS_ENSURE_ARG_POINTER(aStrBundle); 1.328 + NS_ENSURE_ARG_POINTER(aKey); 1.329 + 1.330 + // Determine default label from string bundle 1.331 + nsXPIDLString valUni; 1.332 + nsAutoString key; 1.333 + key.AssignWithConversion(aKey); 1.334 + nsresult rv = aStrBundle->GetStringFromName(key.get(), getter_Copies(valUni)); 1.335 + if (NS_SUCCEEDED(rv) && valUni) { 1.336 + oVal.Assign(valUni); 1.337 + } else { 1.338 + oVal.Truncate(); 1.339 + } 1.340 + return rv; 1.341 +} 1.342 + 1.343 +//-------------------------------------------------------- 1.344 +// Set a multi-byte string in the control 1.345 +static void SetTextOnWnd(HWND aControl, const nsString& aStr) 1.346 +{ 1.347 + nsAutoCString text; 1.348 + if (NS_SUCCEEDED(NS_CopyUnicodeToNative(aStr, text))) { 1.349 + ::SetWindowText(aControl, text.get()); 1.350 + } 1.351 +} 1.352 + 1.353 +//-------------------------------------------------------- 1.354 +// Will get the control and localized string by "key" 1.355 +static void SetText(HWND aParent, 1.356 + UINT aId, 1.357 + nsIStringBundle* aStrBundle, 1.358 + const char* aKey) 1.359 +{ 1.360 + HWND wnd = GetDlgItem (aParent, aId); 1.361 + if (!wnd) { 1.362 + return; 1.363 + } 1.364 + nsAutoString str; 1.365 + nsresult rv = GetLocalizedString(aStrBundle, aKey, str); 1.366 + if (NS_SUCCEEDED(rv)) { 1.367 + SetTextOnWnd(wnd, str); 1.368 + } 1.369 +} 1.370 + 1.371 +//-------------------------------------------------------- 1.372 +static void SetRadio(HWND aParent, 1.373 + UINT aId, 1.374 + bool aIsSet, 1.375 + bool isEnabled = true) 1.376 +{ 1.377 + HWND wnd = ::GetDlgItem (aParent, aId); 1.378 + if (!wnd) { 1.379 + return; 1.380 + } 1.381 + if (!isEnabled) { 1.382 + ::EnableWindow(wnd, FALSE); 1.383 + return; 1.384 + } 1.385 + ::EnableWindow(wnd, TRUE); 1.386 + ::SendMessage(wnd, BM_SETCHECK, (WPARAM)aIsSet, (LPARAM)0); 1.387 +} 1.388 + 1.389 +//-------------------------------------------------------- 1.390 +static void SetRadioOfGroup(HWND aDlg, int aRadId) 1.391 +{ 1.392 + int radioIds[] = {rad4, rad5, rad6}; 1.393 + int numRads = 3; 1.394 + 1.395 + for (int i=0;i<numRads;i++) { 1.396 + HWND radWnd = ::GetDlgItem(aDlg, radioIds[i]); 1.397 + if (radWnd != nullptr) { 1.398 + ::SendMessage(radWnd, BM_SETCHECK, (WPARAM)(radioIds[i] == aRadId), (LPARAM)0); 1.399 + } 1.400 + } 1.401 +} 1.402 + 1.403 +//-------------------------------------------------------- 1.404 +typedef struct { 1.405 + const char * mKeyStr; 1.406 + long mKeyId; 1.407 +} PropKeyInfo; 1.408 + 1.409 +// These are the control ids used in the dialog and 1.410 +// defined by MS-Windows in commdlg.h 1.411 +static PropKeyInfo gAllPropKeys[] = { 1.412 + {"printFramesTitleWindows", grp3}, 1.413 + {"asLaidOutWindows", rad4}, 1.414 + {"selectedFrameWindows", rad5}, 1.415 + {"separateFramesWindows", rad6}, 1.416 + {nullptr, 0}}; 1.417 + 1.418 +//-------------------------------------------------------- 1.419 +//-------------------------------------------------------- 1.420 +//-------------------------------------------------------- 1.421 +//-------------------------------------------------------- 1.422 +// Get the absolute coords of the child windows relative 1.423 +// to its parent window 1.424 +static void GetLocalRect(HWND aWnd, RECT& aRect, HWND aParent) 1.425 +{ 1.426 + ::GetWindowRect(aWnd, &aRect); 1.427 + 1.428 + // MapWindowPoints converts screen coordinates to client coordinates. 1.429 + // It works correctly in both left-to-right and right-to-left windows. 1.430 + ::MapWindowPoints(nullptr, aParent, (LPPOINT)&aRect, 2); 1.431 +} 1.432 + 1.433 +//-------------------------------------------------------- 1.434 +// Show or Hide the control 1.435 +static void Show(HWND aWnd, bool bState) 1.436 +{ 1.437 + if (aWnd) { 1.438 + ::ShowWindow(aWnd, bState?SW_SHOW:SW_HIDE); 1.439 + } 1.440 +} 1.441 + 1.442 +//-------------------------------------------------------- 1.443 +// Create a child window "control" 1.444 +static HWND CreateControl(LPCTSTR aType, 1.445 + DWORD aStyle, 1.446 + HINSTANCE aHInst, 1.447 + HWND aHdlg, 1.448 + int aId, 1.449 + const nsAString& aStr, 1.450 + const nsIntRect& aRect) 1.451 +{ 1.452 + nsAutoCString str; 1.453 + if (NS_FAILED(NS_CopyUnicodeToNative(aStr, str))) 1.454 + return nullptr; 1.455 + 1.456 + HWND hWnd = ::CreateWindow (aType, str.get(), 1.457 + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle, 1.458 + aRect.x, aRect.y, aRect.width, aRect.height, 1.459 + (HWND)aHdlg, (HMENU)(intptr_t)aId, 1.460 + aHInst, nullptr); 1.461 + if (hWnd == nullptr) return nullptr; 1.462 + 1.463 + // get the native font for the dialog and 1.464 + // set it into the new control 1.465 + HFONT hFont = (HFONT)::SendMessage(aHdlg, WM_GETFONT, (WPARAM)0, (LPARAM)0); 1.466 + if (hFont != nullptr) { 1.467 + ::SendMessage(hWnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0); 1.468 + } 1.469 + return hWnd; 1.470 +} 1.471 + 1.472 +//-------------------------------------------------------- 1.473 +// Create a Radio Button 1.474 +static HWND CreateRadioBtn(HINSTANCE aHInst, 1.475 + HWND aHdlg, 1.476 + int aId, 1.477 + const char* aStr, 1.478 + const nsIntRect& aRect) 1.479 +{ 1.480 + nsString cStr; 1.481 + cStr.AssignWithConversion(aStr); 1.482 + return CreateControl("BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, cStr, aRect); 1.483 +} 1.484 + 1.485 +//-------------------------------------------------------- 1.486 +// Create a Group Box 1.487 +static HWND CreateGroupBox(HINSTANCE aHInst, 1.488 + HWND aHdlg, 1.489 + int aId, 1.490 + const nsAString& aStr, 1.491 + const nsIntRect& aRect) 1.492 +{ 1.493 + return CreateControl("BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect); 1.494 +} 1.495 + 1.496 +//-------------------------------------------------------- 1.497 +// Localizes and initializes the radio buttons and group 1.498 +static void InitializeExtendedDialog(HWND hdlg, int16_t aHowToEnableFrameUI) 1.499 +{ 1.500 + NS_ABORT_IF_FALSE(aHowToEnableFrameUI != nsIPrintSettings::kFrameEnableNone, 1.501 + "should not be called"); 1.502 + 1.503 + // Localize the new controls in the print dialog 1.504 + nsCOMPtr<nsIStringBundle> strBundle; 1.505 + if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) { 1.506 + int32_t i = 0; 1.507 + while (gAllPropKeys[i].mKeyStr != nullptr) { 1.508 + SetText(hdlg, gAllPropKeys[i].mKeyId, strBundle, gAllPropKeys[i].mKeyStr); 1.509 + i++; 1.510 + } 1.511 + } 1.512 + 1.513 + // Set up radio buttons 1.514 + if (aHowToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) { 1.515 + SetRadio(hdlg, rad4, false); 1.516 + SetRadio(hdlg, rad5, true); 1.517 + SetRadio(hdlg, rad6, false); 1.518 + // set default so user doesn't have to actually press on it 1.519 + gFrameSelectedRadioBtn = rad5; 1.520 + 1.521 + } else { // nsIPrintSettings::kFrameEnableAsIsAndEach 1.522 + SetRadio(hdlg, rad4, false); 1.523 + SetRadio(hdlg, rad5, false, false); 1.524 + SetRadio(hdlg, rad6, true); 1.525 + // set default so user doesn't have to actually press on it 1.526 + gFrameSelectedRadioBtn = rad6; 1.527 + } 1.528 +} 1.529 + 1.530 + 1.531 +//-------------------------------------------------------- 1.532 +// Special Hook Procedure for handling the print dialog messages 1.533 +static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) 1.534 +{ 1.535 + 1.536 + if (uiMsg == WM_COMMAND) { 1.537 + UINT id = LOWORD(wParam); 1.538 + if (id == rad4 || id == rad5 || id == rad6) { 1.539 + gFrameSelectedRadioBtn = id; 1.540 + SetRadioOfGroup(hdlg, id); 1.541 + } 1.542 + 1.543 + } else if (uiMsg == WM_INITDIALOG) { 1.544 + PRINTDLG * printDlg = (PRINTDLG *)lParam; 1.545 + if (printDlg == nullptr) return 0L; 1.546 + 1.547 + int16_t howToEnableFrameUI = (int16_t)printDlg->lCustData; 1.548 + // don't add frame options if they would be disabled anyway 1.549 + // because there are no frames 1.550 + if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableNone) 1.551 + return TRUE; 1.552 + 1.553 + HINSTANCE hInst = (HINSTANCE)::GetWindowLongPtr(hdlg, GWLP_HINSTANCE); 1.554 + if (hInst == nullptr) return 0L; 1.555 + 1.556 + // Start by getting the local rects of several of the controls 1.557 + // so we can calculate where the new controls are 1.558 + HWND wnd = ::GetDlgItem(hdlg, grp1); 1.559 + if (wnd == nullptr) return 0L; 1.560 + RECT dlgRect; 1.561 + GetLocalRect(wnd, dlgRect, hdlg); 1.562 + 1.563 + wnd = ::GetDlgItem(hdlg, rad1); // this is the top control "All" 1.564 + if (wnd == nullptr) return 0L; 1.565 + RECT rad1Rect; 1.566 + GetLocalRect(wnd, rad1Rect, hdlg); 1.567 + 1.568 + wnd = ::GetDlgItem(hdlg, rad2); // this is the bottom control "Selection" 1.569 + if (wnd == nullptr) return 0L; 1.570 + RECT rad2Rect; 1.571 + GetLocalRect(wnd, rad2Rect, hdlg); 1.572 + 1.573 + wnd = ::GetDlgItem(hdlg, rad3); // this is the middle control "Pages" 1.574 + if (wnd == nullptr) return 0L; 1.575 + RECT rad3Rect; 1.576 + GetLocalRect(wnd, rad3Rect, hdlg); 1.577 + 1.578 + HWND okWnd = ::GetDlgItem(hdlg, IDOK); 1.579 + if (okWnd == nullptr) return 0L; 1.580 + RECT okRect; 1.581 + GetLocalRect(okWnd, okRect, hdlg); 1.582 + 1.583 + wnd = ::GetDlgItem(hdlg, grp4); // this is the "Print range" groupbox 1.584 + if (wnd == nullptr) return 0L; 1.585 + RECT prtRect; 1.586 + GetLocalRect(wnd, prtRect, hdlg); 1.587 + 1.588 + 1.589 + // calculate various different "gaps" for layout purposes 1.590 + 1.591 + int rbGap = rad3Rect.top - rad1Rect.bottom; // gap between radiobtns 1.592 + int grpBotGap = dlgRect.bottom - rad2Rect.bottom; // gap from bottom rb to bottom of grpbox 1.593 + int grpGap = dlgRect.top - prtRect.bottom ; // gap between group boxes 1.594 + int top = dlgRect.bottom + grpGap; 1.595 + int radHgt = rad1Rect.bottom - rad1Rect.top + 1; // top of new group box 1.596 + int y = top+(rad1Rect.top-dlgRect.top); // starting pos of first radio 1.597 + int rbWidth = dlgRect.right - rad1Rect.left - 5; // measure from rb left to the edge of the groupbox 1.598 + // (5 is arbitrary) 1.599 + nsIntRect rect; 1.600 + 1.601 + // Create and position the radio buttons 1.602 + // 1.603 + // If any one control cannot be created then 1.604 + // hide the others and bail out 1.605 + // 1.606 + rect.SetRect(rad1Rect.left, y, rbWidth,radHgt); 1.607 + HWND rad4Wnd = CreateRadioBtn(hInst, hdlg, rad4, kAsLaidOutOnScreenStr, rect); 1.608 + if (rad4Wnd == nullptr) return 0L; 1.609 + y += radHgt + rbGap; 1.610 + 1.611 + rect.SetRect(rad1Rect.left, y, rbWidth, radHgt); 1.612 + HWND rad5Wnd = CreateRadioBtn(hInst, hdlg, rad5, kTheSelectedFrameStr, rect); 1.613 + if (rad5Wnd == nullptr) { 1.614 + Show(rad4Wnd, FALSE); // hide 1.615 + return 0L; 1.616 + } 1.617 + y += radHgt + rbGap; 1.618 + 1.619 + rect.SetRect(rad1Rect.left, y, rbWidth, radHgt); 1.620 + HWND rad6Wnd = CreateRadioBtn(hInst, hdlg, rad6, kEachFrameSeparately, rect); 1.621 + if (rad6Wnd == nullptr) { 1.622 + Show(rad4Wnd, FALSE); // hide 1.623 + Show(rad5Wnd, FALSE); // hide 1.624 + return 0L; 1.625 + } 1.626 + y += radHgt + grpBotGap; 1.627 + 1.628 + // Create and position the group box 1.629 + rect.SetRect (dlgRect.left, top, dlgRect.right-dlgRect.left+1, y-top+1); 1.630 + HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, NS_LITERAL_STRING("Print Frame"), rect); 1.631 + if (grpBoxWnd == nullptr) { 1.632 + Show(rad4Wnd, FALSE); // hide 1.633 + Show(rad5Wnd, FALSE); // hide 1.634 + Show(rad6Wnd, FALSE); // hide 1.635 + return 0L; 1.636 + } 1.637 + 1.638 + // Here we figure out the old height of the dlg 1.639 + // then figure its gap from the old grpbx to the bottom 1.640 + // then size the dlg 1.641 + RECT pr, cr; 1.642 + ::GetWindowRect(hdlg, &pr); 1.643 + ::GetClientRect(hdlg, &cr); 1.644 + 1.645 + int dlgHgt = (cr.bottom - cr.top) + 1; 1.646 + int bottomGap = dlgHgt - okRect.bottom; 1.647 + pr.bottom += (dlgRect.bottom-dlgRect.top) + grpGap + 1 - (dlgHgt-dlgRect.bottom) + bottomGap; 1.648 + 1.649 + ::SetWindowPos(hdlg, nullptr, pr.left, pr.top, pr.right-pr.left+1, pr.bottom-pr.top+1, 1.650 + SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER); 1.651 + 1.652 + // figure out the new height of the dialog 1.653 + ::GetClientRect(hdlg, &cr); 1.654 + dlgHgt = (cr.bottom - cr.top) + 1; 1.655 + 1.656 + // Reposition the OK and Cancel btns 1.657 + int okHgt = okRect.bottom - okRect.top + 1; 1.658 + ::SetWindowPos(okWnd, nullptr, okRect.left, dlgHgt-bottomGap-okHgt, 0, 0, 1.659 + SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER); 1.660 + 1.661 + HWND cancelWnd = ::GetDlgItem(hdlg, IDCANCEL); 1.662 + if (cancelWnd == nullptr) return 0L; 1.663 + 1.664 + RECT cancelRect; 1.665 + GetLocalRect(cancelWnd, cancelRect, hdlg); 1.666 + int cancelHgt = cancelRect.bottom - cancelRect.top + 1; 1.667 + ::SetWindowPos(cancelWnd, nullptr, cancelRect.left, dlgHgt-bottomGap-cancelHgt, 0, 0, 1.668 + SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER); 1.669 + 1.670 + // localize and initialize the groupbox and radiobuttons 1.671 + InitializeExtendedDialog(hdlg, howToEnableFrameUI); 1.672 + 1.673 + // Looks like we were able to extend the dialog 1.674 + gDialogWasExtended = true; 1.675 + return TRUE; 1.676 + } 1.677 + return 0L; 1.678 +} 1.679 + 1.680 +//---------------------------------------------------------------------------------- 1.681 +// Returns a Global Moveable Memory Handle to a DevMode 1.682 +// from the Printer by the name of aPrintName 1.683 +// 1.684 +// NOTE: 1.685 +// This function assumes that aPrintName has already been converted from 1.686 +// unicode 1.687 +// 1.688 +static HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS) 1.689 +{ 1.690 + HGLOBAL hGlobalDevMode = nullptr; 1.691 + 1.692 + HANDLE hPrinter = nullptr; 1.693 + // const cast kludge for silly Win32 api's 1.694 + LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get())); 1.695 + BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr); 1.696 + if (status) { 1.697 + 1.698 + LPDEVMODEW pNewDevMode; 1.699 + DWORD dwNeeded, dwRet; 1.700 + 1.701 + // Get the buffer size 1.702 + dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr, nullptr, 0); 1.703 + if (dwNeeded == 0) { 1.704 + return nullptr; 1.705 + } 1.706 + 1.707 + // Allocate a buffer of the correct size. 1.708 + pNewDevMode = (LPDEVMODEW)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded); 1.709 + if (!pNewDevMode) return nullptr; 1.710 + 1.711 + hGlobalDevMode = (HGLOBAL)::GlobalAlloc(GHND, dwNeeded); 1.712 + if (!hGlobalDevMode) { 1.713 + ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); 1.714 + return nullptr; 1.715 + } 1.716 + 1.717 + dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, pNewDevMode, nullptr, DM_OUT_BUFFER); 1.718 + 1.719 + if (dwRet != IDOK) { 1.720 + ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); 1.721 + ::GlobalFree(hGlobalDevMode); 1.722 + ::ClosePrinter(hPrinter); 1.723 + return nullptr; 1.724 + } 1.725 + 1.726 + // Lock memory and copy contents from DEVMODE (current printer) 1.727 + // to Global Memory DEVMODE 1.728 + LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hGlobalDevMode); 1.729 + if (devMode) { 1.730 + memcpy(devMode, pNewDevMode, dwNeeded); 1.731 + // Initialize values from the PrintSettings 1.732 + SetupDevModeFromSettings(devMode, aPS); 1.733 + 1.734 + // Sets back the changes we made to the DevMode into the Printer Driver 1.735 + dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER); 1.736 + if (dwRet != IDOK) { 1.737 + ::GlobalUnlock(hGlobalDevMode); 1.738 + ::GlobalFree(hGlobalDevMode); 1.739 + ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); 1.740 + ::ClosePrinter(hPrinter); 1.741 + return nullptr; 1.742 + } 1.743 + 1.744 + ::GlobalUnlock(hGlobalDevMode); 1.745 + } else { 1.746 + ::GlobalFree(hGlobalDevMode); 1.747 + hGlobalDevMode = nullptr; 1.748 + } 1.749 + 1.750 + ::HeapFree(::GetProcessHeap(), 0, pNewDevMode); 1.751 + 1.752 + ::ClosePrinter(hPrinter); 1.753 + 1.754 + } else { 1.755 + return nullptr; 1.756 + } 1.757 + 1.758 + return hGlobalDevMode; 1.759 +} 1.760 + 1.761 +//------------------------------------------------------------------ 1.762 +// helper 1.763 +static void GetDefaultPrinterNameFromGlobalPrinters(nsXPIDLString &printerName) 1.764 +{ 1.765 + nsCOMPtr<nsIPrinterEnumerator> prtEnum = do_GetService("@mozilla.org/gfx/printerenumerator;1"); 1.766 + if (prtEnum) { 1.767 + prtEnum->GetDefaultPrinterName(getter_Copies(printerName)); 1.768 + } 1.769 +} 1.770 + 1.771 +// Determine whether we have a completely native dialog 1.772 +// or whether we cshould extend it 1.773 +static bool ShouldExtendPrintDialog() 1.774 +{ 1.775 + nsresult rv; 1.776 + nsCOMPtr<nsIPrefService> prefs = 1.777 + do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); 1.778 + NS_ENSURE_SUCCESS(rv, true); 1.779 + nsCOMPtr<nsIPrefBranch> prefBranch; 1.780 + rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch)); 1.781 + NS_ENSURE_SUCCESS(rv, true); 1.782 + 1.783 + bool result; 1.784 + rv = prefBranch->GetBoolPref("print.extend_native_print_dialog", &result); 1.785 + NS_ENSURE_SUCCESS(rv, true); 1.786 + return result; 1.787 +} 1.788 + 1.789 +//------------------------------------------------------------------ 1.790 +// Displays the native Print Dialog 1.791 +static nsresult 1.792 +ShowNativePrintDialog(HWND aHWnd, 1.793 + nsIPrintSettings* aPrintSettings) 1.794 +{ 1.795 + //NS_ENSURE_ARG_POINTER(aHWnd); 1.796 + NS_ENSURE_ARG_POINTER(aPrintSettings); 1.797 + 1.798 + gDialogWasExtended = false; 1.799 + 1.800 + HGLOBAL hGlobalDevMode = nullptr; 1.801 + HGLOBAL hDevNames = nullptr; 1.802 + 1.803 + // Get the Print Name to be used 1.804 + nsXPIDLString printerName; 1.805 + aPrintSettings->GetPrinterName(getter_Copies(printerName)); 1.806 + 1.807 + // If there is no name then use the default printer 1.808 + if (printerName.IsEmpty()) { 1.809 + GetDefaultPrinterNameFromGlobalPrinters(printerName); 1.810 + } else { 1.811 + HANDLE hPrinter = nullptr; 1.812 + if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())), &hPrinter, nullptr)) { 1.813 + // If the last used printer is not found, we should use default printer. 1.814 + GetDefaultPrinterNameFromGlobalPrinters(printerName); 1.815 + } else { 1.816 + ::ClosePrinter(hPrinter); 1.817 + } 1.818 + } 1.819 + 1.820 + // Now create a DEVNAMES struct so the the dialog is initialized correctly. 1.821 + 1.822 + uint32_t len = printerName.Length(); 1.823 + hDevNames = (HGLOBAL)::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1) + 1.824 + sizeof(DEVNAMES)); 1.825 + if (!hDevNames) { 1.826 + return NS_ERROR_OUT_OF_MEMORY; 1.827 + } 1.828 + 1.829 + DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames); 1.830 + if (!pDevNames) { 1.831 + ::GlobalFree(hDevNames); 1.832 + return NS_ERROR_FAILURE; 1.833 + } 1.834 + pDevNames->wDriverOffset = sizeof(DEVNAMES)/sizeof(wchar_t); 1.835 + pDevNames->wDeviceOffset = sizeof(DEVNAMES)/sizeof(wchar_t); 1.836 + pDevNames->wOutputOffset = sizeof(DEVNAMES)/sizeof(wchar_t)+len; 1.837 + pDevNames->wDefault = 0; 1.838 + 1.839 + memcpy(pDevNames+1, printerName, (len + 1) * sizeof(wchar_t)); 1.840 + ::GlobalUnlock(hDevNames); 1.841 + 1.842 + // Create a Moveable Memory Object that holds a new DevMode 1.843 + // from the Printer Name 1.844 + // The PRINTDLG.hDevMode requires that it be a moveable memory object 1.845 + // NOTE: We only need to free hGlobalDevMode when the dialog is cancelled 1.846 + // When the user prints, it comes back in the printdlg struct and 1.847 + // is used and cleaned up later 1.848 + hGlobalDevMode = CreateGlobalDevModeAndInit(printerName, aPrintSettings); 1.849 + 1.850 + // Prepare to Display the Print Dialog 1.851 + PRINTDLGW prntdlg; 1.852 + memset(&prntdlg, 0, sizeof(PRINTDLGW)); 1.853 + 1.854 + prntdlg.lStructSize = sizeof(prntdlg); 1.855 + prntdlg.hwndOwner = aHWnd; 1.856 + prntdlg.hDevMode = hGlobalDevMode; 1.857 + prntdlg.hDevNames = hDevNames; 1.858 + prntdlg.hDC = nullptr; 1.859 + prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC | 1.860 + PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE; 1.861 + 1.862 + // if there is a current selection then enable the "Selection" radio button 1.863 + int16_t howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone; 1.864 + bool isOn; 1.865 + aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn); 1.866 + if (!isOn) { 1.867 + prntdlg.Flags |= PD_NOSELECTION; 1.868 + } 1.869 + aPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI); 1.870 + 1.871 + int32_t pg = 1; 1.872 + aPrintSettings->GetStartPageRange(&pg); 1.873 + prntdlg.nFromPage = pg; 1.874 + 1.875 + aPrintSettings->GetEndPageRange(&pg); 1.876 + prntdlg.nToPage = pg; 1.877 + 1.878 + prntdlg.nMinPage = 1; 1.879 + prntdlg.nMaxPage = 0xFFFF; 1.880 + prntdlg.nCopies = 1; 1.881 + prntdlg.lpfnSetupHook = nullptr; 1.882 + prntdlg.lpSetupTemplateName = nullptr; 1.883 + prntdlg.hPrintTemplate = nullptr; 1.884 + prntdlg.hSetupTemplate = nullptr; 1.885 + 1.886 + prntdlg.hInstance = nullptr; 1.887 + prntdlg.lpPrintTemplateName = nullptr; 1.888 + 1.889 + if (!ShouldExtendPrintDialog()) { 1.890 + prntdlg.lCustData = 0; 1.891 + prntdlg.lpfnPrintHook = nullptr; 1.892 + } else { 1.893 + // Set up print dialog "hook" procedure for extending the dialog 1.894 + prntdlg.lCustData = (DWORD)howToEnableFrameUI; 1.895 + prntdlg.lpfnPrintHook = (LPPRINTHOOKPROC)PrintHookProc; 1.896 + prntdlg.Flags |= PD_ENABLEPRINTHOOK; 1.897 + } 1.898 + 1.899 + BOOL result = ::PrintDlgW(&prntdlg); 1.900 + 1.901 + if (TRUE == result) { 1.902 + // check to make sure we don't have any nullptr pointers 1.903 + NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE); 1.904 + 1.905 + if (prntdlg.hDevNames == nullptr) { 1.906 + ::GlobalFree(hGlobalDevMode); 1.907 + return NS_ERROR_FAILURE; 1.908 + } 1.909 + // Lock the deviceNames and check for nullptr 1.910 + DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames); 1.911 + if (devnames == nullptr) { 1.912 + ::GlobalFree(hGlobalDevMode); 1.913 + return NS_ERROR_FAILURE; 1.914 + } 1.915 + 1.916 + char16_t* device = &(((char16_t *)devnames)[devnames->wDeviceOffset]); 1.917 + char16_t* driver = &(((char16_t *)devnames)[devnames->wDriverOffset]); 1.918 + 1.919 + // Check to see if the "Print To File" control is checked 1.920 + // then take the name from devNames and set it in the PrintSettings 1.921 + // 1.922 + // NOTE: 1.923 + // As per Microsoft SDK documentation the returned value offset from 1.924 + // devnames->wOutputOffset is either "FILE:" or nullptr 1.925 + // if the "Print To File" checkbox is checked it MUST be "FILE:" 1.926 + // We assert as an extra safety check. 1.927 + if (prntdlg.Flags & PD_PRINTTOFILE) { 1.928 + char16ptr_t fileName = &(((wchar_t *)devnames)[devnames->wOutputOffset]); 1.929 + NS_ASSERTION(wcscmp(fileName, L"FILE:") == 0, "FileName must be `FILE:`"); 1.930 + aPrintSettings->SetToFileName(fileName); 1.931 + aPrintSettings->SetPrintToFile(true); 1.932 + } else { 1.933 + // clear "print to file" info 1.934 + aPrintSettings->SetPrintToFile(false); 1.935 + aPrintSettings->SetToFileName(nullptr); 1.936 + } 1.937 + 1.938 + nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings)); 1.939 + if (!psWin) { 1.940 + ::GlobalFree(hGlobalDevMode); 1.941 + return NS_ERROR_FAILURE; 1.942 + } 1.943 + 1.944 + // Setup local Data members 1.945 + psWin->SetDeviceName(device); 1.946 + psWin->SetDriverName(driver); 1.947 + 1.948 +#if defined(DEBUG_rods) || defined(DEBUG_dcone) 1.949 + wprintf(L"printer: driver %s, device %s flags: %d\n", driver, device, prntdlg.Flags); 1.950 +#endif 1.951 + // fill the print options with the info from the dialog 1.952 + 1.953 + aPrintSettings->SetPrinterName(device); 1.954 + 1.955 + if (prntdlg.Flags & PD_SELECTION) { 1.956 + aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection); 1.957 + 1.958 + } else if (prntdlg.Flags & PD_PAGENUMS) { 1.959 + aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange); 1.960 + aPrintSettings->SetStartPageRange(prntdlg.nFromPage); 1.961 + aPrintSettings->SetEndPageRange(prntdlg.nToPage); 1.962 + 1.963 + } else { // (prntdlg.Flags & PD_ALLPAGES) 1.964 + aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages); 1.965 + } 1.966 + 1.967 + if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) { 1.968 + // make sure the dialog got extended 1.969 + if (gDialogWasExtended) { 1.970 + // check to see about the frame radio buttons 1.971 + switch (gFrameSelectedRadioBtn) { 1.972 + case rad4: 1.973 + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs); 1.974 + break; 1.975 + case rad5: 1.976 + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame); 1.977 + break; 1.978 + case rad6: 1.979 + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep); 1.980 + break; 1.981 + } // switch 1.982 + } else { 1.983 + // if it didn't get extended then have it default to printing 1.984 + // each frame separately 1.985 + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep); 1.986 + } 1.987 + } else { 1.988 + aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames); 1.989 + } 1.990 + // Unlock DeviceNames 1.991 + ::GlobalUnlock(prntdlg.hDevNames); 1.992 + 1.993 + // Transfer the settings from the native data to the PrintSettings 1.994 + LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode); 1.995 + if (devMode == nullptr) { 1.996 + ::GlobalFree(hGlobalDevMode); 1.997 + return NS_ERROR_FAILURE; 1.998 + } 1.999 + psWin->SetDevMode(devMode); // copies DevMode 1.1000 + SetPrintSettingsFromDevMode(aPrintSettings, devMode); 1.1001 + ::GlobalUnlock(prntdlg.hDevMode); 1.1002 + 1.1003 +#if defined(DEBUG_rods) || defined(DEBUG_dcone) 1.1004 + bool printSelection = prntdlg.Flags & PD_SELECTION; 1.1005 + bool printAllPages = prntdlg.Flags & PD_ALLPAGES; 1.1006 + bool printNumPages = prntdlg.Flags & PD_PAGENUMS; 1.1007 + int32_t fromPageNum = 0; 1.1008 + int32_t toPageNum = 0; 1.1009 + 1.1010 + if (printNumPages) { 1.1011 + fromPageNum = prntdlg.nFromPage; 1.1012 + toPageNum = prntdlg.nToPage; 1.1013 + } 1.1014 + if (printSelection) { 1.1015 + printf("Printing the selection\n"); 1.1016 + 1.1017 + } else if (printAllPages) { 1.1018 + printf("Printing all the pages\n"); 1.1019 + 1.1020 + } else { 1.1021 + printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum); 1.1022 + } 1.1023 +#endif 1.1024 + 1.1025 + } else { 1.1026 + ::SetFocus(aHWnd); 1.1027 + aPrintSettings->SetIsCancelled(true); 1.1028 + if (hGlobalDevMode) ::GlobalFree(hGlobalDevMode); 1.1029 + return NS_ERROR_ABORT; 1.1030 + } 1.1031 + 1.1032 + return NS_OK; 1.1033 +} 1.1034 + 1.1035 +//------------------------------------------------------------------ 1.1036 +static void 1.1037 +PrepareForPrintDialog(nsIWebBrowserPrint* aWebBrowserPrint, nsIPrintSettings* aPS) 1.1038 +{ 1.1039 + NS_ASSERTION(aWebBrowserPrint, "Can't be null"); 1.1040 + NS_ASSERTION(aPS, "Can't be null"); 1.1041 + 1.1042 + bool isFramesetDocument; 1.1043 + bool isFramesetFrameSelected; 1.1044 + bool isIFrameSelected; 1.1045 + bool isRangeSelection; 1.1046 + 1.1047 + aWebBrowserPrint->GetIsFramesetDocument(&isFramesetDocument); 1.1048 + aWebBrowserPrint->GetIsFramesetFrameSelected(&isFramesetFrameSelected); 1.1049 + aWebBrowserPrint->GetIsIFrameSelected(&isIFrameSelected); 1.1050 + aWebBrowserPrint->GetIsRangeSelection(&isRangeSelection); 1.1051 + 1.1052 + // Setup print options for UI 1.1053 + if (isFramesetDocument) { 1.1054 + if (isFramesetFrameSelected) { 1.1055 + aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll); 1.1056 + } else { 1.1057 + aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach); 1.1058 + } 1.1059 + } else { 1.1060 + aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone); 1.1061 + } 1.1062 + 1.1063 + // Now determine how to set up the Frame print UI 1.1064 + aPS->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, isRangeSelection || isIFrameSelected); 1.1065 + 1.1066 +} 1.1067 + 1.1068 +//---------------------------------------------------------------------------------- 1.1069 +//-- Show Print Dialog 1.1070 +//---------------------------------------------------------------------------------- 1.1071 +nsresult NativeShowPrintDialog(HWND aHWnd, 1.1072 + nsIWebBrowserPrint* aWebBrowserPrint, 1.1073 + nsIPrintSettings* aPrintSettings) 1.1074 +{ 1.1075 + PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings); 1.1076 + 1.1077 + nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings); 1.1078 + if (aHWnd) { 1.1079 + ::DestroyWindow(aHWnd); 1.1080 + } 1.1081 + 1.1082 + return rv; 1.1083 +} 1.1084 +