傳統型應用程式列印
本節說明如何從原生 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 程式應該設計為多執行緒處理。 多執行緒設計的其中一個需求是保護程式的資料元素,以便讓多個執行緒同時使用安全。 您可以使用同步處理物件並組織資料來保護資料元素,以避免執行緒之間的衝突。 同時,程式必須在列印程式資料時防止變更程式資料。 此範例程式使用數種不同的多執行緒程式設計技術。
同步處理事件
範例程式會使用事件、執行緒控制碼和等候函式來同步處理列印執行緒與主程式之間的處理,並指出資料正在使用中。
應用程式特定的 Windows 訊息
範例程式會使用應用程式特定的視窗訊息,讓程式與其他原生 Windows 程式更相容。 將處理分成較小的步驟,並將視窗訊息迴圈中的這些步驟排入佇列,可讓 Windows 更輕鬆地管理處理,而不會封鎖可能也在電腦上執行的其他應用程式。
資料結構
雖然範例程式不會使用物件和類別,以物件導向樣式撰寫,不過它會將資料元素分組到資料結構中。 此範例不會使用物件導向的方法,以避免表示某個方法比另一種方法更好或更糟。
您可以在設計程式時,使用範例程式的函式和資料結構作為起點。 無論您決定要設計物件導向程式,請務必記住的重要設計考慮是將相關的資料元素分組,以便視需要在不同的執行緒中安全地使用這些元素。
印表機裝置內容
列印時,您可能會想要將內容轉譯為列印到裝置內容。 如何:擷取印表機裝置內容 描述您可以取得印表機裝置內容的不同方式。
相關主題