OLD | NEW |
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 Loading... |
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) { | 53 : PrintingContext(delegate), context_(NULL), dialog_box_(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 NOTIMPLEMENTED(); | 64 DCHECK(!in_print_job_); |
| 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)); |
65 } | 112 } |
66 | 113 |
67 PrintingContext::Result PrintingContextWin::UseDefaultSettings() { | 114 PrintingContext::Result PrintingContextWin::UseDefaultSettings() { |
68 DCHECK(!in_print_job_); | 115 DCHECK(!in_print_job_); |
69 | 116 |
70 scoped_refptr<PrintBackend> backend = PrintBackend::CreateInstance(NULL); | 117 PRINTDLG dialog_options = { sizeof(PRINTDLG) }; |
71 base::string16 default_printer = | 118 dialog_options.Flags = PD_RETURNDC | PD_RETURNDEFAULT; |
72 base::UTF8ToWide(backend->GetDefaultPrinterName()); | 119 if (PrintDlg(&dialog_options)) |
73 if (!default_printer.empty()) { | 120 return ParseDialogResult(dialog_options); |
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(); | |
84 | 121 |
85 // No default printer configured, do we have any printers at all? | 122 // No default printer configured, do we have any printers at all? |
86 DWORD bytes_needed = 0; | 123 DWORD bytes_needed = 0; |
87 DWORD count_returned = 0; | 124 DWORD count_returned = 0; |
88 (void)::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, | 125 (void)::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, |
89 NULL, 2, NULL, 0, &bytes_needed, &count_returned); | 126 NULL, 2, NULL, 0, &bytes_needed, &count_returned); |
90 if (bytes_needed) { | 127 if (bytes_needed) { |
91 DCHECK_GE(bytes_needed, count_returned * sizeof(PRINTER_INFO_2)); | 128 DCHECK_GE(bytes_needed, count_returned * sizeof(PRINTER_INFO_2)); |
92 scoped_ptr<BYTE[]> printer_info_buffer(new BYTE[bytes_needed]); | 129 scoped_ptr<BYTE[]> printer_info_buffer(new BYTE[bytes_needed]); |
93 BOOL ret = ::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, | 130 BOOL ret = ::EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, |
94 NULL, 2, printer_info_buffer.get(), | 131 NULL, 2, printer_info_buffer.get(), |
95 bytes_needed, &bytes_needed, | 132 bytes_needed, &bytes_needed, |
96 &count_returned); | 133 &count_returned); |
97 if (ret && count_returned) { // have printers | 134 if (ret && count_returned) { // have printers |
98 // Open the first successfully found printer. | 135 // Open the first successfully found printer. |
99 const PRINTER_INFO_2* info_2 = | 136 const PRINTER_INFO_2* info_2 = |
100 reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get()); | 137 reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.get()); |
101 const PRINTER_INFO_2* info_2_end = info_2 + count_returned; | 138 const PRINTER_INFO_2* info_2_end = info_2 + count_returned; |
102 for (; info_2 < info_2_end; ++info_2) { | 139 for (; info_2 < info_2_end; ++info_2) { |
103 ScopedPrinterHandle printer; | 140 ScopedPrinterHandle printer; |
104 if (!printer.OpenPrinter(info_2->pPrinterName)) | 141 if (!printer.OpenPrinter(info_2->pPrinterName)) |
105 continue; | 142 continue; |
106 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = | 143 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = |
107 CreateDevMode(printer, NULL); | 144 CreateDevMode(printer, NULL); |
108 if (InitializeSettings(info_2->pPrinterName, dev_mode.get()) == OK) | 145 if (!dev_mode || !AllocateContext(info_2->pPrinterName, dev_mode.get(), |
| 146 &context_)) { |
| 147 continue; |
| 148 } |
| 149 if (InitializeSettings(*dev_mode.get(), info_2->pPrinterName, NULL, 0, |
| 150 false)) { |
109 return OK; | 151 return OK; |
| 152 } |
| 153 ReleaseContext(); |
110 } | 154 } |
111 if (context_) | 155 if (context_) |
112 return OK; | 156 return OK; |
113 } | 157 } |
114 } | 158 } |
115 | 159 |
116 return OnError(); | 160 ResetSettings(); |
| 161 return FAILED; |
117 } | 162 } |
118 | 163 |
119 gfx::Size PrintingContextWin::GetPdfPaperSizeDeviceUnits() { | 164 gfx::Size PrintingContextWin::GetPdfPaperSizeDeviceUnits() { |
120 // Default fallback to Letter size. | 165 // Default fallback to Letter size. |
121 gfx::SizeF paper_size(kLetterWidthInch, kLetterHeightInch); | 166 gfx::SizeF paper_size(kLetterWidthInch, kLetterHeightInch); |
122 | 167 |
123 // Get settings from locale. Paper type buffer length is at most 4. | 168 // Get settings from locale. Paper type buffer length is at most 4. |
124 const int paper_type_buffer_len = 4; | 169 const int paper_type_buffer_len = 4; |
125 wchar_t paper_type_buffer[paper_type_buffer_len] = {0}; | 170 wchar_t paper_type_buffer[paper_type_buffer_len] = {0}; |
126 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE, paper_type_buffer, | 171 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE, paper_type_buffer, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 dev_mode->dmPaperSize = static_cast<short>(id); | 250 dev_mode->dmPaperSize = static_cast<short>(id); |
206 } else if (width > 0 && height > 0) { | 251 } else if (width > 0 && height > 0) { |
207 dev_mode->dmFields |= DM_PAPERWIDTH; | 252 dev_mode->dmFields |= DM_PAPERWIDTH; |
208 dev_mode->dmPaperWidth = width; | 253 dev_mode->dmPaperWidth = width; |
209 dev_mode->dmFields |= DM_PAPERLENGTH; | 254 dev_mode->dmFields |= DM_PAPERLENGTH; |
210 dev_mode->dmPaperLength = height; | 255 dev_mode->dmPaperLength = height; |
211 } | 256 } |
212 } | 257 } |
213 | 258 |
214 // Update data using DocumentProperties. | 259 // Update data using DocumentProperties. |
215 if (show_system_dialog) { | 260 scoped_dev_mode = CreateDevMode(printer, scoped_dev_mode.get()); |
216 scoped_dev_mode = ShowPrintDialog( | 261 if (!scoped_dev_mode) |
217 printer, delegate_->GetParentView(), scoped_dev_mode.get()); | 262 return OnError(); |
218 } else { | 263 |
219 scoped_dev_mode = CreateDevMode(printer, scoped_dev_mode.get()); | 264 // Set printer then refresh printer settings. |
| 265 if (!AllocateContext(settings_.device_name(), scoped_dev_mode.get(), |
| 266 &context_)) { |
| 267 return OnError(); |
220 } | 268 } |
221 // Set printer then refresh printer settings. | 269 PrintSettingsInitializerWin::InitPrintSettings(context_, |
222 return InitializeSettings(settings_.device_name(), scoped_dev_mode.get()); | 270 *scoped_dev_mode.get(), |
| 271 &settings_); |
| 272 return OK; |
223 } | 273 } |
224 | 274 |
225 PrintingContext::Result PrintingContextWin::InitWithSettings( | 275 PrintingContext::Result PrintingContextWin::InitWithSettings( |
226 const PrintSettings& settings) { | 276 const PrintSettings& settings) { |
227 DCHECK(!in_print_job_); | 277 DCHECK(!in_print_job_); |
228 | 278 |
229 settings_ = settings; | 279 settings_ = settings; |
230 | 280 |
231 // TODO(maruel): settings_.ToDEVMODE() | 281 // TODO(maruel): settings_.ToDEVMODE() |
232 ScopedPrinterHandle printer; | 282 ScopedPrinterHandle printer; |
233 if (!printer.OpenPrinter(settings_.device_name().c_str())) | 283 if (!printer.OpenPrinter(settings_.device_name().c_str())) { |
234 return FAILED; | 284 return FAILED; |
| 285 } |
235 | 286 |
236 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = | 287 Result status = OK; |
237 CreateDevMode(printer, NULL); | |
238 | 288 |
239 return InitializeSettings(settings_.device_name(), dev_mode.get()); | 289 if (!GetPrinterSettings(printer, settings_.device_name())) |
| 290 status = FAILED; |
| 291 |
| 292 if (status != OK) |
| 293 ResetSettings(); |
| 294 return status; |
240 } | 295 } |
241 | 296 |
242 PrintingContext::Result PrintingContextWin::NewDocument( | 297 PrintingContext::Result PrintingContextWin::NewDocument( |
243 const base::string16& document_name) { | 298 const base::string16& document_name) { |
244 DCHECK(!in_print_job_); | 299 DCHECK(!in_print_job_); |
245 if (!context_) | 300 if (!context_) |
246 return OnError(); | 301 return OnError(); |
247 | 302 |
248 // Set the flag used by the AbortPrintJob dialog procedure. | 303 // Set the flag used by the AbortPrintJob dialog procedure. |
249 abort_printing_ = false; | 304 abort_printing_ = false; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 368 |
314 ResetSettings(); | 369 ResetSettings(); |
315 return OK; | 370 return OK; |
316 } | 371 } |
317 | 372 |
318 void PrintingContextWin::Cancel() { | 373 void PrintingContextWin::Cancel() { |
319 abort_printing_ = true; | 374 abort_printing_ = true; |
320 in_print_job_ = false; | 375 in_print_job_ = false; |
321 if (context_) | 376 if (context_) |
322 CancelDC(context_); | 377 CancelDC(context_); |
| 378 if (dialog_box_) { |
| 379 DestroyWindow(dialog_box_); |
| 380 dialog_box_dismissed_ = true; |
| 381 } |
323 } | 382 } |
324 | 383 |
325 void PrintingContextWin::ReleaseContext() { | 384 void PrintingContextWin::ReleaseContext() { |
326 if (context_) { | 385 if (context_) { |
327 DeleteDC(context_); | 386 DeleteDC(context_); |
328 context_ = NULL; | 387 context_ = NULL; |
329 } | 388 } |
330 } | 389 } |
331 | 390 |
332 gfx::NativeDrawingContext PrintingContextWin::context() const { | 391 gfx::NativeDrawingContext PrintingContextWin::context() const { |
333 return context_; | 392 return context_; |
334 } | 393 } |
335 | 394 |
336 // static | 395 // static |
337 BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) { | 396 BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) { |
338 if (nCode) { | 397 if (nCode) { |
339 // TODO(maruel): Need a way to find the right instance to set. Should | 398 // TODO(maruel): Need a way to find the right instance to set. Should |
340 // leverage PrintJobManager here? | 399 // leverage PrintJobManager here? |
341 // abort_printing_ = true; | 400 // abort_printing_ = true; |
342 } | 401 } |
343 return true; | 402 return true; |
344 } | 403 } |
345 | 404 |
346 PrintingContext::Result PrintingContextWin::InitializeSettings( | 405 bool PrintingContextWin::InitializeSettings(const DEVMODE& dev_mode, |
347 const std::wstring& device_name, | 406 const std::wstring& new_device_name, |
348 DEVMODE* dev_mode) { | 407 const PRINTPAGERANGE* ranges, |
349 if (!dev_mode) | 408 int number_ranges, |
350 return OnError(); | 409 bool selection_only) { |
| 410 skia::InitializeDC(context_); |
| 411 DCHECK(GetDeviceCaps(context_, CLIPCAPS)); |
| 412 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB); |
| 413 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64); |
| 414 // Some printers don't advertise these. |
| 415 // DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_SCALING); |
| 416 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_CONST_ALPHA); |
| 417 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA); |
351 | 418 |
352 ReleaseContext(); | 419 // StretchDIBits() support is needed for printing. |
353 context_ = CreateDC(L"WINSPOOL", device_name.c_str(), NULL, dev_mode); | 420 if (!(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB) || |
354 if (!context_) | 421 !(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64)) { |
355 return OnError(); | 422 NOTREACHED(); |
356 | 423 ResetSettings(); |
357 skia::InitializeDC(context_); | 424 return false; |
| 425 } |
358 | 426 |
359 DCHECK(!in_print_job_); | 427 DCHECK(!in_print_job_); |
360 settings_.set_device_name(device_name); | 428 DCHECK(context_); |
361 PrintSettingsInitializerWin::InitPrintSettings( | 429 PageRanges ranges_vector; |
362 context_, *dev_mode, &settings_); | 430 if (!selection_only) { |
| 431 // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. |
| 432 ranges_vector.reserve(number_ranges); |
| 433 for (int i = 0; i < number_ranges; ++i) { |
| 434 PageRange range; |
| 435 // Transfer from 1-based to 0-based. |
| 436 range.from = ranges[i].nFromPage - 1; |
| 437 range.to = ranges[i].nToPage - 1; |
| 438 ranges_vector.push_back(range); |
| 439 } |
| 440 } |
363 | 441 |
364 return OK; | 442 settings_.set_ranges(ranges_vector); |
| 443 settings_.set_device_name(new_device_name); |
| 444 settings_.set_selection_only(selection_only); |
| 445 PrintSettingsInitializerWin::InitPrintSettings(context_, dev_mode, |
| 446 &settings_); |
| 447 |
| 448 return true; |
365 } | 449 } |
366 | 450 |
367 scoped_ptr<DEVMODE, base::FreeDeleter> PrintingContextWin::ShowPrintDialog( | 451 bool PrintingContextWin::GetPrinterSettings(HANDLE printer, |
368 HANDLE printer, | 452 const std::wstring& device_name) { |
369 gfx::NativeView parent_view, | 453 DCHECK(!in_print_job_); |
370 DEVMODE* dev_mode) { | 454 |
| 455 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode = |
| 456 CreateDevMode(printer, NULL); |
| 457 |
| 458 if (!dev_mode || !AllocateContext(device_name, dev_mode.get(), &context_)) { |
| 459 ResetSettings(); |
| 460 return false; |
| 461 } |
| 462 |
| 463 return InitializeSettings(*dev_mode.get(), device_name, NULL, 0, false); |
| 464 } |
| 465 |
| 466 // static |
| 467 bool PrintingContextWin::AllocateContext(const std::wstring& device_name, |
| 468 const DEVMODE* dev_mode, |
| 469 gfx::NativeDrawingContext* context) { |
| 470 *context = CreateDC(L"WINSPOOL", device_name.c_str(), NULL, dev_mode); |
| 471 DCHECK(*context); |
| 472 return *context != NULL; |
| 473 } |
| 474 |
| 475 PrintingContext::Result PrintingContextWin::ParseDialogResultEx( |
| 476 const PRINTDLGEX& dialog_options) { |
| 477 // If the user clicked OK or Apply then Cancel, but not only Cancel. |
| 478 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { |
| 479 // Start fresh. |
| 480 ResetSettings(); |
| 481 |
| 482 DEVMODE* dev_mode = NULL; |
| 483 if (dialog_options.hDevMode) { |
| 484 dev_mode = |
| 485 reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode)); |
| 486 DCHECK(dev_mode); |
| 487 } |
| 488 |
| 489 std::wstring device_name; |
| 490 if (dialog_options.hDevNames) { |
| 491 DEVNAMES* dev_names = |
| 492 reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames)); |
| 493 DCHECK(dev_names); |
| 494 if (dev_names) { |
| 495 device_name = reinterpret_cast<const wchar_t*>(dev_names) + |
| 496 dev_names->wDeviceOffset; |
| 497 GlobalUnlock(dialog_options.hDevNames); |
| 498 } |
| 499 } |
| 500 |
| 501 bool success = false; |
| 502 if (dev_mode && !device_name.empty()) { |
| 503 context_ = dialog_options.hDC; |
| 504 PRINTPAGERANGE* page_ranges = NULL; |
| 505 DWORD num_page_ranges = 0; |
| 506 bool print_selection_only = false; |
| 507 if (dialog_options.Flags & PD_PAGENUMS) { |
| 508 page_ranges = dialog_options.lpPageRanges; |
| 509 num_page_ranges = dialog_options.nPageRanges; |
| 510 } |
| 511 if (dialog_options.Flags & PD_SELECTION) { |
| 512 print_selection_only = true; |
| 513 } |
| 514 success = InitializeSettings(*dev_mode, |
| 515 device_name, |
| 516 page_ranges, |
| 517 num_page_ranges, |
| 518 print_selection_only); |
| 519 } |
| 520 |
| 521 if (!success && dialog_options.hDC) { |
| 522 DeleteDC(dialog_options.hDC); |
| 523 context_ = NULL; |
| 524 } |
| 525 |
| 526 if (dev_mode) { |
| 527 GlobalUnlock(dialog_options.hDevMode); |
| 528 } |
| 529 } else { |
| 530 if (dialog_options.hDC) { |
| 531 DeleteDC(dialog_options.hDC); |
| 532 } |
| 533 } |
| 534 |
| 535 if (dialog_options.hDevMode != NULL) |
| 536 GlobalFree(dialog_options.hDevMode); |
| 537 if (dialog_options.hDevNames != NULL) |
| 538 GlobalFree(dialog_options.hDevNames); |
| 539 |
| 540 switch (dialog_options.dwResultAction) { |
| 541 case PD_RESULT_PRINT: |
| 542 return context_ ? OK : FAILED; |
| 543 case PD_RESULT_APPLY: |
| 544 return context_ ? CANCEL : FAILED; |
| 545 case PD_RESULT_CANCEL: |
| 546 return CANCEL; |
| 547 default: |
| 548 return FAILED; |
| 549 } |
| 550 } |
| 551 |
| 552 HRESULT PrintingContextWin::ShowPrintDialog(PRINTDLGEX* options) { |
371 // Note that this cannot use ui::BaseShellDialog as the print dialog is | 553 // Note that this cannot use ui::BaseShellDialog as the print dialog is |
372 // system modal: opening it from a background thread can cause Windows to | 554 // system modal: opening it from a background thread can cause Windows to |
373 // get the wrong Z-order which will make the print dialog appear behind the | 555 // get the wrong Z-order which will make the print dialog appear behind the |
374 // browser frame (but still being modal) so neither the browser frame nor | 556 // browser frame (but still being modal) so neither the browser frame nor |
375 // the print dialog will get any input. See http://crbug.com/342697 | 557 // the print dialog will get any input. See http://crbug.com/342697 |
376 // http://crbug.com/180997 for details. | 558 // http://crbug.com/180997 for details. |
377 base::MessageLoop::ScopedNestableTaskAllower allow( | 559 base::MessageLoop::ScopedNestableTaskAllower allow( |
378 base::MessageLoop::current()); | 560 base::MessageLoop::current()); |
379 | 561 |
380 bool canceled = false; | 562 return PrintDlgEx(options); |
381 scoped_ptr<DEVMODE, base::FreeDeleter> result = | 563 } |
382 PromptDevMode(printer, | |
383 settings_.device_name(), | |
384 dev_mode, | |
385 GetRootWindow(parent_view), | |
386 &canceled); | |
387 | 564 |
388 if (canceled) { | 565 PrintingContext::Result PrintingContextWin::ParseDialogResult( |
389 result.reset(); | 566 const PRINTDLG& dialog_options) { |
390 abort_printing_ = true; | 567 // If the user clicked OK or Apply then Cancel, but not only Cancel. |
| 568 // Start fresh. |
| 569 ResetSettings(); |
| 570 |
| 571 DEVMODE* dev_mode = NULL; |
| 572 if (dialog_options.hDevMode) { |
| 573 dev_mode = |
| 574 reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode)); |
| 575 DCHECK(dev_mode); |
391 } | 576 } |
392 | 577 |
393 return result.Pass(); | 578 std::wstring device_name; |
| 579 if (dialog_options.hDevNames) { |
| 580 DEVNAMES* dev_names = |
| 581 reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames)); |
| 582 DCHECK(dev_names); |
| 583 if (dev_names) { |
| 584 device_name = |
| 585 reinterpret_cast<const wchar_t*>( |
| 586 reinterpret_cast<const wchar_t*>(dev_names) + |
| 587 dev_names->wDeviceOffset); |
| 588 GlobalUnlock(dialog_options.hDevNames); |
| 589 } |
| 590 } |
| 591 |
| 592 bool success = false; |
| 593 if (dev_mode && !device_name.empty()) { |
| 594 context_ = dialog_options.hDC; |
| 595 success = InitializeSettings(*dev_mode, device_name, NULL, 0, false); |
| 596 } |
| 597 |
| 598 if (!success && dialog_options.hDC) { |
| 599 DeleteDC(dialog_options.hDC); |
| 600 context_ = NULL; |
| 601 } |
| 602 |
| 603 if (dev_mode) { |
| 604 GlobalUnlock(dialog_options.hDevMode); |
| 605 } |
| 606 |
| 607 if (dialog_options.hDevMode != NULL) |
| 608 GlobalFree(dialog_options.hDevMode); |
| 609 if (dialog_options.hDevNames != NULL) |
| 610 GlobalFree(dialog_options.hDevNames); |
| 611 |
| 612 return context_ ? OK : FAILED; |
394 } | 613 } |
395 | 614 |
396 } // namespace printing | 615 } // namespace printing |
OLD | NEW |