Print in windows application

Desktop App Printing

This section describes how to print from a native Windows desktop program.

Overview

To provide the best user experience when you print from a native Windows program, the program must be designed to print from a dedicated thread. In a native Windows program, the program is responsible for managing user interface events and messages. Printing operations can require periods of intense computation as the application content is rendered for the printer, which can prevent the program from responding to user interaction if this processing is performed in the same thread as event processing of the user interaction.

If you are already familiar with how to write a multi-threaded native Windows program, you go directly to How to print from a Windows application and learn how to add printing functionality to your program.

Basic Windows Program Requirements

For best performance and program responsiveness, do not perform a program’s print job processing in the thread that processes user interaction.

This separation of printing from user interaction will influence how the program manages the application data. You should thoroughly understand these implications before you start writing the application. The following topics describe the basic requirements of handling printing in a separate thread of a program.

Windows Program Basics

A native Windows program must provide the main window procedure to process the window messages that it receives from the operating system. Every window in a Windows program has a corresponding WndProc function that processes these window messages. The thread in which this function runs is called the user interface, or UI, thread.

Use resources for strings.
Use string resources from the program’s resource file instead of string constants for strings that might need to be changed when you support another language. Before a program can use a string resource as a string, the program must retrieve the resource from the resource file and copy it to a local memory buffer. This requires some additional programming in the beginning, but allows for easier modification, translation, and localization of the program in the future.
Process data in steps.
Process the print job in steps that can be interrupted. This design makes it possible for the user to cancel a long processing operation before it completes and prevents the program from blocking other programs that might be running at the same time.
Use window user data.
Printing applications often have several windows and threads. To keep the data available between threads and processing steps without using static, global variables, reference the data structures by a data pointer that is part of the window in which they are used.

The following code example shows a main entry point for a printing application. This example shows how to use string resources instead of string constants and also shows the main message loop that processes the program’s window messages.

Document Information

Native Windows programs that print should be designed for multi-threaded processing. One of the requirements of a multi-threaded design is to protect the program’s data elements so that they are safe for multiple threads to use at the same time. You can protect data elements by using synchronization objects and organizing the data to avoid conflicts between the threads. At the same time, the program must prevent changes to the program data while it is being printed. The sample program uses several different multi-threaded programming techniques.

Synchronization Events
The sample program uses events, thread handles, and wait functions to synchronize the processing between the print thread and the main program and to indicate that the data is in use.
Application-Specific Windows Messages
The sample program uses application-specific window messages to make the program more compatible with other native Windows programs. Breaking the processing into smaller steps and queuing those steps in the window message loop makes it easier for Windows to manage the processing without blocking other applications that might also be running on the computer.
Data Structures
The sample program is not written in an object-oriented style using objects and classes, although it does group data elements into data structures. The sample does not use an object-oriented approach to avoid implying that one approach is better or worse than another.
You can use the functions and data structures of the sample program as a starting point when you design your program. Whether you decide to design an object-oriented program or not, the important design consideration to remember is to group the related data elements so that you can use them safely in different threads as necessary.

Читайте также:  Sony vpceh установка windows

Printer Device Context

When printing, you might want to render the content to be printed to a device context. How To: Retrieve a Printer Device Context describes the different ways that you can obtain a printer device context.

How To: Print from a Windows Program

This section describes how to print from a native Windows program.

Overview

Printing is usually an integral part of a native Windows program. Therefore, it is not a feature that you can add easily after you have written the program. That being said, if the program is designed to use XPS documents it will not need much, if any, additional code to render the document content for printing. The XPS documents of the application can be sent directly to a printer that has an XPSDrv printer driver.

Use the XPS Document API to create the document content and the XPS Print API to send the document content to the printer. The XPS Print API processes the document content for the destination printer. If the selected printer has an XPSDrv printer driver, the document will be sent to the printer without any additional conversion. If the selected printer has a GDI-based printer driver, the program can also send the content to the printer, and the XPS Print API converts the document content so that it will be compatible with the GDI-based printer driver. In either case, the processing that the application performs is the same.

Printing tasks

The following topics describe the basic steps of printing program content.

Collect print job information from user.

Typically, a user initiates a print job when they select the print option from a menu and the program displays a print dialog box to collect the details of the print job. The user typically selects the printer, the number of copies, and printer configuration details such as two-sided printing and stapling.

Create progress indicator.

A progress indicator provides the user with feedback about how the print job is progressing. The progress indicator can be a progress bar that is part of a dialog box that includes the Cancel button for the job, or it can be a progress bar in the status bar at the bottom of the main window.

For information about the progress indicator works, see How To: Display the Print Job Progress.

For more ideas about how to display the progress of the print job, see the information in the Windows Application UI Development guidelines.

Start the printing thread.

After the program has collected the print job information from the user, it can start the printing thread to perform the actual processing of the document for printing.

For information about the printing thread, see How To: Start and Stop a Printing Thread.

Render print job data.

The printing thread renders the document data for printing. You should break down this processing into discrete processing steps so that the user can interrupt the processing and cancel the job as well as to not allow the processing thread to block other threads and processes.

For information about how the renders the print job data, see How To: Render Print Job Data.

Monitor print job progress.

As each processing step is performed, update the progress bar to inform the use. Compute the processing steps to complete the requested job and then updates the progress bar as those steps are performed.

Close print job and terminate printing thread.

After the program has sent the print job to the printer, or if the user has cancelled the print job, you must close the print job and release the resources used by the print job.

Print from your app

Important APIs

Learn how to print documents from a Universal Windows app. This topic also shows how to print specific pages. For more advanced changes to the print preview UI, see Customize the print preview UI.

В Most of the examples in this topic are based on the Universal Windows Platform (UWP) print sample, which is part of the Universal Windows Platform (UWP) app samples repo on GitHub.

Register for printing

The first step to add printing to your app is to register for the Print contract. Your app must do this on every screen from which you want your user to be able to print. Only the screen that is displayed to the user can be registered for printing. If one screen of your app has registered for printing, it must unregister for printing when it exits. If it is replaced by another screen, the next screen must register for a new Print contract when it opens.

Читайте также:  Обычные обои windows 10

В If you need to support printing from more than one page in your app, you can put this print code in a common helper class and have your app pages reuse it. For an example of how to do this, see the PrintHelper class in the UWP print sample.

First, declare the PrintManager and PrintDocument. The PrintManager type is in the Windows.Graphics.Printing namespace along with types to support other Windows printing functionality. The PrintDocument type is in the Windows.UI.Xaml.Printing namespace along with other types that support preparing XAML content for printing. You can make it easier to write your printing code by adding the following using or Imports statements to your page.

The PrintDocument class is used to handle much of the interaction between the app and the PrintManager, but it exposes several callbacks of its own. During registration, create instances of PrintManager and PrintDocument and register handlers for their printing events.

In the UWP print sample, registration is performed by the RegisterForPrinting method.

When the user goes to a page that supports printing, it initiates the registration within the OnNavigatedTo method.

In the sample, the event handlers are unregistered in the UnregisterForPrinting method.

When the user leaves a page that supports printing, the event handlers are unregistered within the OnNavigatedFrom method.

If you have a multiple-page app and don’t disconnect printing, an exception is thrown when the user leaves the page and then returns to it.

Create a print button

Add a print button to your app’s screen where you’d like it to appear. Make sure that it doesn’t interfere with the content that you want to print.

Next, add an event handler to your app’s code to handle the click event. Use the ShowPrintUIAsync method to start printing from your app. ShowPrintUIAsync is an asynchronous method that displays the appropriate printing window. We recommend calling the IsSupported method first in order to check that the app is being run on a device that supports printing (and handle the case in which it is not). If printing can’t be performed at that time for any other reason, ShowPrintUIAsync will throw an exception. We recommend catching these exceptions and letting the user know when printing can’t proceed.

In this example, a print window is displayed in the event handler for a button click. If the method throws an exception (because printing can’t be performed at that time), a ContentDialog control informs the user of the situation.

Format your app’s content

When ShowPrintUIAsync is called, the PrintTaskRequested event is raised. The PrintTaskRequested event handler shown in this step creates a PrintTask by calling the PrintTaskRequest.CreatePrintTask method and passes the title for the print page and the name of a PrintTaskSourceRequestedHandler delegate. Notice that in this example, the PrintTaskSourceRequestedHandler is defined inline. The PrintTaskSourceRequestedHandler provides the formatted content for printing and is described later.

In this example, a completion handler is also defined to catch errors. It’s a good idea to handle completion events because then your app can let the user know if an error occurred and provide possible solutions. Likewise, your app could use the completion event to indicate subsequent steps for the user to take after the print job is successful.

After the print task is created, the PrintManager requests a collection of print pages to show in the print preview UI by raising the Paginate event. This corresponds with the Paginate method of the IPrintPreviewPageCollection interface. The event handler you created during registration will be called at this time.

В If the user changes print settings, the paginate event handler will be called again to allow you to reflow the content. For the best user experience, we recommend checking the settings before you reflow the content and avoid reinitializing the paginated content when it’s not necessary.

In the Paginate event handler (the CreatePrintPreviewPages method in the UWP print sample), create the pages to show in the print preview UI and to send to the printer. The code you use to prepare your app’s content for printing is specific to your app and the content you print. Refer to the UWP print sample source code to see how it formats its content for printing.

Читайте также:  Astra linux запуск deb

When a particular page is to be shown in the print preview window, the PrintManager raises the GetPreviewPage event. This corresponds with the MakePage method of the IPrintPreviewPageCollection interface. The event handler you created during registration will be called at this time.

In the GetPreviewPage event handler (the GetPrintPreviewPage method in the UWP print sample), set the appropriate page on the print document.

Finally, once the user clicks the print button, the PrintManager requests the final collection of pages to send to the printer by calling the MakeDocument method of the IDocumentPageSource interface. In XAML, this raises the AddPages event. The event handler you created during registration will be called at this time.

In the AddPages event handler (the AddPrintPages method in the UWP print sample), add pages from the page collection to the PrintDocument object to be sent to the printer. If a user specifies particular pages or a range of pages to print, you use that information here to add only the pages that will actually be sent to the printer.

Prepare print options

Next prepare print options. As an example, this section will describe how to set the page range option to allow printing of specific pages. For more advanced options, see Customize the print preview UI.

This step creates a new print option, defines a list of values that the option supports, and then adds the option to the print preview UI. The page range option has these settings:

Option name Action
Print all Print all pages in the document.
Print Selection Print only the content the user selected.
Print Range Display an edit control into which the user can enter the pages to print.

Clear the list of options that are shown in the print preview UI and add the options that you want to display when the user wants to print from the app.

В The options appear in the print preview UI in the same order they are appended, with the first option shown at the top of the window.

Create the new print option and initialize the list of option values.

Add your custom print option and assign the event handler. The custom option is appended last so that it appears at the bottom of the list of options. But you can put it anywhere in the list, custom print options don’t need to be added last.

The CreateTextOption method creates the Range text box. This is where the user enters the specific pages they want to print when they select the Print Range option.

Handle print option changes

The OptionChanged event handler does two things. First, it shows and hides the text edit field for the page range depending on the page range option that the user selected. Second, it tests the text entered into the page range text box to make sure that it represents a valid page range for the document.

This example shows how print option change events are handled in the UWP print sample.

В See the GetPagesInRange method in the UWP print sample for details on how to parse the page range the user enters in the Range text box.

Preview selected pages

How you format your app’s content for printing depends on the nature of your app and its content. A print helper class in used in the UWP print sample to format the content for printing.

When printing a subset of pages, there are several ways to show the content in the print preview. Regardless of the method you chose to show the page range in the print preview, the printed output must contain only the selected pages.

  • Show all the pages in the print preview whether a page range is specified or not, leaving the user to know which pages will actually be printed.
  • Show only the pages selected by the user’s page range in the print preview, updating the display whenever the user changes the page range.
  • Show all the pages in print preview, but grey out the pages that are not in page range selected by the user.
Оцените статью