Поделиться через


Печать настольных приложений

В этом разделе описывается, как печатать из стандартной программы для рабочего стола Windows.

Обзор

Чтобы обеспечить лучший пользовательский интерфейс при печати из собственной программы Windows, программа должна быть разработана для печати из выделенного потока. В собственной программе Windows программа отвечает за управление событиями и сообщениями пользовательского интерфейса. Для операций печати могут потребоваться интенсивные вычисления, так как содержимое приложения рендерится для принтера, что может помешать программе реагировать на пользовательские взаимодействия, если это выполняется в том же потоке, что и обработка пользовательских событий.

Если вы уже знакомы с тем, как написать многопотоковую нативную программу для Windows, перейдите непосредственно к разделу как распечатать из приложения Windows и узнайте, как добавить функциональность печати в вашу программу.

Основные требования к программе Windows

Для повышения производительности и реагирования на работу программы не выполняйте обработку заданий печати программы в потоке, который обрабатывает взаимодействие с пользователем.

Это разделение печати от взаимодействия с пользователем будет влиять на то, как программа управляет данными приложения. Прежде чем приступить к написанию приложения, необходимо тщательно понять эти последствия. В следующих разделах описаны основные требования к обработке печати в отдельном потоке программы.

Основные сведения о программе Windows

Собственная программа Windows должна предоставить процедуру главного окна для обработки сообщений окна, получаемых из операционной системы. Каждое окно в программе Windows имеет соответствующую функцию WndProc, обрабатывающую эти сообщения окон. Поток, в котором выполняется эта функция, называется потоком пользовательского интерфейса или UI-потоком.

Используйте ресурсы для строк.
Используйте строковые ресурсы из файла ресурсов программы вместо строковых констант для строк, которые могут быть изменены при поддержке другого языка. Прежде чем программа сможет использовать строковый ресурс в качестве строки, программа должна получить ресурс из файла ресурса и скопировать его в локальный буфер памяти. Это требует дополнительного программирования в начале, но позволяет упростить изменение, перевод и локализацию программы в будущем.
обработка данных в шагах.
Обрабатывайте задание печати пошагово, чтобы его можно было прервать. Эта конструкция позволяет пользователю отменить длинную операцию обработки до завершения и предотвратить блокировку других программ, которые могут выполняться одновременно.
Использовать пользовательские данные окна.
В приложениях печати часто есть несколько окон и потоков. Чтобы обеспечить доступность данных между потоками и этапами обработки без использования статических глобальных переменных, ссылайтесь на структуры данных указателем данных, который является частью окна, в котором они используются.

В следующем примере кода показана основная точка входа для приложения печати. В этом примере показано, как использовать строковые ресурсы вместо строковых констант, а также основной цикл сообщений, обрабатывающий сообщения окна программы.

int APIENTRY 
wWinMain(
        HINSTANCE hInstance, 
        HINSTANCE hPrevInstance, 
        LPWSTR lpCmdLine, 
        int nCmdShow
)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    MSG msg;
    HACCEL hAccelTable;
    HRESULT hr = S_OK;

    // Register the main window class name
    WCHAR szWindowClass[MAXIMUM_RESOURCE_STRING_LENGTH];            
    LoadString(
        hInstance, 
        IDC_PRINTSAMPLE, 
        szWindowClass, 
        MAXIMUM_RESOURCE_STRING_LENGTH);
    MyRegisterClass(hInstance, szWindowClass);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        // Unable to initialize this instance of the application
        //  so display error message and exit
        MessageBoxWithResourceString (
            hInstance, 
            GetDesktopWindow(), 
            IDS_ERROR_INSTINITFAIL, 
            IDS_CAPTION_ERROR, 
            (MB_OK | MB_ICONEXCLAMATION));
        return FALSE;
    }    
    
    // Init COM for printing interfaces
    if (FAILED(hr = CoInitializeEx(0, COINIT_MULTITHREADED)))
    {
        // Unable to initialize COM
        //  so display error message and exit
        MessageBoxWithResourceString (
            hInstance, 
            GetDesktopWindow(), 
            IDS_ERROR_COMINITFAIL, 
            IDS_CAPTION_ERROR, 
            (MB_OK | MB_ICONEXCLAMATION));
        return FALSE;
    }

    hAccelTable = LoadAccelerators(
                    hInstance, 
                    MAKEINTRESOURCE(IDC_PRINTSAMPLE));

    // Main message handling loop
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    // Uninitialize (close) the COM interface
    CoUninitialize();

    return (int) msg.wParam;
}

Сведения о документе

Windows-программы, предназначенные для печати, должны быть спроектированы с учётом многопоточной обработки. Одним из требований многопоточных проектов является защита элементов данных программы, чтобы они были безопасными для нескольких потоков, используемых одновременно. Элементы данных можно защитить с помощью объектов синхронизации и упорядочить данные, чтобы избежать конфликтов между потоками. В то же время программа должна предотвратить изменения данных программы во время печати. В примере программы используется несколько различных многопоточных методов программирования.

События синхронизации
В примере программы используются события, дескриптора потоков и функции ожидания для синхронизации обработки между потоком печати и основной программой, а также для указания того, что данные используются.
Application-Specific сообщения Windows
Пример программы использует сообщения окна для конкретного приложения, чтобы сделать программу более совместимой с другими собственными программами Windows. Разбиение обработки на меньшие шаги и постановка этих шагов в очередь в цикле сообщений окна упрощает Windows управление обработкой без блокировки других приложений, которые также могут работать на компьютере.
структуры данных
Пример программы не написан в объектно-ориентированном стиле, используя объекты и классы, хотя он группирует элементы данных в структуры данных. В примере не используется объектно-ориентированный подход, чтобы избежать того, что один подход лучше или хуже другого.
Функции и структуры данных примера программы можно использовать в качестве отправной точки при разработке программы. Независимо от того, решите ли вы разработать объектно-ориентированное приложение или нет, важно учитывать, что необходимо сгруппировать связанные элементы данных, чтобы их можно было безопасно использовать в разных потоках.

Контекст устройства принтера

При печати может потребоваться отобразить содержимое, которое будет напечатано в контексте устройства. Практическое руководство. Получение контекста устройства принтера описывает различные способы получения контекста устройства принтера.

Печать из приложения Windows