如何取得印表機裝置上下文
本主題描述如何擷取印表機裝置內容。 您可以直接呼叫 CreateDC 函式來擷取印表機裝置內容,也可以由 列印 通用對話框傳回。
當您顯示 列印 一般對話框時,用戶將能夠選取印表機、檔的頁數,以及他們想要列印的檔複本數目。 列印 通用對話框會將這些選擇傳回至資料結構中。
本主題描述如何使用下列方法來取得印表機裝置內容。
- 呼叫 CreateDC
-
顯示列印通用對話框
- 使用 PrintDlgEx 函式
- 使用 PrintDlg 函式
呼叫 CreateDC
如果您知道要列印的裝置,您可以呼叫 CreateDC,並將該資訊直接傳遞至函式。 CreateDC 會傳回裝置內容,您可以在其中轉譯要列印的內容。
擷取裝置內容最簡單的呼叫會顯示在下列程式代碼範例中。 此範例中的程式碼會擷取預設顯示裝置的設備上下文。
hDC = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
若要轉譯至特定印表機,您必須將 「WINSPOOL」 指定為裝置,並將印表機的正確名稱傳遞至 CreateDC。 您也可以在呼叫 CreateDC 時傳遞 DEVMODE 結構,以便在建立裝置內容時,為裝置驅動程式提供裝置特定的初始化數據。
下列範例示範呼叫 createDC,其中已選取 「WINSPOOL」 驅動程式,並以名稱指定印表機名稱。
printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL);
您可以藉由呼叫 EnumPrinters 函式,取得要傳遞至 createDC 的確切列印機名稱字元串。 下列程式代碼範例示範如何呼叫 EnumPrinters,並取得本機和本機連線印表機的名稱。 因為無法事先知道所需緩衝區的大小,所以 EnumPrinters 會呼叫兩次。 第一次呼叫會傳回所需緩衝區的大小。 該資訊可用來配置所需大小的緩衝區,而第二次呼叫 EnumPrinters 會傳回您想要的數據。
fnReturn = EnumPrinters(
PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
1L, // printer info level
(LPBYTE)NULL,
0L,
&dwNeeded,
&dwReturned);
if (dwNeeded > 0)
{
pInfo = (PRINTER_INFO_1 *)HeapAlloc(
GetProcessHeap(), 0L, dwNeeded);
}
if (NULL != pInfo)
{
dwReturned = 0;
fnReturn = EnumPrinters(
PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
1L, // printer info level
(LPBYTE)pInfo,
dwNeeded,
&dwNeeded,
&dwReturned);
}
if (fnReturn)
{
// Review the information from all the printers
// returned by EnumPrinters.
for (i=0; i < dwReturned; i++)
{
// pThisInfo[i]->pName contains the printer
// name to use in the CreateDC function call.
//
// When this desired printer is found in the list of
// returned printer, set the printerName value to
// use in the call to CreateDC.
// printerName = pThisInfo[i]->pName
}
}
顯示列印通用對話框
您可以選擇兩個 列印 一般對話框來向用戶顯示:較新的對話框,您可以透過呼叫 PrintDlgEx 函式來顯示;以及較舊樣式的對話框,您可以透過呼叫 PrintDlg 函式來顯示。 下列各節說明如何從應用程式呼叫每個對話框。
使用 PrintDlgEx 函式
呼叫 PrintDlgEx 函式,以顯示 列印 屬性表。 藉由使用屬性表,用戶可以指定列印作業的相關信息。 例如,用戶可以選取要列印的頁面範圍、複本數目等等。 PrintDlgEx 也可以擷取所選印表機的設備上下文控制代碼。 您可以使用 句柄在印表機上轉譯輸出。
如需示範如何使用 PrintDlgEx 擷取印表機裝置內容的範例程式代碼,請參閱「使用通用對話框」下的「使用列印屬性表」。
使用 PrintDlg 函式
如果您的應用程式必須在不支援 PrintDlgEx 函式的系統上執行,例如在執行 Windows 2000 之前的 Windows 版本,或不需要 PrintDlgEx 函式所提供的額外功能,請使用 printDlg函式。 下列步驟說明如何顯示舊樣式 列印 一般對話方塊。
- 初始化 PRINTDLG 數據結構。
- 呼叫 PrintDlg,向用戶顯示 列印 通用對話方塊。
- 如果 printDlg呼叫傳回 TRUE ,請鎖定傳回的 DEVMODE 結構記憶體。 如果 PrintDlg 呼叫傳回 FALSE,那麼表示使用者在 [列印] 通用對話框中按下了 [取消] 按鈕,因此不需要進一步處理。
- 配置一個本機記憶體緩衝區,其大小足以包含一份 DEVMODE 結構的副本。
- 將傳回的 DEVMODE 結構複製到本地分配的結構。
- 請儲存從 PRINTDLG 結構中傳回的其他資訊,這些資訊將是您處理列印作業所需的。
- 釋放 PRINTDLG,以及它所指向的記憶體緩衝區。
下列範例程式代碼說明如何使用 PrintDlg 函式來取得裝置內容和所選印表機的名稱。
// Display the printer dialog box so the user can select the
// printer and the number of copies to print.
BOOL printDlgReturn = FALSE;
HDC printerDC = NULL;
PRINTDLG printDlgInfo = {0};
LPWSTR localPrinterName = NULL;
PDEVMODE returnedDevmode = NULL;
PDEVMODE localDevmode = NULL;
int localNumberOfCopies = 0;
// Initialize the print dialog box's data structure.
printDlgInfo.lStructSize = sizeof( printDlgInfo );
printDlgInfo.Flags =
// Return a printer device context.
PD_RETURNDC
// Don't allow separate print to file.
// Remove these flags if you want to support this feature.
| PD_HIDEPRINTTOFILE
| PD_DISABLEPRINTTOFILE
// Don't allow selecting individual document pages to print.
// Remove this flag if you want to support this feature.
| PD_NOSELECTION;
// Display the printer dialog and retrieve the printer DC.
printDlgReturn = PrintDlg(&printDlgInfo);
// Check the return value.
if (TRUE == printDlgReturn)
{
// The user clicked OK so the printer dialog box data
// structure was returned with the user's selections.
// Copy the relevant data from the data structure and
// save them to a local data structure.
//
// Get the HDC of the selected printer
printerDC = printDlgInfo.hDC;
// In this example, the DEVMODE structure returned by
// the printer dialog box is copied to a local memory
// block and a pointer to the printer name that is
// stored in the copied DEVMODE structure is saved.
//
// Lock the handle to get a pointer to the DEVMODE structure.
returnedDevmode = (PDEVMODE)GlobalLock(printDlgInfo.hDevMode);
localDevmode = (LPDEVMODE)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
returnedDevmode->dmSize);
if (NULL != localDevmode)
{
memcpy(
(LPVOID)localDevmode,
(LPVOID)returnedDevmode,
returnedDevmode->dmSize);
// Save the printer name from the DEVMODE structure.
// This is done here just to illustrate how to access
// the name field. The printer name can also be accessed
// by referring to the dmDeviceName in the local
// copy of the DEVMODE structure.
localPrinterName = localDevmode->dmDeviceName;
// Save the number of copies as entered by the user
localNumberOfCopies = printDlgInfo.nCopies;
}
else
{
// Unable to allocate a new structure so leave
// the pointer as NULL to indicate that it's empty.
}
// Free the DEVMODE structure returned by the print
// dialog box.
if (NULL != printDlgInfo.hDevMode)
{
GlobalFree(printDlgInfo.hDevMode);
}
}
else
{
// The user cancelled out of the print dialog box.
}
如需有關 PrintDlg 函式的詳細資訊,請參閱在《使用一般對話方塊》中的「顯示列印對話方塊」。