15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Меняем размер бумаги на принтере.

Компилятор: C++ Builder

Для изменения размера бумаги на принтере, необходимо несколько раз вызвать API функцию DocumentProperties(). Для начала, чтобы открыть принтер (и получить его дескриптор), вызываем функцию OpenPrinter(). Далее вызываем DocumentProerties() с нулевым параметром fMode, чтобы получить размер в байтах, необходимый для структуры DEVMODE. Выделяем необходимое количество памяти, а затем снова вызываем DocumentProperties(), чтобы получить указатель на структуру, используемую принтером. При помощи этого указателя изменяем необходимые нам поля. Затем опять вызываем DocumentProperties(), записать изменения в DEVMODE и передать её в функцию CreateDC().

 

//---------------------------------------------------------------------------

void __fastcall TForm1::PrintButtonClick(TObject *Sender)
{
   
// получаем имя дефолтового принтера, драйвер и порт
    char *def_string = "no printer";
    char buffer[MAX_PATH];
    GetProfileString("windows", "device", def_string,
                     buffer, MAX_PATH);

    AnsiString Abuffer(buffer);
    AnsiString Device, Driver, Port;

    // парсим из буфера определённые свойства
    int first_comma = Abuffer.Pos(",");
    Device = Abuffer.SubString(1, first_comma - 1);
    Abuffer = Abuffer.SubString(first_comma + 1,
              Abuffer.Length() - first_comma);
    int second_comma = Abuffer.Pos(",");
    Driver = Abuffer.SubString(1, second_comma - 1);
    Port = Abuffer.SubString(second_comma + 1,
                             Abuffer.Length() - second_comma);

    // открываем принтер
    HANDLE HPrinter;
    if (OpenPrinter(Device.c_str(), &HPrinter, NULL))
    {
       
// вызываем DocumentProerties() с нулевым параметром fMode
        //
чтобы получить количество необходимых байт
        long int num_bytes;
        num_bytes = DocumentProperties(NULL, HPrinter, Device.c_str(),
                                       NULL, NULL, 0);

        // выделяем память
        unsigned char *buffer = new unsigned char[num_bytes];

        // опять вызываем DocumentProperties(), на сей раз, чтобы
        //
получить информацию об устройстве
        DocumentProperties(NULL, HPrinter, Device.c_str(),
                           (PDEVMODE)buffer, NULL, DM_OUT_BUFFER);
       
        PDEVMODE pdm = (PDEVMODE)buffer;

        // изменяем соответствующие поля
        pdm->dmPaperSize = DMPAPER_10X14;  // например

        // говорим Windows, какие поля мы изменили
        pdm->dmFields = pdm->dmFields | DM_PAPERSIZE;

        // ещё раз вызываем DocumentProperties(), чтобы получить окончательный
        // DEVMODE
который будет передан в функцию CreateDC()
        DocumentProperties(NULL, HPrinter, Device.c_str(),
                           pdm, pdm, DM_OUT_BUFFER | DM_IN_BUFFER);

        // создаём контекст устройства принтера
        HDC HPrinterDC = CreateDC(Driver.c_str(), Device.c_str(),
                                  NULL, pdm);
        if (HPrinterDC)
        {
            DOCINFO di;
            di.cbSize = sizeof(DOCINFO);
            di.lpszDocName = "Test Print";
            di.lpszOutput = (LPTSTR) NULL;
            di.lpszDatatype = (LPTSTR) NULL;
            di.fwType = 0;

            // начинаем печать
            if (StartDoc(HPrinterDC, &di))
            {
                if (StartPage(HPrinterDC))
                {
                    float fLogPelsX1, fLogPelsY1;

                    fLogPelsX1 =
                       (float)GetDeviceCaps(HPrinterDC, LOGPIXELSX);
                    fLogPelsY1 =
                       (float)GetDeviceCaps(HPrinterDC, LOGPIXELSY);

                    RECT R = Rect(0, 0, fLogPelsX1 * 8.5, fLogPelsY1 * 11);
                   
// печатаем любой текст
                    ::DrawText(HPrinterDC, Memo1->Text.c_str(),
                               Memo1->Text.Length(), &R,
                               DT_LEFT | DT_EDITCONTROL | DT_WORDBREAK);
                              
                    EndPage(HPrinterDC);
                }
                EndDoc(HPrinterDC);
            }
            DeleteDC(HPrinterDC);
        }
        delete [] buffer;
        ClosePrinter(HPrinter);
    }
}