Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе описывается, как получить контекст устройства принтера. Вы можете получить контекст устройства принтера, вызвав функцию CreateDC напрямую, или он возвращается общим диалоговым окном печати .
При отображении окна печати в обычном диалоговом окне пользователь сможет выбрать принтер, страницы документа и количество копий документа, которые он хочет распечатать. Стандартное диалоговое окно печати возвращает эти выборы в структуре данных.
В этом разделе описывается, как получить контекст устройства принтера с помощью следующих методов.
Вызов CreateDC
Если вы знаете устройство, на которое вы хотите распечатать, можно вызвать CreateDC и передать эти сведения непосредственно в функцию. CreateDC возвращает контекст устройства, в котором можно отобразить содержимое для печати.
Самый простой вызов для получения контекста устройства показан в следующем примере кода. Код в этом примере извлекает контекст устройства для стандартного устройства отображения.
hDC = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
Чтобы выполнить отрисовку на определенном принтере, необходимо указать "WINSPOOL" в качестве устройства и передать правильное имя принтера в CreateDC. Можно также передать структуру DEVMODE в вызове CreateDC, если вы хотите предоставить специфичные для устройства данные инициализации для драйвера устройства при создании контекста устройства.
В следующем примере показан вызов CreateDC, в котором выбран драйвер WINSPOOL, а имя принтера указывается по имени.
printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL);
Вы можете получить точную строку имени принтера для передачи в CreateDC, вызвав функцию EnumPrinters. В следующем примере кода показано, как вызывать 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 до Windows 2000, или не требует дополнительных функций, которые предоставляет функция PrintDlgEx, используйте функцию PrintDlg. Ниже описано, как отобразить более старый стиль печатать обычное диалоговое окно.
- Инициализируйте структуру данных PRINTDLG.
- Вызовите PrintDlg для отображения стандартного диалогового окна печати пользователю.
- Если вызов PrintDlg возвращает TRUE, заблокируйте возвращенную память структуры DEVMODE. Если вызов PrintDlg возвращает FALSE, пользователь нажал кнопку "Отмена Cancel" в общем диалоговом окне Печать, поэтому больше ничего не требуется обрабатывать.
- Выделите достаточно большой локальный буфер памяти, чтобы содержать копию структуры 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 см. в разделе "Отображение диалогового окна печати" в Использование общих диалоговых окон.