Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: printing/printing_context_win.cc

Issue 480303002: Use document from preview for System Dialog printing on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tue Aug 26 01:11:31 PDT 2014 Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « printing/printing_context_win.h ('k') | printing/printing_context_win_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "printing/printing_context_win.h" 5 #include "printing/printing_context_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 } // anonymous namespace 43 } // anonymous namespace
44 44
45 namespace printing { 45 namespace printing {
46 46
47 // static 47 // static
48 scoped_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) { 48 scoped_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) {
49 return make_scoped_ptr<PrintingContext>(new PrintingContextWin(delegate)); 49 return make_scoped_ptr<PrintingContext>(new PrintingContextWin(delegate));
50 } 50 }
51 51
52 PrintingContextWin::PrintingContextWin(Delegate* delegate) 52 PrintingContextWin::PrintingContextWin(Delegate* delegate)
53 : PrintingContext(delegate), context_(NULL), dialog_box_(NULL) { 53 : PrintingContext(delegate), context_(NULL) {
54 } 54 }
55 55
56 PrintingContextWin::~PrintingContextWin() { 56 PrintingContextWin::~PrintingContextWin() {
57 ReleaseContext(); 57 ReleaseContext();
58 } 58 }
59 59
60 void PrintingContextWin::AskUserForSettings( 60 void PrintingContextWin::AskUserForSettings(
61 int max_pages, 61 int max_pages,
62 bool has_selection, 62 bool has_selection,
63 const PrintSettingsCallback& callback) { 63 const PrintSettingsCallback& callback) {
64 DCHECK(!in_print_job_); 64 NOTIMPLEMENTED();
65 dialog_box_dismissed_ = false;
66
67 HWND window = GetRootWindow(delegate_->GetParentView());
68 DCHECK(window);
69
70 // Show the OS-dependent dialog box.
71 // If the user press
72 // - OK, the settings are reset and reinitialized with the new settings. OK is
73 // returned.
74 // - Apply then Cancel, the settings are reset and reinitialized with the new
75 // settings. CANCEL is returned.
76 // - Cancel, the settings are not changed, the previous setting, if it was
77 // initialized before, are kept. CANCEL is returned.
78 // On failure, the settings are reset and FAILED is returned.
79 PRINTDLGEX dialog_options = { sizeof(PRINTDLGEX) };
80 dialog_options.hwndOwner = window;
81 // Disable options we don't support currently.
82 // TODO(maruel): Reuse the previously loaded settings!
83 dialog_options.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE |
84 PD_NOCURRENTPAGE | PD_HIDEPRINTTOFILE;
85 if (!has_selection)
86 dialog_options.Flags |= PD_NOSELECTION;
87
88 PRINTPAGERANGE ranges[32];
89 dialog_options.nStartPage = START_PAGE_GENERAL;
90 if (max_pages) {
91 // Default initialize to print all the pages.
92 memset(ranges, 0, sizeof(ranges));
93 ranges[0].nFromPage = 1;
94 ranges[0].nToPage = max_pages;
95 dialog_options.nPageRanges = 1;
96 dialog_options.nMaxPageRanges = arraysize(ranges);
97 dialog_options.nMinPage = 1;
98 dialog_options.nMaxPage = max_pages;
99 dialog_options.lpPageRanges = ranges;
100 } else {
101 // No need to bother, we don't know how many pages are available.
102 dialog_options.Flags |= PD_NOPAGENUMS;
103 }
104
105 if (ShowPrintDialog(&dialog_options) != S_OK) {
106 ResetSettings();
107 callback.Run(FAILED);
108 }
109
110 // TODO(maruel): Support PD_PRINTTOFILE.
111 callback.Run(ParseDialogResultEx(dialog_options));
112 } 65 }
113 66
114 PrintingContext::Result PrintingContextWin::UseDefaultSettings() { 67 PrintingContext::Result PrintingContextWin::UseDefaultSettings() {
115 DCHECK(!in_print_job_); 68 DCHECK(!in_print_job_);
116 69
117 PRINTDLG dialog_options = { sizeof(PRINTDLG) }; 70 scoped_refptr<PrintBackend> backend = PrintBackend::CreateInstance(NULL);
118 dialog_options.Flags = PD_RETURNDC | PD_RETURNDEFAULT; 71 base::string16 default_printer =
119 if (PrintDlg(&dialog_options)) 72 base::UTF8ToWide(backend->GetDefaultPrinterName());
120 return ParseDialogResult(dialog_options); 73 if (!default_printer.empty()) {
74 ScopedPrinterHandle printer;
75 if (printer.OpenPrinter(default_printer.c_str())) {
76 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode =
77 CreateDevMode(printer, NULL);
78 if (InitializeSettings(default_printer, dev_mode.get()) == OK)
79 return OK;
80 }
81 }
82
83 ReleaseContext();
121 84
122 // No default printer configured, do we have any printers at all? 85 // No default printer configured, do we have any printers at all?
123 DWORD bytes_needed = 0; 86 DWORD bytes_needed = 0;
124 DWORD count_returned = 0; 87 DWORD count_returned = 0;
125 (void)::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, 88 (void)::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,
126 NULL, 2, NULL, 0, &bytes_needed, &count_returned); 89 NULL, 2, NULL, 0, &bytes_needed, &count_returned);
127 if (bytes_needed) { 90 if (bytes_needed) {
128 DCHECK_GE(bytes_needed, count_returned * sizeof(PRINTER_INFO_2)); 91 DCHECK_GE(bytes_needed, count_returned * sizeof(PRINTER_INFO_2));
129 scoped_ptr<BYTE[]> printer_info_buffer(new BYTE[bytes_needed]); 92 scoped_ptr<BYTE[]> printer_info_buffer(new BYTE[bytes_needed]);
130 BOOL ret = ::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, 93 BOOL ret = ::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,
131 NULL, 2, printer_info_buffer.get(), 94 NULL, 2, printer_info_buffer.get(),
132 bytes_needed, &bytes_needed, 95 bytes_needed, &bytes_needed,
133 &count_returned); 96 &count_returned);
134 if (ret && count_returned) { // have printers 97 if (ret && count_returned) { // have printers
135 // Open the first successfully found printer. 98 // Open the first successfully found printer.
136 const PRINTER_INFO_2* info_2 = 99 const PRINTER_INFO_2* info_2 =
137 reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get()); 100 reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get());
138 const PRINTER_INFO_2* info_2_end = info_2 + count_returned; 101 const PRINTER_INFO_2* info_2_end = info_2 + count_returned;
139 for (; info_2 < info_2_end; ++info_2) { 102 for (; info_2 < info_2_end; ++info_2) {
140 ScopedPrinterHandle printer; 103 ScopedPrinterHandle printer;
141 if (!printer.OpenPrinter(info_2->pPrinterName)) 104 if (!printer.OpenPrinter(info_2->pPrinterName))
142 continue; 105 continue;
143 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = 106 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode =
144 CreateDevMode(printer, NULL); 107 CreateDevMode(printer, NULL);
145 if (!dev_mode || !AllocateContext(info_2->pPrinterName, dev_mode.get(), 108 if (InitializeSettings(info_2->pPrinterName, dev_mode.get()) == OK)
146 &context_)) {
147 continue;
148 }
149 if (InitializeSettings(*dev_mode.get(), info_2->pPrinterName, NULL, 0,
150 false)) {
151 return OK; 109 return OK;
152 }
153 ReleaseContext();
154 } 110 }
155 if (context_) 111 if (context_)
156 return OK; 112 return OK;
157 } 113 }
158 } 114 }
159 115
160 ResetSettings(); 116 return OnError();
161 return FAILED;
162 } 117 }
163 118
164 gfx::Size PrintingContextWin::GetPdfPaperSizeDeviceUnits() { 119 gfx::Size PrintingContextWin::GetPdfPaperSizeDeviceUnits() {
165 // Default fallback to Letter size. 120 // Default fallback to Letter size.
166 gfx::SizeF paper_size(kLetterWidthInch, kLetterHeightInch); 121 gfx::SizeF paper_size(kLetterWidthInch, kLetterHeightInch);
167 122
168 // Get settings from locale. Paper type buffer length is at most 4. 123 // Get settings from locale. Paper type buffer length is at most 4.
169 const int paper_type_buffer_len = 4; 124 const int paper_type_buffer_len = 4;
170 wchar_t paper_type_buffer[paper_type_buffer_len] = {0}; 125 wchar_t paper_type_buffer[paper_type_buffer_len] = {0};
171 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE, paper_type_buffer, 126 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE, paper_type_buffer,
(...skipping 13 matching lines...) Expand all
185 default: // DMPAPER_LETTER is used for default fallback. 140 default: // DMPAPER_LETTER is used for default fallback.
186 break; 141 break;
187 } 142 }
188 } 143 }
189 return gfx::Size( 144 return gfx::Size(
190 paper_size.width() * settings_.device_units_per_inch(), 145 paper_size.width() * settings_.device_units_per_inch(),
191 paper_size.height() * settings_.device_units_per_inch()); 146 paper_size.height() * settings_.device_units_per_inch());
192 } 147 }
193 148
194 PrintingContext::Result PrintingContextWin::UpdatePrinterSettings( 149 PrintingContext::Result PrintingContextWin::UpdatePrinterSettings(
195 bool external_preview) { 150 bool external_preview,
151 bool show_system_dialog) {
196 DCHECK(!in_print_job_); 152 DCHECK(!in_print_job_);
197 DCHECK(!external_preview) << "Not implemented"; 153 DCHECK(!external_preview) << "Not implemented";
198 154
199 ScopedPrinterHandle printer; 155 ScopedPrinterHandle printer;
200 if (!printer.OpenPrinter(settings_.device_name().c_str())) 156 if (!printer.OpenPrinter(settings_.device_name().c_str()))
201 return OnError(); 157 return OnError();
202 158
203 // Make printer changes local to Chrome. 159 // Make printer changes local to Chrome.
204 // See MSDN documentation regarding DocumentProperties. 160 // See MSDN documentation regarding DocumentProperties.
205 scoped_ptr<DEVMODE, base::FreeDeleter> scoped_dev_mode = 161 scoped_ptr<DEVMODE, base::FreeDeleter> scoped_dev_mode =
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 dev_mode->dmPaperSize = static_cast<short>(id); 205 dev_mode->dmPaperSize = static_cast<short>(id);
250 } else if (width > 0 && height > 0) { 206 } else if (width > 0 && height > 0) {
251 dev_mode->dmFields |= DM_PAPERWIDTH; 207 dev_mode->dmFields |= DM_PAPERWIDTH;
252 dev_mode->dmPaperWidth = width; 208 dev_mode->dmPaperWidth = width;
253 dev_mode->dmFields |= DM_PAPERLENGTH; 209 dev_mode->dmFields |= DM_PAPERLENGTH;
254 dev_mode->dmPaperLength = height; 210 dev_mode->dmPaperLength = height;
255 } 211 }
256 } 212 }
257 213
258 // Update data using DocumentProperties. 214 // Update data using DocumentProperties.
259 scoped_dev_mode = CreateDevMode(printer, scoped_dev_mode.get()); 215 if (show_system_dialog) {
260 if (!scoped_dev_mode) 216 scoped_dev_mode = ShowPrintDialog(
261 return OnError(); 217 printer, delegate_->GetParentView(), scoped_dev_mode.get());
262 218 } else {
219 scoped_dev_mode = CreateDevMode(printer, scoped_dev_mode.get());
220 }
263 // Set printer then refresh printer settings. 221 // Set printer then refresh printer settings.
264 if (!AllocateContext(settings_.device_name(), scoped_dev_mode.get(), 222 return InitializeSettings(settings_.device_name(), scoped_dev_mode.get());
265 &context_)) {
266 return OnError();
267 }
268 PrintSettingsInitializerWin::InitPrintSettings(context_,
269 *scoped_dev_mode.get(),
270 &settings_);
271 return OK;
272 } 223 }
273 224
274 PrintingContext::Result PrintingContextWin::InitWithSettings( 225 PrintingContext::Result PrintingContextWin::InitWithSettings(
275 const PrintSettings& settings) { 226 const PrintSettings& settings) {
276 DCHECK(!in_print_job_); 227 DCHECK(!in_print_job_);
277 228
278 settings_ = settings; 229 settings_ = settings;
279 230
280 // TODO(maruel): settings_.ToDEVMODE() 231 // TODO(maruel): settings_.ToDEVMODE()
281 ScopedPrinterHandle printer; 232 ScopedPrinterHandle printer;
282 if (!printer.OpenPrinter(settings_.device_name().c_str())) { 233 if (!printer.OpenPrinter(settings_.device_name().c_str()))
283 return FAILED; 234 return FAILED;
284 }
285 235
286 Result status = OK; 236 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode =
237 CreateDevMode(printer, NULL);
287 238
288 if (!GetPrinterSettings(printer, settings_.device_name())) 239 return InitializeSettings(settings_.device_name(), dev_mode.get());
289 status = FAILED;
290
291 if (status != OK)
292 ResetSettings();
293 return status;
294 } 240 }
295 241
296 PrintingContext::Result PrintingContextWin::NewDocument( 242 PrintingContext::Result PrintingContextWin::NewDocument(
297 const base::string16& document_name) { 243 const base::string16& document_name) {
298 DCHECK(!in_print_job_); 244 DCHECK(!in_print_job_);
299 if (!context_) 245 if (!context_)
300 return OnError(); 246 return OnError();
301 247
302 // Set the flag used by the AbortPrintJob dialog procedure. 248 // Set the flag used by the AbortPrintJob dialog procedure.
303 abort_printing_ = false; 249 abort_printing_ = false;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 313
368 ResetSettings(); 314 ResetSettings();
369 return OK; 315 return OK;
370 } 316 }
371 317
372 void PrintingContextWin::Cancel() { 318 void PrintingContextWin::Cancel() {
373 abort_printing_ = true; 319 abort_printing_ = true;
374 in_print_job_ = false; 320 in_print_job_ = false;
375 if (context_) 321 if (context_)
376 CancelDC(context_); 322 CancelDC(context_);
377 if (dialog_box_) {
378 DestroyWindow(dialog_box_);
379 dialog_box_dismissed_ = true;
380 }
381 } 323 }
382 324
383 void PrintingContextWin::ReleaseContext() { 325 void PrintingContextWin::ReleaseContext() {
384 if (context_) { 326 if (context_) {
385 DeleteDC(context_); 327 DeleteDC(context_);
386 context_ = NULL; 328 context_ = NULL;
387 } 329 }
388 } 330 }
389 331
390 gfx::NativeDrawingContext PrintingContextWin::context() const { 332 gfx::NativeDrawingContext PrintingContextWin::context() const {
391 return context_; 333 return context_;
392 } 334 }
393 335
394 // static 336 // static
395 BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) { 337 BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) {
396 if (nCode) { 338 if (nCode) {
397 // TODO(maruel): Need a way to find the right instance to set. Should 339 // TODO(maruel): Need a way to find the right instance to set. Should
398 // leverage PrintJobManager here? 340 // leverage PrintJobManager here?
399 // abort_printing_ = true; 341 // abort_printing_ = true;
400 } 342 }
401 return true; 343 return true;
402 } 344 }
403 345
404 bool PrintingContextWin::InitializeSettings(const DEVMODE& dev_mode, 346 PrintingContext::Result PrintingContextWin::InitializeSettings(
405 const std::wstring& new_device_name, 347 const std::wstring& device_name,
406 const PRINTPAGERANGE* ranges, 348 DEVMODE* dev_mode) {
407 int number_ranges, 349 if (!dev_mode)
408 bool selection_only) { 350 return OnError();
351
352 ReleaseContext();
353 context_ = CreateDC(L"WINSPOOL", device_name.c_str(), NULL, dev_mode);
354 if (!context_)
355 return OnError();
356
409 skia::InitializeDC(context_); 357 skia::InitializeDC(context_);
410 DCHECK(GetDeviceCaps(context_, CLIPCAPS));
411 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB);
412 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64);
413 // Some printers don't advertise these.
414 // DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_SCALING);
415 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_CONST_ALPHA);
416 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA);
417
418 // StretchDIBits() support is needed for printing.
419 if (!(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB) ||
420 !(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64)) {
421 NOTREACHED();
422 ResetSettings();
423 return false;
424 }
425 358
426 DCHECK(!in_print_job_); 359 DCHECK(!in_print_job_);
427 DCHECK(context_); 360 settings_.set_device_name(device_name);
428 PageRanges ranges_vector; 361 PrintSettingsInitializerWin::InitPrintSettings(
429 if (!selection_only) { 362 context_, *dev_mode, &settings_);
430 // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector.
431 ranges_vector.reserve(number_ranges);
432 for (int i = 0; i < number_ranges; ++i) {
433 PageRange range;
434 // Transfer from 1-based to 0-based.
435 range.from = ranges[i].nFromPage - 1;
436 range.to = ranges[i].nToPage - 1;
437 ranges_vector.push_back(range);
438 }
439 }
440 363
441 settings_.set_ranges(ranges_vector); 364 return OK;
442 settings_.set_device_name(new_device_name);
443 settings_.set_selection_only(selection_only);
444 PrintSettingsInitializerWin::InitPrintSettings(context_, dev_mode,
445 &settings_);
446
447 return true;
448 } 365 }
449 366
450 bool PrintingContextWin::GetPrinterSettings(HANDLE printer, 367 scoped_ptr<DEVMODE, base::FreeDeleter> PrintingContextWin::ShowPrintDialog(
451 const std::wstring& device_name) { 368 HANDLE printer,
452 DCHECK(!in_print_job_); 369 gfx::NativeView parent_view,
453 370 DEVMODE* dev_mode) {
454 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode =
455 CreateDevMode(printer, NULL);
456
457 if (!dev_mode || !AllocateContext(device_name, dev_mode.get(), &context_)) {
458 ResetSettings();
459 return false;
460 }
461
462 return InitializeSettings(*dev_mode.get(), device_name, NULL, 0, false);
463 }
464
465 // static
466 bool PrintingContextWin::AllocateContext(const std::wstring& device_name,
467 const DEVMODE* dev_mode,
468 gfx::NativeDrawingContext* context) {
469 *context = CreateDC(L"WINSPOOL", device_name.c_str(), NULL, dev_mode);
470 DCHECK(*context);
471 return *context != NULL;
472 }
473
474 PrintingContext::Result PrintingContextWin::ParseDialogResultEx(
475 const PRINTDLGEX& dialog_options) {
476 // If the user clicked OK or Apply then Cancel, but not only Cancel.
477 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) {
478 // Start fresh.
479 ResetSettings();
480
481 DEVMODE* dev_mode = NULL;
482 if (dialog_options.hDevMode) {
483 dev_mode =
484 reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode));
485 DCHECK(dev_mode);
486 }
487
488 std::wstring device_name;
489 if (dialog_options.hDevNames) {
490 DEVNAMES* dev_names =
491 reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames));
492 DCHECK(dev_names);
493 if (dev_names) {
494 device_name = reinterpret_cast<const wchar_t*>(dev_names) +
495 dev_names->wDeviceOffset;
496 GlobalUnlock(dialog_options.hDevNames);
497 }
498 }
499
500 bool success = false;
501 if (dev_mode && !device_name.empty()) {
502 context_ = dialog_options.hDC;
503 PRINTPAGERANGE* page_ranges = NULL;
504 DWORD num_page_ranges = 0;
505 bool print_selection_only = false;
506 if (dialog_options.Flags & PD_PAGENUMS) {
507 page_ranges = dialog_options.lpPageRanges;
508 num_page_ranges = dialog_options.nPageRanges;
509 }
510 if (dialog_options.Flags & PD_SELECTION) {
511 print_selection_only = true;
512 }
513 success = InitializeSettings(*dev_mode,
514 device_name,
515 page_ranges,
516 num_page_ranges,
517 print_selection_only);
518 }
519
520 if (!success && dialog_options.hDC) {
521 DeleteDC(dialog_options.hDC);
522 context_ = NULL;
523 }
524
525 if (dev_mode) {
526 GlobalUnlock(dialog_options.hDevMode);
527 }
528 } else {
529 if (dialog_options.hDC) {
530 DeleteDC(dialog_options.hDC);
531 }
532 }
533
534 if (dialog_options.hDevMode != NULL)
535 GlobalFree(dialog_options.hDevMode);
536 if (dialog_options.hDevNames != NULL)
537 GlobalFree(dialog_options.hDevNames);
538
539 switch (dialog_options.dwResultAction) {
540 case PD_RESULT_PRINT:
541 return context_ ? OK : FAILED;
542 case PD_RESULT_APPLY:
543 return context_ ? CANCEL : FAILED;
544 case PD_RESULT_CANCEL:
545 return CANCEL;
546 default:
547 return FAILED;
548 }
549 }
550
551 HRESULT PrintingContextWin::ShowPrintDialog(PRINTDLGEX* options) {
552 // Note that this cannot use ui::BaseShellDialog as the print dialog is 371 // Note that this cannot use ui::BaseShellDialog as the print dialog is
553 // system modal: opening it from a background thread can cause Windows to 372 // system modal: opening it from a background thread can cause Windows to
554 // get the wrong Z-order which will make the print dialog appear behind the 373 // get the wrong Z-order which will make the print dialog appear behind the
555 // browser frame (but still being modal) so neither the browser frame nor 374 // browser frame (but still being modal) so neither the browser frame nor
556 // the print dialog will get any input. See http://crbug.com/342697 375 // the print dialog will get any input. See http://crbug.com/342697
557 // http://crbug.com/180997 for details. 376 // http://crbug.com/180997 for details.
558 base::MessageLoop::ScopedNestableTaskAllower allow( 377 base::MessageLoop::ScopedNestableTaskAllower allow(
559 base::MessageLoop::current()); 378 base::MessageLoop::current());
560 379
561 return PrintDlgEx(options); 380 bool canceled = false;
562 } 381 scoped_ptr<DEVMODE, base::FreeDeleter> result =
382 PromptDevMode(printer,
383 settings_.device_name(),
384 dev_mode,
385 GetRootWindow(parent_view),
386 &canceled);
563 387
564 PrintingContext::Result PrintingContextWin::ParseDialogResult( 388 if (canceled) {
565 const PRINTDLG& dialog_options) { 389 result.reset();
566 // If the user clicked OK or Apply then Cancel, but not only Cancel. 390 abort_printing_ = true;
567 // Start fresh.
568 ResetSettings();
569
570 DEVMODE* dev_mode = NULL;
571 if (dialog_options.hDevMode) {
572 dev_mode =
573 reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode));
574 DCHECK(dev_mode);
575 } 391 }
576 392
577 std::wstring device_name; 393 return result.Pass();
578 if (dialog_options.hDevNames) {
579 DEVNAMES* dev_names =
580 reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames));
581 DCHECK(dev_names);
582 if (dev_names) {
583 device_name =
584 reinterpret_cast<const wchar_t*>(
585 reinterpret_cast<const wchar_t*>(dev_names) +
586 dev_names->wDeviceOffset);
587 GlobalUnlock(dialog_options.hDevNames);
588 }
589 }
590
591 bool success = false;
592 if (dev_mode && !device_name.empty()) {
593 context_ = dialog_options.hDC;
594 success = InitializeSettings(*dev_mode, device_name, NULL, 0, false);
595 }
596
597 if (!success && dialog_options.hDC) {
598 DeleteDC(dialog_options.hDC);
599 context_ = NULL;
600 }
601
602 if (dev_mode) {
603 GlobalUnlock(dialog_options.hDevMode);
604 }
605
606 if (dialog_options.hDevMode != NULL)
607 GlobalFree(dialog_options.hDevMode);
608 if (dialog_options.hDevNames != NULL)
609 GlobalFree(dialog_options.hDevNames);
610
611 return context_ ? OK : FAILED;
612 } 394 }
613 395
614 } // namespace printing 396 } // namespace printing
OLDNEW
« no previous file with comments | « printing/printing_context_win.h ('k') | printing/printing_context_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698