| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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.h" | 5 #include "printing/printing_context.h" |
| 6 | 6 |
| 7 #include <winspool.h> | 7 #include <winspool.h> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/i18n/file_util_icu.h" | 10 #include "base/i18n/file_util_icu.h" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 131 |
| 132 private: | 132 private: |
| 133 PrintingContext& owner_; | 133 PrintingContext& owner_; |
| 134 HWND owner_hwnd_; | 134 HWND owner_hwnd_; |
| 135 IPrintDialogServices* services_; | 135 IPrintDialogServices* services_; |
| 136 | 136 |
| 137 DISALLOW_EVIL_CONSTRUCTORS(CallbackHandler); | 137 DISALLOW_EVIL_CONSTRUCTORS(CallbackHandler); |
| 138 }; | 138 }; |
| 139 | 139 |
| 140 PrintingContext::PrintingContext() | 140 PrintingContext::PrintingContext() |
| 141 : hdc_(NULL), | 141 : context_(NULL), |
| 142 #ifndef NDEBUG | 142 #ifndef NDEBUG |
| 143 page_number_(-1), | 143 page_number_(-1), |
| 144 #endif | 144 #endif |
| 145 dialog_box_(NULL), | 145 dialog_box_(NULL), |
| 146 dialog_box_dismissed_(false), | 146 dialog_box_dismissed_(false), |
| 147 in_print_job_(false), | 147 in_print_job_(false), |
| 148 abort_printing_(false) { | 148 abort_printing_(false) { |
| 149 } | 149 } |
| 150 | 150 |
| 151 PrintingContext::~PrintingContext() { | 151 PrintingContext::~PrintingContext() { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 | 234 |
| 235 // Close the printer after retrieving the context. | 235 // Close the printer after retrieving the context. |
| 236 ClosePrinter(printer); | 236 ClosePrinter(printer); |
| 237 | 237 |
| 238 if (status != OK) | 238 if (status != OK) |
| 239 ResetSettings(); | 239 ResetSettings(); |
| 240 return status; | 240 return status; |
| 241 } | 241 } |
| 242 | 242 |
| 243 void PrintingContext::ResetSettings() { | 243 void PrintingContext::ResetSettings() { |
| 244 if (hdc_ != NULL) { | 244 if (context_ != NULL) { |
| 245 DeleteDC(hdc_); | 245 DeleteDC(context_); |
| 246 hdc_ = NULL; | 246 context_ = NULL; |
| 247 } | 247 } |
| 248 settings_.Clear(); | 248 settings_.Clear(); |
| 249 in_print_job_ = false; | 249 in_print_job_ = false; |
| 250 | 250 |
| 251 #ifndef NDEBUG | 251 #ifndef NDEBUG |
| 252 page_number_ = -1; | 252 page_number_ = -1; |
| 253 #endif | 253 #endif |
| 254 } | 254 } |
| 255 | 255 |
| 256 PrintingContext::Result PrintingContext::NewDocument( | 256 PrintingContext::Result PrintingContext::NewDocument( |
| 257 const std::wstring& document_name) { | 257 const std::wstring& document_name) { |
| 258 DCHECK(!in_print_job_); | 258 DCHECK(!in_print_job_); |
| 259 if (!hdc_) | 259 if (!context_) |
| 260 return OnError(); | 260 return OnError(); |
| 261 | 261 |
| 262 // Set the flag used by the AbortPrintJob dialog procedure. | 262 // Set the flag used by the AbortPrintJob dialog procedure. |
| 263 abort_printing_ = false; | 263 abort_printing_ = false; |
| 264 | 264 |
| 265 in_print_job_ = true; | 265 in_print_job_ = true; |
| 266 | 266 |
| 267 // Register the application's AbortProc function with GDI. | 267 // Register the application's AbortProc function with GDI. |
| 268 if (SP_ERROR == SetAbortProc(hdc_, &AbortProc)) | 268 if (SP_ERROR == SetAbortProc(context_, &AbortProc)) |
| 269 return OnError(); | 269 return OnError(); |
| 270 | 270 |
| 271 DOCINFO di = { sizeof(DOCINFO) }; | 271 DOCINFO di = { sizeof(DOCINFO) }; |
| 272 di.lpszDocName = document_name.c_str(); | 272 di.lpszDocName = document_name.c_str(); |
| 273 | 273 |
| 274 // Is there a debug dump directory specified? If so, force to print to a file. | 274 // Is there a debug dump directory specified? If so, force to print to a file. |
| 275 std::wstring debug_dump_path = PrintedDocument::debug_dump_path(); | 275 std::wstring debug_dump_path = PrintedDocument::debug_dump_path(); |
| 276 if (!debug_dump_path.empty()) { | 276 if (!debug_dump_path.empty()) { |
| 277 // Create a filename. | 277 // Create a filename. |
| 278 std::wstring filename; | 278 std::wstring filename; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 289 di.lpszOutput = debug_dump_path.c_str(); | 289 di.lpszOutput = debug_dump_path.c_str(); |
| 290 } | 290 } |
| 291 | 291 |
| 292 // No message loop running in unit tests. | 292 // No message loop running in unit tests. |
| 293 DCHECK(!MessageLoop::current() ? true : | 293 DCHECK(!MessageLoop::current() ? true : |
| 294 !MessageLoop::current()->NestableTasksAllowed()); | 294 !MessageLoop::current()->NestableTasksAllowed()); |
| 295 | 295 |
| 296 // Begin a print job by calling the StartDoc function. | 296 // Begin a print job by calling the StartDoc function. |
| 297 // NOTE: StartDoc() starts a message loop. That causes a lot of problems with | 297 // NOTE: StartDoc() starts a message loop. That causes a lot of problems with |
| 298 // IPC. Make sure recursive task processing is disabled. | 298 // IPC. Make sure recursive task processing is disabled. |
| 299 if (StartDoc(hdc_, &di) <= 0) | 299 if (StartDoc(context_, &di) <= 0) |
| 300 return OnError(); | 300 return OnError(); |
| 301 | 301 |
| 302 #ifndef NDEBUG | 302 #ifndef NDEBUG |
| 303 page_number_ = 0; | 303 page_number_ = 0; |
| 304 #endif | 304 #endif |
| 305 return OK; | 305 return OK; |
| 306 } | 306 } |
| 307 | 307 |
| 308 PrintingContext::Result PrintingContext::NewPage() { | 308 PrintingContext::Result PrintingContext::NewPage() { |
| 309 if (abort_printing_) | 309 if (abort_printing_) |
| 310 return CANCEL; | 310 return CANCEL; |
| 311 DCHECK(in_print_job_); | 311 DCHECK(in_print_job_); |
| 312 | 312 |
| 313 // Inform the driver that the application is about to begin sending data. | 313 // Inform the driver that the application is about to begin sending data. |
| 314 if (StartPage(hdc_) <= 0) | 314 if (StartPage(context_) <= 0) |
| 315 return OnError(); | 315 return OnError(); |
| 316 | 316 |
| 317 #ifndef NDEBUG | 317 #ifndef NDEBUG |
| 318 ++page_number_; | 318 ++page_number_; |
| 319 #endif | 319 #endif |
| 320 | 320 |
| 321 return OK; | 321 return OK; |
| 322 } | 322 } |
| 323 | 323 |
| 324 PrintingContext::Result PrintingContext::PageDone() { | 324 PrintingContext::Result PrintingContext::PageDone() { |
| 325 if (abort_printing_) | 325 if (abort_printing_) |
| 326 return CANCEL; | 326 return CANCEL; |
| 327 DCHECK(in_print_job_); | 327 DCHECK(in_print_job_); |
| 328 | 328 |
| 329 if (EndPage(hdc_) <= 0) | 329 if (EndPage(context_) <= 0) |
| 330 return OnError(); | 330 return OnError(); |
| 331 return OK; | 331 return OK; |
| 332 } | 332 } |
| 333 | 333 |
| 334 PrintingContext::Result PrintingContext::DocumentDone() { | 334 PrintingContext::Result PrintingContext::DocumentDone() { |
| 335 if (abort_printing_) | 335 if (abort_printing_) |
| 336 return CANCEL; | 336 return CANCEL; |
| 337 DCHECK(in_print_job_); | 337 DCHECK(in_print_job_); |
| 338 | 338 |
| 339 // Inform the driver that document has ended. | 339 // Inform the driver that document has ended. |
| 340 if (EndDoc(hdc_) <= 0) | 340 if (EndDoc(context_) <= 0) |
| 341 return OnError(); | 341 return OnError(); |
| 342 | 342 |
| 343 ResetSettings(); | 343 ResetSettings(); |
| 344 return OK; | 344 return OK; |
| 345 } | 345 } |
| 346 | 346 |
| 347 void PrintingContext::Cancel() { | 347 void PrintingContext::Cancel() { |
| 348 abort_printing_ = true; | 348 abort_printing_ = true; |
| 349 in_print_job_ = false; | 349 in_print_job_ = false; |
| 350 if (hdc_) | 350 if (context_) |
| 351 CancelDC(hdc_); | 351 CancelDC(context_); |
| 352 DismissDialog(); | 352 DismissDialog(); |
| 353 } | 353 } |
| 354 | 354 |
| 355 void PrintingContext::DismissDialog() { | 355 void PrintingContext::DismissDialog() { |
| 356 if (dialog_box_) { | 356 if (dialog_box_) { |
| 357 DestroyWindow(dialog_box_); | 357 DestroyWindow(dialog_box_); |
| 358 dialog_box_dismissed_ = true; | 358 dialog_box_dismissed_ = true; |
| 359 } | 359 } |
| 360 } | 360 } |
| 361 | 361 |
| 362 PrintingContext::Result PrintingContext::OnError() { | 362 PrintingContext::Result PrintingContext::OnError() { |
| 363 // This will close hdc_ and clear settings_. | 363 // This will close context_ and clear settings_. |
| 364 ResetSettings(); | 364 ResetSettings(); |
| 365 return abort_printing_ ? CANCEL : FAILED; | 365 return abort_printing_ ? CANCEL : FAILED; |
| 366 } | 366 } |
| 367 | 367 |
| 368 // static | 368 // static |
| 369 BOOL PrintingContext::AbortProc(HDC hdc, int nCode) { | 369 BOOL PrintingContext::AbortProc(HDC hdc, int nCode) { |
| 370 if (nCode) { | 370 if (nCode) { |
| 371 // TODO(maruel): Need a way to find the right instance to set. Should | 371 // TODO(maruel): Need a way to find the right instance to set. Should |
| 372 // leverage PrintJobManager here? | 372 // leverage PrintJobManager here? |
| 373 // abort_printing_ = true; | 373 // abort_printing_ = true; |
| 374 } | 374 } |
| 375 return true; | 375 return true; |
| 376 } | 376 } |
| 377 | 377 |
| 378 bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode, | 378 bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode, |
| 379 const std::wstring& new_device_name, | 379 const std::wstring& new_device_name, |
| 380 const PRINTPAGERANGE* ranges, | 380 const PRINTPAGERANGE* ranges, |
| 381 int number_ranges, | 381 int number_ranges, |
| 382 bool selection_only) { | 382 bool selection_only) { |
| 383 skia::PlatformDevice::InitializeDC(hdc_); | 383 skia::PlatformDevice::InitializeDC(context_); |
| 384 DCHECK(GetDeviceCaps(hdc_, CLIPCAPS)); | 384 DCHECK(GetDeviceCaps(context_, CLIPCAPS)); |
| 385 DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_STRETCHDIB); | 385 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB); |
| 386 DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_BITMAP64); | 386 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64); |
| 387 // Some printers don't advertise these. | 387 // Some printers don't advertise these. |
| 388 // DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_SCALING); | 388 // DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_SCALING); |
| 389 // DCHECK(GetDeviceCaps(hdc_, SHADEBLENDCAPS) & SB_CONST_ALPHA); | 389 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_CONST_ALPHA); |
| 390 // DCHECK(GetDeviceCaps(hdc_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA); | 390 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA); |
| 391 | 391 |
| 392 // StretchDIBits() support is needed for printing. | 392 // StretchDIBits() support is needed for printing. |
| 393 if (!(GetDeviceCaps(hdc_, RASTERCAPS) & RC_STRETCHDIB) || | 393 if (!(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB) || |
| 394 !(GetDeviceCaps(hdc_, RASTERCAPS) & RC_BITMAP64)) { | 394 !(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64)) { |
| 395 NOTREACHED(); | 395 NOTREACHED(); |
| 396 ResetSettings(); | 396 ResetSettings(); |
| 397 return false; | 397 return false; |
| 398 } | 398 } |
| 399 | 399 |
| 400 DCHECK(!in_print_job_); | 400 DCHECK(!in_print_job_); |
| 401 DCHECK(hdc_); | 401 DCHECK(context_); |
| 402 PageRanges ranges_vector; | 402 PageRanges ranges_vector; |
| 403 if (!selection_only) { | 403 if (!selection_only) { |
| 404 // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. | 404 // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. |
| 405 ranges_vector.reserve(number_ranges); | 405 ranges_vector.reserve(number_ranges); |
| 406 for (int i = 0; i < number_ranges; ++i) { | 406 for (int i = 0; i < number_ranges; ++i) { |
| 407 PageRange range; | 407 PageRange range; |
| 408 // Transfer from 1-based to 0-based. | 408 // Transfer from 1-based to 0-based. |
| 409 range.from = ranges[i].nFromPage - 1; | 409 range.from = ranges[i].nFromPage - 1; |
| 410 range.to = ranges[i].nToPage - 1; | 410 range.to = ranges[i].nToPage - 1; |
| 411 ranges_vector.push_back(range); | 411 ranges_vector.push_back(range); |
| 412 } | 412 } |
| 413 } | 413 } |
| 414 settings_.Init(hdc_, | 414 settings_.Init(context_, |
| 415 dev_mode, | 415 dev_mode, |
| 416 ranges_vector, | 416 ranges_vector, |
| 417 new_device_name, | 417 new_device_name, |
| 418 selection_only); | 418 selection_only); |
| 419 return true; | 419 return true; |
| 420 } | 420 } |
| 421 | 421 |
| 422 bool PrintingContext::GetPrinterSettings(HANDLE printer, | 422 bool PrintingContext::GetPrinterSettings(HANDLE printer, |
| 423 const std::wstring& device_name) { | 423 const std::wstring& device_name) { |
| 424 DCHECK(!in_print_job_); | 424 DCHECK(!in_print_job_); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 } | 467 } |
| 468 buffer.reset(); | 468 buffer.reset(); |
| 469 } | 469 } |
| 470 // Failed to retrieve the printer settings. | 470 // Failed to retrieve the printer settings. |
| 471 ResetSettings(); | 471 ResetSettings(); |
| 472 return false; | 472 return false; |
| 473 } | 473 } |
| 474 | 474 |
| 475 bool PrintingContext::AllocateContext(const std::wstring& printer_name, | 475 bool PrintingContext::AllocateContext(const std::wstring& printer_name, |
| 476 const DEVMODE* dev_mode) { | 476 const DEVMODE* dev_mode) { |
| 477 hdc_ = CreateDC(L"WINSPOOL", printer_name.c_str(), NULL, dev_mode); | 477 context_ = CreateDC(L"WINSPOOL", printer_name.c_str(), NULL, dev_mode); |
| 478 DCHECK(hdc_); | 478 DCHECK(context_); |
| 479 return hdc_ != NULL; | 479 return context_ != NULL; |
| 480 } | 480 } |
| 481 | 481 |
| 482 PrintingContext::Result PrintingContext::ParseDialogResultEx( | 482 PrintingContext::Result PrintingContext::ParseDialogResultEx( |
| 483 const PRINTDLGEX& dialog_options) { | 483 const PRINTDLGEX& dialog_options) { |
| 484 // If the user clicked OK or Apply then Cancel, but not only Cancel. | 484 // If the user clicked OK or Apply then Cancel, but not only Cancel. |
| 485 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { | 485 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { |
| 486 // Start fresh. | 486 // Start fresh. |
| 487 ResetSettings(); | 487 ResetSettings(); |
| 488 | 488 |
| 489 DEVMODE* dev_mode = NULL; | 489 DEVMODE* dev_mode = NULL; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 502 device_name = | 502 device_name = |
| 503 reinterpret_cast<const wchar_t*>( | 503 reinterpret_cast<const wchar_t*>( |
| 504 reinterpret_cast<const wchar_t*>(dev_names) + | 504 reinterpret_cast<const wchar_t*>(dev_names) + |
| 505 dev_names->wDeviceOffset); | 505 dev_names->wDeviceOffset); |
| 506 GlobalUnlock(dialog_options.hDevNames); | 506 GlobalUnlock(dialog_options.hDevNames); |
| 507 } | 507 } |
| 508 } | 508 } |
| 509 | 509 |
| 510 bool success = false; | 510 bool success = false; |
| 511 if (dev_mode && !device_name.empty()) { | 511 if (dev_mode && !device_name.empty()) { |
| 512 hdc_ = dialog_options.hDC; | 512 context_ = dialog_options.hDC; |
| 513 PRINTPAGERANGE* page_ranges = NULL; | 513 PRINTPAGERANGE* page_ranges = NULL; |
| 514 DWORD num_page_ranges = 0; | 514 DWORD num_page_ranges = 0; |
| 515 bool print_selection_only = false; | 515 bool print_selection_only = false; |
| 516 if (dialog_options.Flags & PD_PAGENUMS) { | 516 if (dialog_options.Flags & PD_PAGENUMS) { |
| 517 page_ranges = dialog_options.lpPageRanges; | 517 page_ranges = dialog_options.lpPageRanges; |
| 518 num_page_ranges = dialog_options.nPageRanges; | 518 num_page_ranges = dialog_options.nPageRanges; |
| 519 } | 519 } |
| 520 if (dialog_options.Flags & PD_SELECTION) { | 520 if (dialog_options.Flags & PD_SELECTION) { |
| 521 print_selection_only = true; | 521 print_selection_only = true; |
| 522 } | 522 } |
| 523 success = InitializeSettings(*dev_mode, | 523 success = InitializeSettings(*dev_mode, |
| 524 device_name, | 524 device_name, |
| 525 dialog_options.lpPageRanges, | 525 dialog_options.lpPageRanges, |
| 526 dialog_options.nPageRanges, | 526 dialog_options.nPageRanges, |
| 527 print_selection_only); | 527 print_selection_only); |
| 528 } | 528 } |
| 529 | 529 |
| 530 if (!success && dialog_options.hDC) { | 530 if (!success && dialog_options.hDC) { |
| 531 DeleteDC(dialog_options.hDC); | 531 DeleteDC(dialog_options.hDC); |
| 532 hdc_ = NULL; | 532 context_ = NULL; |
| 533 } | 533 } |
| 534 | 534 |
| 535 if (dev_mode) { | 535 if (dev_mode) { |
| 536 GlobalUnlock(dialog_options.hDevMode); | 536 GlobalUnlock(dialog_options.hDevMode); |
| 537 } | 537 } |
| 538 } else { | 538 } else { |
| 539 if (dialog_options.hDC) { | 539 if (dialog_options.hDC) { |
| 540 DeleteDC(dialog_options.hDC); | 540 DeleteDC(dialog_options.hDC); |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 | 543 |
| 544 if (dialog_options.hDevMode != NULL) | 544 if (dialog_options.hDevMode != NULL) |
| 545 GlobalFree(dialog_options.hDevMode); | 545 GlobalFree(dialog_options.hDevMode); |
| 546 if (dialog_options.hDevNames != NULL) | 546 if (dialog_options.hDevNames != NULL) |
| 547 GlobalFree(dialog_options.hDevNames); | 547 GlobalFree(dialog_options.hDevNames); |
| 548 | 548 |
| 549 switch (dialog_options.dwResultAction) { | 549 switch (dialog_options.dwResultAction) { |
| 550 case PD_RESULT_PRINT: | 550 case PD_RESULT_PRINT: |
| 551 return hdc_ ? OK : FAILED; | 551 return context_ ? OK : FAILED; |
| 552 case PD_RESULT_APPLY: | 552 case PD_RESULT_APPLY: |
| 553 return hdc_ ? CANCEL : FAILED; | 553 return context_ ? CANCEL : FAILED; |
| 554 case PD_RESULT_CANCEL: | 554 case PD_RESULT_CANCEL: |
| 555 return CANCEL; | 555 return CANCEL; |
| 556 default: | 556 default: |
| 557 return FAILED; | 557 return FAILED; |
| 558 } | 558 } |
| 559 } | 559 } |
| 560 | 560 |
| 561 PrintingContext::Result PrintingContext::ParseDialogResult( | 561 PrintingContext::Result PrintingContext::ParseDialogResult( |
| 562 const PRINTDLG& dialog_options) { | 562 const PRINTDLG& dialog_options) { |
| 563 // If the user clicked OK or Apply then Cancel, but not only Cancel. | 563 // If the user clicked OK or Apply then Cancel, but not only Cancel. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 580 device_name = | 580 device_name = |
| 581 reinterpret_cast<const wchar_t*>( | 581 reinterpret_cast<const wchar_t*>( |
| 582 reinterpret_cast<const wchar_t*>(dev_names) + | 582 reinterpret_cast<const wchar_t*>(dev_names) + |
| 583 dev_names->wDeviceOffset); | 583 dev_names->wDeviceOffset); |
| 584 GlobalUnlock(dialog_options.hDevNames); | 584 GlobalUnlock(dialog_options.hDevNames); |
| 585 } | 585 } |
| 586 } | 586 } |
| 587 | 587 |
| 588 bool success = false; | 588 bool success = false; |
| 589 if (dev_mode && !device_name.empty()) { | 589 if (dev_mode && !device_name.empty()) { |
| 590 hdc_ = dialog_options.hDC; | 590 context_ = dialog_options.hDC; |
| 591 success = InitializeSettings(*dev_mode, device_name, NULL, 0, false); | 591 success = InitializeSettings(*dev_mode, device_name, NULL, 0, false); |
| 592 } | 592 } |
| 593 | 593 |
| 594 if (!success && dialog_options.hDC) { | 594 if (!success && dialog_options.hDC) { |
| 595 DeleteDC(dialog_options.hDC); | 595 DeleteDC(dialog_options.hDC); |
| 596 hdc_ = NULL; | 596 context_ = NULL; |
| 597 } | 597 } |
| 598 | 598 |
| 599 if (dev_mode) { | 599 if (dev_mode) { |
| 600 GlobalUnlock(dialog_options.hDevMode); | 600 GlobalUnlock(dialog_options.hDevMode); |
| 601 } | 601 } |
| 602 | 602 |
| 603 if (dialog_options.hDevMode != NULL) | 603 if (dialog_options.hDevMode != NULL) |
| 604 GlobalFree(dialog_options.hDevMode); | 604 GlobalFree(dialog_options.hDevMode); |
| 605 if (dialog_options.hDevNames != NULL) | 605 if (dialog_options.hDevNames != NULL) |
| 606 GlobalFree(dialog_options.hDevNames); | 606 GlobalFree(dialog_options.hDevNames); |
| 607 | 607 |
| 608 return hdc_ ? OK : FAILED; | 608 return context_ ? OK : FAILED; |
| 609 } | 609 } |
| 610 | 610 |
| 611 } // namespace printing | 611 } // namespace printing |
| OLD | NEW |