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

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

Общие сведения

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

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

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

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

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

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

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

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

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

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, которые печатают, должны быть разработаны для многопотоковой обработки. Одним из требований многопотокового проектирования является защита элементов данных программы, чтобы они были безопасными для одновременного использования нескольких потоков. Вы можете защитить элементы данных с помощью объектов синхронизации и упорядочения данных, чтобы избежать конфликтов между потоками. В то же время программа должна предотвращать изменения данных программы во время их печати. В примере программы используется несколько различных многопоточных методов программирования.

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

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

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

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