Изменение параметров принтера с помощью функции DocumentProperties()
В этой статье показано, как изменить параметры принтера с помощью DocumentProperties()
функции .
Исходная версия продукта: Принтера
Исходный номер базы знаний: 167345
Сводка
Использовать структуру DEVMODE для изменения параметров принтера сложнее, чем просто изменить поля структуры. В частности, допустимая структура DEVMODE для устройства содержит частные данные, которые могут быть изменены только функцией DocumentProperties()
.
В этой статье объясняется, как изменить содержимое структуры DEVMODE с помощью DocumentProperties()
функции .
Дополнительная информация
Структура DEVMODE, как описано в пакете SDK для Win32, содержит общедоступные или "независимые от устройства данные", а также частные или "зависимые от устройства данные". Частная часть DEVMODE существует сразу после общедоступной части, определенной структурой DEVMODE, в непрерывном буфере памяти.
Программа не может предсказать размер этого буфера, так как он отличается от принтера к принтеру и от версии к версии драйвера принтера. Кроме того, структура DEVMODE, объявленная программой, не содержит достаточно места для данных частных устройств. Если буфер DEVMODE, в который отсутствуют частные данные, передается в такие функции, как CreateDC()
, ResetDC()
и DocumentProperties()
, функция может завершиться ошибкой.
Чтобы надежно использовать DEVMODE с драйвером устройства, создайте и измените его, выполнив следующие действия.
Определите требуемый размер буфера с устройства, а затем выделите для него достаточно памяти.
DocumentProperties()
возвращает количество байтов, необходимых для буфера DEVMODE, если для последнего параметра задано значение 0. В примере кода в этой статье используется этот метод для определения правильного размера буфера. Затем в примере кода используется функция выделения памяти во время выполнения C для выделения достаточно большогоmalloc()
буфера. Так какDocumentProperties()
функции, такие какResetDC()
и ,CreateDC()
принимают указатели на DEVMODE в качестве параметра, большинство приложений могут выделять память, адресуемую указателем.Однако такие функции, как общие
PrintDlg()
, принимают параметры, необходимые для обработки, в глобальную память. Если программа использует окончательный буфер DEVMODE в качестве параметра для одной из этих функций, она должна выделить память с помощьюGlobalAlloc()
и получить указатель на буфер с помощьюGlobalLock()
.Попросите драйвер устройства инициализировать буфер DEVMODE с параметрами по умолчанию.
Пример кода вызывает
DocumentProperties()
второй раз для инициализации выделенного буфера с текущими параметрами по умолчанию.DocumentProperties()
Заполняет буфер, называемый параметром pDevModeOutput , текущими параметрами принтера приDM_OUT_BUFFER
передаче команды в параметре fMode.Внесите изменения в общедоступную часть DEVMODE и попросите драйвер устройства объединить изменения в частную часть DEVMODE, вызвав
DocumentProperties()
.После инициализации буфера с текущими параметрами на шаге 2 пример кода вносит изменения в общедоступную часть DEVMODE. Описание элементов DEVMODE см. в документации по пакету SDK для Win32. Этот пример кода определяет, может ли принтер использовать параметры ориентации и дуплексных (двусторонних) и изменяет их соответствующим образом.
Примечание.
Флаг в члене dmFields DEVMODE является только признаком того, что принтер использует связанный элемент структуры. Принтеры имеют различные физические характеристики и поэтому могут поддерживать только подмножество задокументированных возможностей DEVMODE. Чтобы определить поддерживаемые параметры поля DEVMODE, приложения должны использовать
DeviceCapabilities()
.Затем пример кода выполняет третий вызов
DocumentProperties()
и передает буфер DEVMODE в параметрах pDevModeInput и pDevModeOutput. Он также передает объединенные команды DM_IN_BUFFER и DM_OUT_BUFFER в параметре fMode с помощью оператора OR("|"). Эти команды сообщают функции принять все параметры, содержащиеся во входном буфере, и объединить их с текущими параметрами устройства. Затем он записывает результат в буфер, указанный в параметре out.
Примечание.
DocumentProperties()
ссылается на конкретный принтер с помощью дескриптора к принтеру: hPrinter. Этот дескриптор получен из OpenPrinter()
, который также иллюстрирует пример кода. OpenPrinter()
требуется имя принтера, которое обычно является понятным именем принтера, которое отображается в оболочке операционной системы. Это имя можно получить из EnumPrinters()
, из структуры DEVNAMES, возвращаемой PrintDlg()
, или из принтера по умолчанию.
В этой статье первые два шага выделения правильного размера буфера и инициализации этого буфера выполняются с помощью DocumentProperties()
. Эти действия также можно выполнить с помощью GetPrinter()
.
Дополнительные сведения и пример см. в статье Изменение параметров принтера с помощью функции SetPrinter.
Пример кода
Пример кода выполняет следующие три шага для получения и изменения буфера DEVMODE. Функция принимает именованный принтер и настраивает DEVMODE для печати двусторонней и в альбомной ориентации, если она поддерживает эти функции. Результирующий объект DEVMODE, возвращаемый вызывающей объекту, подходит для других вызовов API, использующих буферы DEVMODE, таких как CreateDC()
, SetPrinter()
, PrintDlg()
или ResetDC()
. Когда вызывающий объект завершил работу с помощью буфера DEVMODE, вызывающий объект отвечает за освобождение памяти.
LPDEVMODE GetLandscapeDevMode(HWND hWnd, char *pDevice)
{
HANDLE hPrinter;
LPDEVMODE pDevMode;
DWORD dwNeeded, dwRet;
/* Start by opening the printer */
if (!OpenPrinter(pDevice, &hPrinter, NULL))
return NULL;
/*
* Step 1:
* Allocate a buffer of the correct size.
*/
dwNeeded = DocumentProperties(hWnd,
hPrinter, /* Handle to our printer. */
pDevice, /* Name of the printer. */
NULL, /* Asking for size, so */
NULL, /* these are not used. */
0); /* Zero returns buffer size. */
pDevMode = (LPDEVMODE)malloc(dwNeeded);
/*
* Step 2:
* Get the default DevMode for the printer and
* modify it for your needs.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* The address of the buffer to fill. */
NULL, /* Not using the input buffer. */
DM_OUT_BUFFER); /* Have the output buffer filled. */
if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
ClosePrinter(hPrinter);
return NULL;
}
/*
* Make changes to the DevMode which are supported.
*/
if (pDevMode->dmFields & DM_ORIENTATION)
{
/* If the printer supports paper orientation, set it.*/
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}
if (pDevMode->dmFields & DM_DUPLEX)
{
/* If it supports duplex printing, use it. */
pDevMode->dmDuplex = DMDUP_HORIZONTAL;
}
/*
* Step 3:
* Merge the new settings with the old.
* This gives the driver an opportunity to update any private
* portions of the DevMode structure.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* Reuse our buffer for output. */
pDevMode, /* Pass the driver our changes. */
DM_IN_BUFFER | /* Commands to Merge our changes and */
DM_OUT_BUFFER); /* write the result. */
/* Finished with the printer */
ClosePrinter(hPrinter);
if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
return NULL;
}
/* Return the modified DevMode structure. */
return pDevMode;
}
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по