Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Как устранить зависание при печати Quick Report в потоке




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

Для этого необходимо вызывать методы и свойства VCL через Synchronize().

Следующий пример демонстрирует это:

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

#include <vcl.h>

#pragma hdrstop

 

#include "Unit1.h"

#include "Unit2.h"

#pragma package(smart_init)

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

// Метод Synchronize используется следующим образом:

//

// Synchronize(UpdateCaption);

//

// где UpdateCaption выглядит примерно так:

//

// void __fastcall PrintQReport::UpdateCaption()

// {

// Form1->Caption = "Updated in a thread";

// }

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

__fastcall PrintQReport::PrintQReport(bool CreateSuspended)

: TThread(CreateSuspended)

{

}

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

void __fastcall PrintQReport::Execute()

{

//---- Поместите сюда код потока ----

Synchronize(Print);

}

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

void __fastcall PrintQReport::Print()

{

Form1->QuickRep1->Print();

}

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

 

 

Для изменения размера бумаги на принтере, необходимо несколько раз вызвать 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);
}
}

 





Поделиться с друзьями:


Дата добавления: 2015-10-01; Мы поможем в написании ваших работ!; просмотров: 403 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Велико ли, мало ли дело, его надо делать. © Неизвестно
==> читать все изречения...

2460 - | 2139 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.012 с.