2002-05-02 15:50:36 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
/* -------------------------------------------------------------------
|
|
|
|
To Build This:
|
|
|
|
|
2014-10-25 21:25:22 +04:00
|
|
|
You need to add this to the the makefile.win in mozilla/dom/base:
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
.\$(OBJDIR)\nsFlyOwnPrintDialog.obj \
|
|
|
|
|
|
|
|
|
|
|
|
And this to the makefile.win in mozilla/content/build:
|
|
|
|
|
|
|
|
WIN_LIBS= \
|
|
|
|
winspool.lib \
|
|
|
|
comctl32.lib \
|
|
|
|
comdlg32.lib
|
|
|
|
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
#include "plstr.h"
|
|
|
|
#include <windows.h>
|
2003-10-08 00:39:25 +04:00
|
|
|
#include <tchar.h>
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
#include <unknwn.h>
|
|
|
|
#include <commdlg.h>
|
|
|
|
|
2018-12-13 16:17:14 +03:00
|
|
|
#include "mozilla/BackgroundHangMonitor.h"
|
2002-05-02 15:50:36 +04:00
|
|
|
#include "nsIWebBrowserPrint.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsReadableUtils.h"
|
|
|
|
#include "nsIPrintSettings.h"
|
|
|
|
#include "nsIPrintSettingsWin.h"
|
2016-10-28 02:31:14 +03:00
|
|
|
#include "nsIPrinterEnumerator.h"
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
#include "nsRect.h"
|
|
|
|
|
2005-07-01 16:32:15 +04:00
|
|
|
#include "nsIPrefService.h"
|
|
|
|
#include "nsIPrefBranch.h"
|
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "prenv.h" /* for PR_GetEnv */
|
|
|
|
|
|
|
|
#include <windows.h>
|
2017-07-06 15:00:35 +03:00
|
|
|
#include <winspool.h>
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// For Localization
|
|
|
|
#include "nsIStringBundle.h"
|
|
|
|
|
2003-07-19 20:29:41 +04:00
|
|
|
// For NS_CopyUnicodeToNative
|
|
|
|
#include "nsNativeCharsetUtils.h"
|
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
// This is for extending the dialog
|
|
|
|
#include <dlgs.h>
|
|
|
|
|
2016-04-05 09:24:28 +03:00
|
|
|
#include "nsWindowsHelpers.h"
|
2016-07-02 01:58:31 +03:00
|
|
|
#include "WinUtils.h"
|
2016-04-05 09:24:28 +03:00
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
// Default labels for the radio buttons
|
2017-10-19 05:04:30 +03:00
|
|
|
static const wchar_t* kAsLaidOutOnScreenStr = L"As &laid out on the screen";
|
2017-10-19 05:04:50 +03:00
|
|
|
static const wchar_t* kTheSelectedFrameStr = L"The selected &frame";
|
|
|
|
static const wchar_t* kEachFrameSeparately = L"&Each frame separately";
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
// Global Data
|
|
|
|
//-----------------------------------------------
|
|
|
|
// Identifies which new radio btn was cliked on
|
|
|
|
static UINT gFrameSelectedRadioBtn = 0;
|
|
|
|
|
|
|
|
// Indicates whether the native print dialog was successfully extended
|
2017-10-19 05:04:50 +03:00
|
|
|
static bool gDialogWasExtended = false;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
#define PRINTDLG_PROPERTIES "chrome://global/locale/printdialog.properties"
|
|
|
|
|
2013-04-03 04:27:12 +04:00
|
|
|
static HWND gParentWnd = nullptr;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Return localized bundle for resource strings
|
2017-10-19 05:04:50 +03:00
|
|
|
static nsresult GetLocalizedBundle(const char* aPropFileName,
|
|
|
|
nsIStringBundle** aStrBundle) {
|
2002-05-02 15:50:36 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(aPropFileName);
|
|
|
|
NS_ENSURE_ARG_POINTER(aStrBundle);
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIStringBundle> bundle;
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
// Create bundle
|
2017-07-06 15:00:35 +03:00
|
|
|
nsCOMPtr<nsIStringBundleService> stringService =
|
2006-06-04 03:35:59 +04:00
|
|
|
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
2002-05-02 15:50:36 +04:00
|
|
|
if (NS_SUCCEEDED(rv) && stringService) {
|
|
|
|
rv = stringService->CreateBundle(aPropFileName, aStrBundle);
|
|
|
|
}
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2017-07-06 15:00:35 +03:00
|
|
|
// Return localized string
|
2017-10-19 05:04:50 +03:00
|
|
|
static nsresult GetLocalizedString(nsIStringBundle* aStrBundle,
|
|
|
|
const char* aKey, nsString& oVal) {
|
2002-05-02 15:50:36 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(aStrBundle);
|
|
|
|
NS_ENSURE_ARG_POINTER(aKey);
|
|
|
|
|
|
|
|
// Determine default label from string bundle
|
2017-08-04 07:40:52 +03:00
|
|
|
nsAutoString valUni;
|
|
|
|
nsresult rv = aStrBundle->GetStringFromName(aKey, valUni);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2002-05-02 15:50:36 +04:00
|
|
|
oVal.Assign(valUni);
|
|
|
|
} else {
|
|
|
|
oVal.Truncate();
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Set a multi-byte string in the control
|
2017-10-19 05:04:50 +03:00
|
|
|
static void SetTextOnWnd(HWND aControl, const nsAString& aStr) {
|
2017-10-19 05:04:30 +03:00
|
|
|
::SetWindowTextW(aControl,
|
|
|
|
reinterpret_cast<const wchar_t*>(aStr.BeginReading()));
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Will get the control and localized string by "key"
|
2017-10-19 05:04:50 +03:00
|
|
|
static void SetText(HWND aParent, UINT aId, nsIStringBundle* aStrBundle,
|
|
|
|
const char* aKey) {
|
|
|
|
HWND wnd = GetDlgItem(aParent, aId);
|
2002-05-02 15:50:36 +04:00
|
|
|
if (!wnd) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
nsAutoString str;
|
|
|
|
nsresult rv = GetLocalizedString(aStrBundle, aKey, str);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
SetTextOnWnd(wnd, str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2017-10-19 05:04:50 +03:00
|
|
|
static void SetRadio(HWND aParent, UINT aId, bool aIsSet,
|
|
|
|
bool isEnabled = true) {
|
|
|
|
HWND wnd = ::GetDlgItem(aParent, aId);
|
2002-05-02 15:50:36 +04:00
|
|
|
if (!wnd) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!isEnabled) {
|
|
|
|
::EnableWindow(wnd, FALSE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
::EnableWindow(wnd, TRUE);
|
|
|
|
::SendMessage(wnd, BM_SETCHECK, (WPARAM)aIsSet, (LPARAM)0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2017-10-19 05:04:50 +03:00
|
|
|
static void SetRadioOfGroup(HWND aDlg, int aRadId) {
|
|
|
|
int radioIds[] = {rad4, rad5, rad6};
|
2002-05-02 15:50:36 +04:00
|
|
|
int numRads = 3;
|
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
for (int i = 0; i < numRads; i++) {
|
2002-05-02 15:50:36 +04:00
|
|
|
HWND radWnd = ::GetDlgItem(aDlg, radioIds[i]);
|
2013-04-03 04:27:12 +04:00
|
|
|
if (radWnd != nullptr) {
|
2017-10-19 05:04:50 +03:00
|
|
|
::SendMessage(radWnd, BM_SETCHECK, (WPARAM)(radioIds[i] == aRadId),
|
|
|
|
(LPARAM)0);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
2017-10-19 05:04:50 +03:00
|
|
|
typedef struct {
|
|
|
|
const char* mKeyStr;
|
|
|
|
long mKeyId;
|
2002-05-02 15:50:36 +04:00
|
|
|
} PropKeyInfo;
|
|
|
|
|
2017-07-06 15:00:35 +03:00
|
|
|
// These are the control ids used in the dialog and
|
2002-05-02 15:50:36 +04:00
|
|
|
// defined by MS-Windows in commdlg.h
|
2017-10-19 05:04:50 +03:00
|
|
|
static PropKeyInfo gAllPropKeys[] = {{"printFramesTitleWindows", grp3},
|
|
|
|
{"asLaidOutWindows", rad4},
|
|
|
|
{"selectedFrameWindows", rad5},
|
|
|
|
{"separateFramesWindows", rad6},
|
|
|
|
{nullptr, 0}};
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Get the absolute coords of the child windows relative
|
|
|
|
// to its parent window
|
2017-10-19 05:04:50 +03:00
|
|
|
static void GetLocalRect(HWND aWnd, RECT& aRect, HWND aParent) {
|
2002-05-02 15:50:36 +04:00
|
|
|
::GetWindowRect(aWnd, &aRect);
|
|
|
|
|
2010-09-20 13:40:40 +04:00
|
|
|
// MapWindowPoints converts screen coordinates to client coordinates.
|
|
|
|
// It works correctly in both left-to-right and right-to-left windows.
|
2013-04-03 04:27:12 +04:00
|
|
|
::MapWindowPoints(nullptr, aParent, (LPPOINT)&aRect, 2);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Show or Hide the control
|
2017-10-19 05:04:50 +03:00
|
|
|
static void Show(HWND aWnd, bool bState) {
|
2002-05-02 15:50:36 +04:00
|
|
|
if (aWnd) {
|
2017-10-19 05:04:50 +03:00
|
|
|
::ShowWindow(aWnd, bState ? SW_SHOW : SW_HIDE);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Create a child window "control"
|
2017-10-19 05:04:50 +03:00
|
|
|
static HWND CreateControl(LPCWSTR aType, DWORD aStyle, HINSTANCE aHInst,
|
|
|
|
HWND aHdlg, int aId, LPCWSTR aStr,
|
|
|
|
const nsIntRect& aRect) {
|
|
|
|
HWND hWnd = ::CreateWindowW(
|
2002-05-02 15:50:36 +04:00
|
|
|
aType, aStr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle, aRect.X(),
|
2018-01-10 19:14:16 +03:00
|
|
|
aRect.Y(), aRect.Width(), aRect.Height(), (HWND)aHdlg,
|
2017-10-19 05:04:50 +03:00
|
|
|
(HMENU)(intptr_t)aId, aHInst, nullptr);
|
|
|
|
if (hWnd == nullptr) return nullptr;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2017-07-06 15:00:35 +03:00
|
|
|
// get the native font for the dialog and
|
2002-05-02 15:50:36 +04:00
|
|
|
// set it into the new control
|
|
|
|
HFONT hFont = (HFONT)::SendMessage(aHdlg, WM_GETFONT, (WPARAM)0, (LPARAM)0);
|
2013-04-03 04:27:12 +04:00
|
|
|
if (hFont != nullptr) {
|
2017-10-19 05:04:50 +03:00
|
|
|
::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)0);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
return hWnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Create a Radio Button
|
2017-10-19 05:04:50 +03:00
|
|
|
static HWND CreateRadioBtn(HINSTANCE aHInst, HWND aHdlg, int aId, LPCWSTR aStr,
|
|
|
|
const nsIntRect& aRect) {
|
|
|
|
return CreateControl(L"BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, aStr,
|
|
|
|
aRect);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Create a Group Box
|
2017-10-19 05:04:50 +03:00
|
|
|
static HWND CreateGroupBox(HINSTANCE aHInst, HWND aHdlg, int aId, LPCWSTR aStr,
|
|
|
|
const nsIntRect& aRect) {
|
2017-10-19 05:04:30 +03:00
|
|
|
return CreateControl(L"BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Localizes and initializes the radio buttons and group
|
2017-10-19 05:04:50 +03:00
|
|
|
static void InitializeExtendedDialog(HWND hdlg, int16_t aHowToEnableFrameUI) {
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(aHowToEnableFrameUI != nsIPrintSettings::kFrameEnableNone,
|
|
|
|
"should not be called");
|
2011-09-24 16:05:29 +04:00
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
// Localize the new controls in the print dialog
|
|
|
|
nsCOMPtr<nsIStringBundle> strBundle;
|
2017-10-19 05:04:50 +03:00
|
|
|
if (NS_SUCCEEDED(
|
|
|
|
GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) {
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t i = 0;
|
2013-04-03 04:27:12 +04:00
|
|
|
while (gAllPropKeys[i].mKeyStr != nullptr) {
|
2002-05-02 15:50:36 +04:00
|
|
|
SetText(hdlg, gAllPropKeys[i].mKeyId, strBundle, gAllPropKeys[i].mKeyStr);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set up radio buttons
|
|
|
|
if (aHowToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) {
|
2017-07-06 15:00:35 +03:00
|
|
|
SetRadio(hdlg, rad4, false);
|
|
|
|
SetRadio(hdlg, rad5, true);
|
2011-10-17 18:59:28 +04:00
|
|
|
SetRadio(hdlg, rad6, false);
|
2002-05-02 15:50:36 +04:00
|
|
|
// set default so user doesn't have to actually press on it
|
|
|
|
gFrameSelectedRadioBtn = rad5;
|
|
|
|
|
2011-09-24 16:05:29 +04:00
|
|
|
} else { // nsIPrintSettings::kFrameEnableAsIsAndEach
|
2017-07-06 15:00:35 +03:00
|
|
|
SetRadio(hdlg, rad4, false);
|
|
|
|
SetRadio(hdlg, rad5, false, false);
|
2011-10-17 18:59:28 +04:00
|
|
|
SetRadio(hdlg, rad6, true);
|
2002-05-02 15:50:36 +04:00
|
|
|
// set default so user doesn't have to actually press on it
|
|
|
|
gFrameSelectedRadioBtn = rad6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Special Hook Procedure for handling the print dialog messages
|
2017-10-19 05:04:50 +03:00
|
|
|
static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam,
|
|
|
|
LPARAM lParam) {
|
2002-05-02 15:50:36 +04:00
|
|
|
if (uiMsg == WM_COMMAND) {
|
|
|
|
UINT id = LOWORD(wParam);
|
|
|
|
if (id == rad4 || id == rad5 || id == rad6) {
|
|
|
|
gFrameSelectedRadioBtn = id;
|
|
|
|
SetRadioOfGroup(hdlg, id);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (uiMsg == WM_INITDIALOG) {
|
2017-10-19 05:04:50 +03:00
|
|
|
PRINTDLG* printDlg = (PRINTDLG*)lParam;
|
|
|
|
if (printDlg == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int16_t howToEnableFrameUI = (int16_t)printDlg->lCustData;
|
2011-09-24 16:05:29 +04:00
|
|
|
// don't add frame options if they would be disabled anyway
|
|
|
|
// because there are no frames
|
|
|
|
if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableNone) return TRUE;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2009-06-15 15:21:15 +04:00
|
|
|
HINSTANCE hInst = (HINSTANCE)::GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
|
2017-10-19 05:04:50 +03:00
|
|
|
if (hInst == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// Start by getting the local rects of several of the controls
|
|
|
|
// so we can calculate where the new controls are
|
|
|
|
HWND wnd = ::GetDlgItem(hdlg, grp1);
|
2017-10-19 05:04:50 +03:00
|
|
|
if (wnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
RECT dlgRect;
|
|
|
|
GetLocalRect(wnd, dlgRect, hdlg);
|
|
|
|
|
|
|
|
wnd = ::GetDlgItem(hdlg, rad1); // this is the top control "All"
|
2017-10-19 05:04:50 +03:00
|
|
|
if (wnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
RECT rad1Rect;
|
|
|
|
GetLocalRect(wnd, rad1Rect, hdlg);
|
|
|
|
|
|
|
|
wnd = ::GetDlgItem(hdlg, rad2); // this is the bottom control "Selection"
|
2017-10-19 05:04:50 +03:00
|
|
|
if (wnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
RECT rad2Rect;
|
|
|
|
GetLocalRect(wnd, rad2Rect, hdlg);
|
|
|
|
|
|
|
|
wnd = ::GetDlgItem(hdlg, rad3); // this is the middle control "Pages"
|
2017-10-19 05:04:50 +03:00
|
|
|
if (wnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
RECT rad3Rect;
|
|
|
|
GetLocalRect(wnd, rad3Rect, hdlg);
|
|
|
|
|
|
|
|
HWND okWnd = ::GetDlgItem(hdlg, IDOK);
|
2017-10-19 05:04:50 +03:00
|
|
|
if (okWnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
RECT okRect;
|
|
|
|
GetLocalRect(okWnd, okRect, hdlg);
|
|
|
|
|
|
|
|
wnd = ::GetDlgItem(hdlg, grp4); // this is the "Print range" groupbox
|
2017-10-19 05:04:50 +03:00
|
|
|
if (wnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
RECT prtRect;
|
|
|
|
GetLocalRect(wnd, prtRect, hdlg);
|
|
|
|
|
|
|
|
// calculate various different "gaps" for layout purposes
|
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
int rbGap = rad3Rect.top - rad1Rect.bottom; // gap between radiobtns
|
|
|
|
int grpBotGap = dlgRect.bottom -
|
|
|
|
rad2Rect.bottom; // gap from bottom rb to bottom of grpbox
|
|
|
|
int grpGap = dlgRect.top - prtRect.bottom; // gap between group boxes
|
|
|
|
int top = dlgRect.bottom + grpGap;
|
|
|
|
int radHgt = rad1Rect.bottom - rad1Rect.top + 1; // top of new group box
|
|
|
|
int y = top + (rad1Rect.top - dlgRect.top); // starting pos of first radio
|
|
|
|
int rbWidth =
|
|
|
|
dlgRect.right - rad1Rect.left - 5; // measure from rb left to the edge
|
|
|
|
// of the groupbox (5 is arbitrary)
|
2009-01-15 06:27:09 +03:00
|
|
|
nsIntRect rect;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// Create and position the radio buttons
|
|
|
|
//
|
2017-07-06 15:00:35 +03:00
|
|
|
// If any one control cannot be created then
|
2002-05-02 15:50:36 +04:00
|
|
|
// hide the others and bail out
|
|
|
|
//
|
2017-10-19 05:04:50 +03:00
|
|
|
rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
|
|
|
|
HWND rad4Wnd =
|
|
|
|
CreateRadioBtn(hInst, hdlg, rad4, kAsLaidOutOnScreenStr, rect);
|
|
|
|
if (rad4Wnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
y += radHgt + rbGap;
|
|
|
|
|
|
|
|
rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
|
2017-10-19 05:04:50 +03:00
|
|
|
HWND rad5Wnd =
|
|
|
|
CreateRadioBtn(hInst, hdlg, rad5, kTheSelectedFrameStr, rect);
|
2013-04-03 04:27:12 +04:00
|
|
|
if (rad5Wnd == nullptr) {
|
2002-05-02 15:50:36 +04:00
|
|
|
Show(rad4Wnd, FALSE); // hide
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
y += radHgt + rbGap;
|
|
|
|
|
|
|
|
rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
|
2017-10-19 05:04:50 +03:00
|
|
|
HWND rad6Wnd =
|
|
|
|
CreateRadioBtn(hInst, hdlg, rad6, kEachFrameSeparately, rect);
|
2013-04-03 04:27:12 +04:00
|
|
|
if (rad6Wnd == nullptr) {
|
2002-05-02 15:50:36 +04:00
|
|
|
Show(rad4Wnd, FALSE); // hide
|
|
|
|
Show(rad5Wnd, FALSE); // hide
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
y += radHgt + grpBotGap;
|
|
|
|
|
|
|
|
// Create and position the group box
|
2017-10-19 05:04:50 +03:00
|
|
|
rect.SetRect(dlgRect.left, top, dlgRect.right - dlgRect.left + 1,
|
|
|
|
y - top + 1);
|
2017-10-19 05:04:30 +03:00
|
|
|
HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, L"Print Frame", rect);
|
2013-04-03 04:27:12 +04:00
|
|
|
if (grpBoxWnd == nullptr) {
|
2002-05-02 15:50:36 +04:00
|
|
|
Show(rad4Wnd, FALSE); // hide
|
|
|
|
Show(rad5Wnd, FALSE); // hide
|
|
|
|
Show(rad6Wnd, FALSE); // hide
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Here we figure out the old height of the dlg
|
2009-02-06 05:05:58 +03:00
|
|
|
// then figure its gap from the old grpbx to the bottom
|
2002-05-02 15:50:36 +04:00
|
|
|
// then size the dlg
|
2017-07-06 15:00:35 +03:00
|
|
|
RECT pr, cr;
|
2002-05-02 15:50:36 +04:00
|
|
|
::GetWindowRect(hdlg, &pr);
|
|
|
|
::GetClientRect(hdlg, &cr);
|
|
|
|
|
|
|
|
int dlgHgt = (cr.bottom - cr.top) + 1;
|
|
|
|
int bottomGap = dlgHgt - okRect.bottom;
|
2017-10-19 05:04:50 +03:00
|
|
|
pr.bottom += (dlgRect.bottom - dlgRect.top) + grpGap + 1 -
|
|
|
|
(dlgHgt - dlgRect.bottom) + bottomGap;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
::SetWindowPos(hdlg, nullptr, pr.left, pr.top, pr.right - pr.left + 1,
|
|
|
|
pr.bottom - pr.top + 1,
|
|
|
|
SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// figure out the new height of the dialog
|
|
|
|
::GetClientRect(hdlg, &cr);
|
|
|
|
dlgHgt = (cr.bottom - cr.top) + 1;
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
// Reposition the OK and Cancel btns
|
|
|
|
int okHgt = okRect.bottom - okRect.top + 1;
|
2017-10-19 05:04:50 +03:00
|
|
|
::SetWindowPos(okWnd, nullptr, okRect.left, dlgHgt - bottomGap - okHgt, 0,
|
|
|
|
0, SWP_NOSIZE | SWP_NOREDRAW | SWP_NOZORDER);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
HWND cancelWnd = ::GetDlgItem(hdlg, IDCANCEL);
|
2017-10-19 05:04:50 +03:00
|
|
|
if (cancelWnd == nullptr) return 0L;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
RECT cancelRect;
|
|
|
|
GetLocalRect(cancelWnd, cancelRect, hdlg);
|
|
|
|
int cancelHgt = cancelRect.bottom - cancelRect.top + 1;
|
2017-10-19 05:04:50 +03:00
|
|
|
::SetWindowPos(cancelWnd, nullptr, cancelRect.left,
|
|
|
|
dlgHgt - bottomGap - cancelHgt, 0, 0,
|
|
|
|
SWP_NOSIZE | SWP_NOREDRAW | SWP_NOZORDER);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// localize and initialize the groupbox and radiobuttons
|
|
|
|
InitializeExtendedDialog(hdlg, howToEnableFrameUI);
|
|
|
|
|
|
|
|
// Looks like we were able to extend the dialog
|
2011-10-17 18:59:28 +04:00
|
|
|
gDialogWasExtended = true;
|
2011-02-07 17:46:31 +03:00
|
|
|
return TRUE;
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Returns a Global Moveable Memory Handle to a DevMode
|
2002-09-26 15:38:03 +04:00
|
|
|
// from the Printer by the name of aPrintName
|
|
|
|
//
|
|
|
|
// NOTE:
|
2017-07-06 15:00:35 +03:00
|
|
|
// This function assumes that aPrintName has already been converted from
|
2003-07-19 20:29:41 +04:00
|
|
|
// unicode
|
2002-09-26 15:38:03 +04:00
|
|
|
//
|
2016-04-05 09:24:28 +03:00
|
|
|
static nsReturnRef<nsHGLOBAL> CreateGlobalDevModeAndInit(
|
2017-08-08 09:07:55 +03:00
|
|
|
const nsString& aPrintName, nsIPrintSettings* aPS) {
|
2016-04-05 09:24:28 +03:00
|
|
|
nsHPRINTER hPrinter = nullptr;
|
2003-07-19 20:29:41 +04:00
|
|
|
// const cast kludge for silly Win32 api's
|
2017-10-19 05:04:50 +03:00
|
|
|
LPWSTR printName =
|
|
|
|
const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get()));
|
2013-04-03 04:27:12 +04:00
|
|
|
BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr);
|
2016-04-05 09:24:28 +03:00
|
|
|
if (!status) {
|
|
|
|
return nsReturnRef<nsHGLOBAL>();
|
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2016-04-05 09:24:28 +03:00
|
|
|
// Make sure hPrinter is closed on all paths
|
|
|
|
nsAutoPrinter autoPrinter(hPrinter);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2016-04-05 09:24:28 +03:00
|
|
|
// Get the buffer size
|
2017-10-19 05:04:50 +03:00
|
|
|
LONG needed = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr,
|
|
|
|
nullptr, 0);
|
2016-08-22 08:45:49 +03:00
|
|
|
if (needed < 0) {
|
2016-04-05 09:24:28 +03:00
|
|
|
return nsReturnRef<nsHGLOBAL>();
|
|
|
|
}
|
2016-04-08 18:37:04 +03:00
|
|
|
|
2016-04-05 09:24:28 +03:00
|
|
|
// Allocate a buffer of the correct size.
|
2017-10-19 05:04:50 +03:00
|
|
|
nsAutoDevMode newDevMode(
|
|
|
|
(LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, needed));
|
2016-04-05 09:24:28 +03:00
|
|
|
if (!newDevMode) {
|
|
|
|
return nsReturnRef<nsHGLOBAL>();
|
|
|
|
}
|
2016-04-08 18:37:04 +03:00
|
|
|
|
2016-08-22 08:45:49 +03:00
|
|
|
nsHGLOBAL hDevMode = ::GlobalAlloc(GHND, needed);
|
2016-04-05 09:24:28 +03:00
|
|
|
nsAutoGlobalMem globalDevMode(hDevMode);
|
|
|
|
if (!hDevMode) {
|
|
|
|
return nsReturnRef<nsHGLOBAL>();
|
|
|
|
}
|
2016-04-08 18:37:04 +03:00
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
LONG ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, newDevMode,
|
|
|
|
nullptr, DM_OUT_BUFFER);
|
2016-08-22 08:45:49 +03:00
|
|
|
if (ret != IDOK) {
|
2016-04-05 09:24:28 +03:00
|
|
|
return nsReturnRef<nsHGLOBAL>();
|
|
|
|
}
|
2016-04-08 18:37:04 +03:00
|
|
|
|
2016-04-05 09:24:28 +03:00
|
|
|
// Lock memory and copy contents from DEVMODE (current printer)
|
|
|
|
// to Global Memory DEVMODE
|
2017-10-19 05:04:50 +03:00
|
|
|
LPDEVMODEW devMode = (DEVMODEW*)::GlobalLock(hDevMode);
|
2016-04-05 09:24:28 +03:00
|
|
|
if (!devMode) {
|
|
|
|
return nsReturnRef<nsHGLOBAL>();
|
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2016-08-22 08:45:49 +03:00
|
|
|
memcpy(devMode, newDevMode.get(), needed);
|
2016-04-05 09:24:28 +03:00
|
|
|
// Initialize values from the PrintSettings
|
|
|
|
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
|
|
|
|
MOZ_ASSERT(psWin);
|
|
|
|
psWin->CopyToNative(devMode);
|
|
|
|
|
|
|
|
// Sets back the changes we made to the DevMode into the Printer Driver
|
2017-10-19 05:04:50 +03:00
|
|
|
ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode,
|
2016-08-22 08:45:49 +03:00
|
|
|
DM_IN_BUFFER | DM_OUT_BUFFER);
|
|
|
|
if (ret != IDOK) {
|
2016-04-05 09:24:28 +03:00
|
|
|
::GlobalUnlock(hDevMode);
|
|
|
|
return nsReturnRef<nsHGLOBAL>();
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
2016-04-05 09:24:28 +03:00
|
|
|
::GlobalUnlock(hDevMode);
|
|
|
|
|
|
|
|
return globalDevMode.out();
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// helper
|
2017-10-19 05:04:50 +03:00
|
|
|
static void GetDefaultPrinterNameFromGlobalPrinters(nsAString& printerName) {
|
|
|
|
nsCOMPtr<nsIPrinterEnumerator> prtEnum =
|
|
|
|
do_GetService("@mozilla.org/gfx/printerenumerator;1");
|
2002-05-02 15:50:36 +04:00
|
|
|
if (prtEnum) {
|
2017-10-09 02:08:09 +03:00
|
|
|
prtEnum->GetDefaultPrinterName(printerName);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-01 16:32:15 +04:00
|
|
|
// Determine whether we have a completely native dialog
|
|
|
|
// or whether we cshould extend it
|
2017-10-19 05:04:50 +03:00
|
|
|
static bool ShouldExtendPrintDialog() {
|
2005-07-01 16:32:15 +04:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIPrefService> prefs =
|
|
|
|
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
2011-10-17 18:59:28 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, true);
|
2005-07-01 16:32:15 +04:00
|
|
|
nsCOMPtr<nsIPrefBranch> prefBranch;
|
2012-07-30 18:20:58 +04:00
|
|
|
rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch));
|
2011-10-17 18:59:28 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, true);
|
2005-07-01 16:32:15 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool result;
|
2005-07-01 16:32:15 +04:00
|
|
|
rv = prefBranch->GetBoolPref("print.extend_native_print_dialog", &result);
|
2011-10-17 18:59:28 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, true);
|
2005-07-01 16:32:15 +04:00
|
|
|
return result;
|
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
// Displays the native Print Dialog
|
2017-10-19 05:04:50 +03:00
|
|
|
static nsresult ShowNativePrintDialog(HWND aHWnd,
|
|
|
|
nsIPrintSettings* aPrintSettings) {
|
2002-05-02 15:50:36 +04:00
|
|
|
// NS_ENSURE_ARG_POINTER(aHWnd);
|
|
|
|
NS_ENSURE_ARG_POINTER(aPrintSettings);
|
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
gDialogWasExtended = false;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// Get the Print Name to be used
|
2017-08-08 09:07:55 +03:00
|
|
|
nsString printerName;
|
2017-10-09 02:08:09 +03:00
|
|
|
aPrintSettings->GetPrinterName(printerName);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// If there is no name then use the default printer
|
2010-12-03 19:21:38 +03:00
|
|
|
if (printerName.IsEmpty()) {
|
|
|
|
GetDefaultPrinterNameFromGlobalPrinters(printerName);
|
2004-12-06 18:29:25 +03:00
|
|
|
} else {
|
2013-04-03 04:27:12 +04:00
|
|
|
HANDLE hPrinter = nullptr;
|
2017-10-19 05:04:50 +03:00
|
|
|
if (!::OpenPrinterW(const_cast<wchar_t*>(
|
|
|
|
static_cast<const wchar_t*>(printerName.get())),
|
|
|
|
&hPrinter, nullptr)) {
|
2004-12-06 18:29:25 +03:00
|
|
|
// If the last used printer is not found, we should use default printer.
|
2010-12-03 19:21:38 +03:00
|
|
|
GetDefaultPrinterNameFromGlobalPrinters(printerName);
|
2004-12-06 18:29:25 +03:00
|
|
|
} else {
|
|
|
|
::ClosePrinter(hPrinter);
|
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Now create a DEVNAMES struct so the the dialog is initialized correctly.
|
2002-09-26 15:38:03 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t len = printerName.Length();
|
2017-10-19 05:04:50 +03:00
|
|
|
nsHGLOBAL hDevNames =
|
|
|
|
::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1) + sizeof(DEVNAMES));
|
2016-04-05 09:24:28 +03:00
|
|
|
nsAutoGlobalMem autoDevNames(hDevNames);
|
2016-04-08 18:37:04 +03:00
|
|
|
if (!hDevNames) {
|
2010-12-03 19:21:38 +03:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
2016-04-08 18:37:04 +03:00
|
|
|
DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames);
|
2010-12-03 19:21:38 +03:00
|
|
|
if (!pDevNames) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2017-10-19 05:04:50 +03:00
|
|
|
pDevNames->wDriverOffset = sizeof(DEVNAMES) / sizeof(wchar_t);
|
|
|
|
pDevNames->wDeviceOffset = sizeof(DEVNAMES) / sizeof(wchar_t);
|
|
|
|
pDevNames->wOutputOffset = sizeof(DEVNAMES) / sizeof(wchar_t) + len;
|
|
|
|
pDevNames->wDefault = 0;
|
2002-09-26 15:38:03 +04:00
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
memcpy(pDevNames + 1, printerName.get(), (len + 1) * sizeof(wchar_t));
|
2016-04-08 18:37:04 +03:00
|
|
|
::GlobalUnlock(hDevNames);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// Create a Moveable Memory Object that holds a new DevMode
|
|
|
|
// from the Printer Name
|
|
|
|
// The PRINTDLG.hDevMode requires that it be a moveable memory object
|
2016-04-05 09:24:28 +03:00
|
|
|
// NOTE: autoDevMode is automatically freed when any error occurred
|
2017-10-19 05:04:50 +03:00
|
|
|
nsAutoGlobalMem autoDevMode(
|
|
|
|
CreateGlobalDevModeAndInit(printerName, aPrintSettings));
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// Prepare to Display the Print Dialog
|
2017-10-19 05:04:50 +03:00
|
|
|
PRINTDLGW prntdlg;
|
2008-10-24 09:21:15 +04:00
|
|
|
memset(&prntdlg, 0, sizeof(PRINTDLGW));
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
prntdlg.lStructSize = sizeof(prntdlg);
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.hwndOwner = aHWnd;
|
|
|
|
prntdlg.hDevMode = autoDevMode.get();
|
|
|
|
prntdlg.hDevNames = hDevNames;
|
|
|
|
prntdlg.hDC = nullptr;
|
|
|
|
prntdlg.Flags =
|
|
|
|
PD_ALLPAGES | PD_RETURNIC | PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
// if there is a current selection then enable the "Selection" radio button
|
2012-08-22 19:56:38 +04:00
|
|
|
int16_t howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool isOn;
|
2002-05-02 15:50:36 +04:00
|
|
|
aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn);
|
|
|
|
if (!isOn) {
|
|
|
|
prntdlg.Flags |= PD_NOSELECTION;
|
|
|
|
}
|
|
|
|
aPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI);
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t pg = 1;
|
2003-07-04 12:31:44 +04:00
|
|
|
aPrintSettings->GetStartPageRange(&pg);
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.nFromPage = pg;
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2003-07-04 12:31:44 +04:00
|
|
|
aPrintSettings->GetEndPageRange(&pg);
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.nToPage = pg;
|
2003-07-04 12:31:44 +04:00
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.nMinPage = 1;
|
|
|
|
prntdlg.nMaxPage = 0xFFFF;
|
|
|
|
prntdlg.nCopies = 1;
|
|
|
|
prntdlg.lpfnSetupHook = nullptr;
|
2013-04-03 04:27:12 +04:00
|
|
|
prntdlg.lpSetupTemplateName = nullptr;
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.hPrintTemplate = nullptr;
|
|
|
|
prntdlg.hSetupTemplate = nullptr;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.hInstance = nullptr;
|
2013-04-03 04:27:12 +04:00
|
|
|
prntdlg.lpPrintTemplateName = nullptr;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2005-07-01 16:32:15 +04:00
|
|
|
if (!ShouldExtendPrintDialog()) {
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.lCustData = 0;
|
|
|
|
prntdlg.lpfnPrintHook = nullptr;
|
2002-05-02 15:50:36 +04:00
|
|
|
} else {
|
|
|
|
// Set up print dialog "hook" procedure for extending the dialog
|
2017-10-19 05:04:50 +03:00
|
|
|
prntdlg.lCustData = (DWORD)howToEnableFrameUI;
|
|
|
|
prntdlg.lpfnPrintHook = (LPPRINTHOOKPROC)PrintHookProc;
|
|
|
|
prntdlg.Flags |= PD_ENABLEPRINTHOOK;
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
2016-07-02 01:58:31 +03:00
|
|
|
BOOL result;
|
|
|
|
{
|
|
|
|
mozilla::widget::WinUtils::AutoSystemDpiAware dpiAwareness;
|
2018-12-13 16:17:14 +03:00
|
|
|
mozilla::BackgroundHangMonitor().NotifyWait();
|
2016-07-02 01:58:31 +03:00
|
|
|
result = ::PrintDlgW(&prntdlg);
|
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
if (TRUE == result) {
|
2013-04-03 04:27:12 +04:00
|
|
|
// check to make sure we don't have any nullptr pointers
|
2002-10-30 16:31:58 +03:00
|
|
|
NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE);
|
|
|
|
|
2013-04-03 04:27:12 +04:00
|
|
|
if (prntdlg.hDevNames == nullptr) {
|
2002-10-30 16:31:58 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
2013-04-03 04:27:12 +04:00
|
|
|
// Lock the deviceNames and check for nullptr
|
2017-10-19 05:04:50 +03:00
|
|
|
DEVNAMES* devnames = (DEVNAMES*)::GlobalLock(prntdlg.hDevNames);
|
2013-04-03 04:27:12 +04:00
|
|
|
if (devnames == nullptr) {
|
2002-10-30 16:31:58 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2017-10-19 05:04:50 +03:00
|
|
|
char16_t* device = &(((char16_t*)devnames)[devnames->wDeviceOffset]);
|
|
|
|
char16_t* driver = &(((char16_t*)devnames)[devnames->wDriverOffset]);
|
2002-09-25 18:12:14 +04:00
|
|
|
|
2002-10-30 16:31:58 +03:00
|
|
|
// Check to see if the "Print To File" control is checked
|
|
|
|
// then take the name from devNames and set it in the PrintSettings
|
|
|
|
//
|
|
|
|
// NOTE:
|
|
|
|
// As per Microsoft SDK documentation the returned value offset from
|
2013-04-03 04:27:12 +04:00
|
|
|
// devnames->wOutputOffset is either "FILE:" or nullptr
|
2002-10-30 16:31:58 +03:00
|
|
|
// if the "Print To File" checkbox is checked it MUST be "FILE:"
|
|
|
|
// We assert as an extra safety check.
|
|
|
|
if (prntdlg.Flags & PD_PRINTTOFILE) {
|
2017-10-19 05:04:50 +03:00
|
|
|
char16ptr_t fileName = &(((wchar_t*)devnames)[devnames->wOutputOffset]);
|
2008-10-24 09:21:15 +04:00
|
|
|
NS_ASSERTION(wcscmp(fileName, L"FILE:") == 0, "FileName must be `FILE:`");
|
2017-10-09 02:08:09 +03:00
|
|
|
aPrintSettings->SetToFileName(nsDependentString(fileName));
|
2011-10-17 18:59:28 +04:00
|
|
|
aPrintSettings->SetPrintToFile(true);
|
2002-10-30 16:31:58 +03:00
|
|
|
} else {
|
|
|
|
// clear "print to file" info
|
2011-10-17 18:59:28 +04:00
|
|
|
aPrintSettings->SetPrintToFile(false);
|
2017-10-09 02:08:09 +03:00
|
|
|
aPrintSettings->SetToFileName(EmptyString());
|
2002-10-30 16:31:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));
|
|
|
|
if (!psWin) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Setup local Data members
|
2017-10-09 02:08:09 +03:00
|
|
|
psWin->SetDeviceName(nsDependentString(device));
|
|
|
|
psWin->SetDriverName(nsDependentString(driver));
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
|
2017-10-19 05:04:50 +03:00
|
|
|
wprintf(L"printer: driver %s, device %s flags: %d\n", driver, device,
|
|
|
|
prntdlg.Flags);
|
2002-05-02 15:50:36 +04:00
|
|
|
#endif
|
2002-10-30 16:31:58 +03:00
|
|
|
// fill the print options with the info from the dialog
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2017-10-09 02:08:09 +03:00
|
|
|
aPrintSettings->SetPrinterName(nsDependentString(device));
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2002-10-30 16:31:58 +03:00
|
|
|
if (prntdlg.Flags & PD_SELECTION) {
|
|
|
|
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2002-10-30 16:31:58 +03:00
|
|
|
} else if (prntdlg.Flags & PD_PAGENUMS) {
|
|
|
|
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange);
|
|
|
|
aPrintSettings->SetStartPageRange(prntdlg.nFromPage);
|
|
|
|
aPrintSettings->SetEndPageRange(prntdlg.nToPage);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2002-10-30 16:31:58 +03:00
|
|
|
} else { // (prntdlg.Flags & PD_ALLPAGES)
|
|
|
|
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
|
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
|
2002-10-30 16:31:58 +03:00
|
|
|
if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) {
|
|
|
|
// make sure the dialog got extended
|
|
|
|
if (gDialogWasExtended) {
|
|
|
|
// check to see about the frame radio buttons
|
|
|
|
switch (gFrameSelectedRadioBtn) {
|
2017-07-06 15:00:35 +03:00
|
|
|
case rad4:
|
2002-10-30 16:31:58 +03:00
|
|
|
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
|
|
|
|
break;
|
2017-07-06 15:00:35 +03:00
|
|
|
case rad5:
|
2002-10-30 16:31:58 +03:00
|
|
|
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);
|
|
|
|
break;
|
2017-07-06 15:00:35 +03:00
|
|
|
case rad6:
|
2002-05-02 15:50:36 +04:00
|
|
|
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
|
2002-10-30 16:31:58 +03:00
|
|
|
break;
|
|
|
|
} // switch
|
|
|
|
} else {
|
|
|
|
// if it didn't get extended then have it default to printing
|
|
|
|
// each frame separately
|
|
|
|
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
2002-10-30 16:31:58 +03:00
|
|
|
} else {
|
|
|
|
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames);
|
|
|
|
}
|
|
|
|
// Unlock DeviceNames
|
|
|
|
::GlobalUnlock(prntdlg.hDevNames);
|
|
|
|
|
|
|
|
// Transfer the settings from the native data to the PrintSettings
|
2008-10-22 04:54:26 +04:00
|
|
|
LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode);
|
2016-01-22 19:05:19 +03:00
|
|
|
if (!devMode || !prntdlg.hDC) {
|
2002-10-30 16:31:58 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
psWin->SetDevMode(devMode); // copies DevMode
|
2016-01-12 20:40:07 +03:00
|
|
|
psWin->CopyFromNative(prntdlg.hDC, devMode);
|
2002-10-30 16:31:58 +03:00
|
|
|
::GlobalUnlock(prntdlg.hDevMode);
|
2016-01-22 19:05:19 +03:00
|
|
|
::DeleteDC(prntdlg.hDC);
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
|
2017-10-19 05:04:50 +03:00
|
|
|
bool printSelection = prntdlg.Flags & PD_SELECTION;
|
|
|
|
bool printAllPages = prntdlg.Flags & PD_ALLPAGES;
|
|
|
|
bool printNumPages = prntdlg.Flags & PD_PAGENUMS;
|
|
|
|
int32_t fromPageNum = 0;
|
|
|
|
int32_t toPageNum = 0;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
if (printNumPages) {
|
|
|
|
fromPageNum = prntdlg.nFromPage;
|
2017-10-19 05:04:50 +03:00
|
|
|
toPageNum = prntdlg.nToPage;
|
2017-07-06 15:00:35 +03:00
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
if (printSelection) {
|
|
|
|
printf("Printing the selection\n");
|
|
|
|
|
|
|
|
} else if (printAllPages) {
|
|
|
|
printf("Printing all the pages\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum);
|
|
|
|
}
|
|
|
|
#endif
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2002-05-02 15:50:36 +04:00
|
|
|
} else {
|
2011-02-07 17:47:10 +03:00
|
|
|
::SetFocus(aHWnd);
|
2011-10-17 18:59:28 +04:00
|
|
|
aPrintSettings->SetIsCancelled(true);
|
2002-05-02 15:50:36 +04:00
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
2017-10-19 05:04:50 +03:00
|
|
|
static void PrepareForPrintDialog(nsIWebBrowserPrint* aWebBrowserPrint,
|
|
|
|
nsIPrintSettings* aPS) {
|
2002-05-02 15:50:36 +04:00
|
|
|
NS_ASSERTION(aWebBrowserPrint, "Can't be null");
|
|
|
|
NS_ASSERTION(aPS, "Can't be null");
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool isFramesetDocument;
|
|
|
|
bool isFramesetFrameSelected;
|
|
|
|
bool isIFrameSelected;
|
|
|
|
bool isRangeSelection;
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
aWebBrowserPrint->GetIsFramesetDocument(&isFramesetDocument);
|
|
|
|
aWebBrowserPrint->GetIsFramesetFrameSelected(&isFramesetFrameSelected);
|
|
|
|
aWebBrowserPrint->GetIsIFrameSelected(&isIFrameSelected);
|
|
|
|
aWebBrowserPrint->GetIsRangeSelection(&isRangeSelection);
|
|
|
|
|
|
|
|
// Setup print options for UI
|
|
|
|
if (isFramesetDocument) {
|
|
|
|
if (isFramesetFrameSelected) {
|
|
|
|
aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll);
|
|
|
|
} else {
|
|
|
|
aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now determine how to set up the Frame print UI
|
2017-10-19 05:04:50 +03:00
|
|
|
aPS->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB,
|
|
|
|
isRangeSelection || isIFrameSelected);
|
2002-05-02 15:50:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
//-- Show Print Dialog
|
|
|
|
//----------------------------------------------------------------------------------
|
2017-10-19 05:04:50 +03:00
|
|
|
nsresult NativeShowPrintDialog(HWND aHWnd, nsIWebBrowserPrint* aWebBrowserPrint,
|
|
|
|
nsIPrintSettings* aPrintSettings) {
|
2002-05-02 15:50:36 +04:00
|
|
|
PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings);
|
|
|
|
|
2011-12-16 13:13:29 +04:00
|
|
|
nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings);
|
2010-09-06 18:09:19 +04:00
|
|
|
if (aHWnd) {
|
|
|
|
::DestroyWindow(aHWnd);
|
|
|
|
}
|
2002-05-02 15:50:36 +04:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|