Як змінити параметри принтера, з функцією DocumentProperties()


Загальні відомості


Змінення параметрів принтера за допомогою DEVMODE структура є досить складно, ніж просто зміни в полях структури. Зокрема, дійсний DEVMODE структуру для пристрою, містить особисті дані, які можуть бути змінені функції DocumentProperties() .

У цій статті описано процес змінення вмісту DEVMODE структуру з функцією DocumentProperties() .

Додаткові відомості


DEVMODE структуру, як описано на Win32 SDK, містить, громадських або "пристрою незалежного даних" а також особисті або "пристрій залежні дані". Приватна частина DEVMODE існує, після спільних частина, яка, що визначає структуру DEVMODE , буфер безперервної пам'яті.

Програми, не може передбачати розмір буфера, це через те, що вона відрізняється від принтера до принтера та від версії драйвера принтера. Крім того, структуру DEVMODE , просто оголошується програми, не містить достатньо місця для приватного пристрій даних. У разі прийняття DEVMODE буфера, що не особистих даних функцій, таких як CreateDC(), ResetDC()і DocumentProperties()функція може не вдатися.

Надійно DEVMODE за допомогою драйвер пристрою, створення та змінити його, виконавши такі дії:

  1. Визначити необхідні розмір буфера пристрою а потім виділити достатньо пам'яті для нього.

    DocumentProperties() повертає байт, необхідних для DEVMODE буфер під час останнього параметр має значення 0. У зразку коду цієї статті використовує цей метод, щоб визначити правильний розмір буфера. Приклад коду використовується функція розподілу пам'яті для виконання C з malloc() виділити буфер, достатньо великий. Через те, що DocumentProperties() та функції, такі як ResetDC() і CreateDC() потрібно вказівники DEVMODE, як параметр, більшість програм, може виділити пам'ять, яка має вирішити вказівника.

    Тим не менш, функції, наприклад, загальних PrintDlg() прийняти параметри, які необхідно буде дескрипторами глобального пам'яті. Програми, які використовують остаточний DEVMODE буфер як параметр для однієї з цих функцій, слід виділити пам'ять, використовуючи GlobalAlloc() та отримати вказівник на буфера, використовуючи GlobalLock().
  2. Запитайте драйвер пристрою для ініціалізації DEVMODE буфер з параметрами за промовчанням.

    Приклад коду викликає DocumentProperties() ще раз для ініціалізації буфера з поточними настройками за промовчанням. DocumentProperties() заповнює в буфер, який називається pDevModeOutput параметр принтера, поточні настройки після того, як передається команда DM_OUT_BUFFER fMode параметр.
  3. Внесення змін до спільних частину до DEVMODE і запитайте драйвер пристрою для злиття приватних частину до DEVMODE зміни, зателефонувавши за номером DocumentProperties().

    Після ініціалізації буфер поточні настройки на кроці 2, змінює прикладів коду спільних частину до DEVMODE. Зверніться до документації Win32 SDK, з описом DEVMODE учасників. Зразок коду визначає, чи принтера, можна використовувати орієнтація та значення властивості дуплекса (двосторонніх) і зміни до їх належним чином.

    Зверніть увагу: позначка з DEVMODE dmFields членів-це з метою інформування, принтер використовує, пов'язаний структури учасника. Принтери мають велику кількість різних фізичних характеристик і таким чином, може підтримувати лише частину до DEVMODE, містить можливості. Для визначення підтримуваних параметри DEVMODE поля, програми, слід використовувати DeviceCapabilities().



    Приклад коду, потім робить, третій виклик DocumentProperties() та передає DEVMODE буфер в обох pDevModeInput і pDevModeOutput параметрів. Вона також проходить комбінований команди DM_IN_BUFFER та DM_OUT_BUFFER fMode параметр за допомогою оператора OR("|"). Ці команди сказати, функції, візьміть, будь-які параметри, які містяться в буфер вводу та об'єднати їх з поточними настройками пристрою. Потім він записує результат буфер, вказану в параметрі в неправильному.
Зверніть увагу: DocumentProperties() посилається на певному принтері, дескриптор принтер: hPrinter. Цього маркера, отримані від OpenPrinter(), яка також показує, прикладів коду. OpenPrinter() вимагає, ім'я принтера, який зазвичай зрозуміле ім'я принтера, відповідно до операційної системи, оболонки. Це ім'я можна отримати від EnumPrinters(), DEVNAMES структури, який повернув метод PrintDlg()або принтер за промовчанням.

Щоб отримати додаткові відомості про принтер за промовчанням клацніть номер статті в базі знань Microsoft Knowledge Base:

Як отримати та встановити принтер за промовчанням у Windows 246772
Зверніть увагу: В цій статті, перші два кроки розподіляти неправильний розмір буфера і ініціалізації буфера здійснюється з DocumentProperties(). Ці дії можна виконувати за допомогою GetPrinter(). Додаткова інформація та наприклад, клацніть номер статті в базі знань Microsoft Knowledge Base:

140285 , як змінити параметри принтера, за допомогою 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;

}