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

Side by Side Diff: printing/printing_context_win.cc

Issue 550033002: Fixed print_web_view_helper for CEF. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Mon Sep 8 02:31:11 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
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) { 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
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
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
OLDNEW
« printing/printing_context_win.h ('K') | « printing/printing_context_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698