方法: プリンター デバイス コンテキストを取得する
このトピックでは、プリンター デバイス コンテキストを取得する方法について説明します。 CreateDC 関数を直接呼び出してプリンター デバイス コンテキストを取得することも、[印刷] 共通ダイアログ ボックスで返すこともできます。
[ 印刷 ] 共通ダイアログ ボックスを表示すると、ユーザーはプリンター、文書のページ、印刷するドキュメント のコピー数を選択できます。 [ 印刷 ] 共通ダイアログ ボックスは、データ構造でこれらの選択内容を返します。
このトピックでは、次の方法を使用してプリンター デバイス コンテキストを取得する方法について説明します。
CreateDC を呼び出す
印刷するデバイスがわかっている場合は、 CreateDC を呼び出して、その情報を関数に直接渡すことができます。 CreateDC は、印刷するコンテンツをレンダリングできるデバイス コンテキストを返します。
デバイス コンテキストを取得するための最も簡単な呼び出しを次のコード例に示します。 この例のコードでは、デバイス コンテキストを既定のディスプレイ デバイスに取得します。
hDC = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
特定のプリンターにレンダリングするには、デバイスとして "WINSPOOL" を指定し、プリンターの正しい名前を CreateDC に渡す必要があります。 デバイス コンテキストを作成するときにデバイス ドライバーにデバイス固有の初期化データを提供する場合は、CreateDC の呼び出しで DEVMODE 構造体を渡すこともできます。
次の例は、"WINSPOOL" ドライバーが選択され、プリンター名が名前で指定されている CreateDC の呼び出しを示しています。
printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL);
EnumPrinters 関数を呼び出すことで、CreateDC に渡す正確なプリンター名文字列を取得できます。 次のコード例は 、EnumPrinters を呼び出し、ローカルおよびローカルに接続されているプリンターの名前を取得する方法を示しています。 必要なバッファーのサイズを事前に確認できないため、 EnumPrinters は 2 回呼び出されます。 最初の呼び出しは、必要なバッファーのサイズを返します。 この情報は、必要なサイズのバッファーを割り当てるために使用され、 EnumPrinters の 2 回目の呼び出しでは、必要なデータが返されます。
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
}
}
[印刷の共通] ダイアログ ボックスを表示する
ユーザーに表示する 2 つの [印刷 ] 共通ダイアログ ボックスから選択できます。 PrintDlgEx 関数を呼び出すことで表示できる新しいダイアログ ボックスと、 PrintDlg 関数を呼び出して表示できる古いスタイルのダイアログ ボックス。 次のセクションでは、アプリケーションから各ダイアログ ボックスを呼び出す方法について説明します。
PrintDlgEx 関数の使用
PrintDlgEx 関数を呼び出して、Print プロパティ シートを表示します。 プロパティ シートを使用すると、ユーザーは印刷ジョブに関する情報を指定できます。 たとえば、ユーザーは印刷するページの範囲、部数などを選択できます。 PrintDlgEx は、選択したプリンターのデバイス コンテキストへのハンドルを取得することもできます。 ハンドルを使用して、プリンターに出力をレンダリングできます。
PrintDlgEx を使用してプリンター デバイス コンテキストを取得するサンプル コードについては、「共通ダイアログ ボックスの使用」の「Print プロパティ シートの使用」を参照してください。
PrintDlg 関数の使用
Windows 2000 より前のバージョンの Windows を実行しているシステムなど、 PrintDlgEx 関数をサポートしていないシステムでアプリケーションを実行する必要がある場合、または 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 関数の詳細については、「共通ダイアログ ボックスの使用」の「印刷ダイアログ ボックスの表示」を参照してください。