Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Win API


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / WinAPI

Выпуск № 330
от 29.10.2006, 07:05

Администратор:Калашников О.А.
В рассылке:Подписчиков: 377, Экспертов: 33
В номере:Вопросов: 1, Ответов: 2


Вопрос № 59989: Здравствуйте, уважаемые эксперты! Подскажите пожалуйста каким образом можно стандартными API средствами распечатать какую-то область контекста на принтере? Спасибо!...

Вопрос № 59.989
Здравствуйте, уважаемые эксперты!
Подскажите пожалуйста каким образом можно стандартными API средствами распечатать какую-то область контекста на принтере?
Спасибо!
Отправлен: 24.10.2006, 07:44
Вопрос задал: Наумов Сергей Александрович / snov (статус: 1-ый класс)
Всего ответов: 2
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Sergey A. Wedensky
Здравствуйте, Наумов Сергей Александрович / snov!

В приложении пример функции, выводящей на печать область rcToPrint контекста hDC в область размером WidthInches x HeightInches дюймов, расположенную в левом верхнем углу листа.
Думаю, при желании доработать сможете сами.

Удачи!

Приложение:

Ответ отправил: Sergey A. Wedensky (статус: 6-ой класс)
Ответ отправлен: 24.10.2006, 10:04
Оценка за ответ: 5
Комментарий оценки:
Спасибо!

Отвечает: JohnP
Здравствуйте, Сергей Александрович!

Первый шаг - наладка принтера и получение DC принтера.
Для этого может использоваться PrintDlg, с указанием значения PD_RETURNDC в поле Flags структуры PRINTDLG.

// инициализируем структуру PRINTDLG
pd.lStructSize = sizeof(PRINTDLG);
memset(&pd,0,sizeof(PRINTDLG));
pd.Flags = PD_RETURNDC;
pd.hwndOwner = hwnd;
pd.nFromPage = 1;
pd.nToPage = 1;
pd.nCopies = 1;
// показываем PRINT dialog box
PrintDlg(&pd);

// Проверяем возможность устройства, заданного как pd.hDC, использовать для печати ф-ию BitBlt.
if (!(GetDeviceCaps(pd.hDC, RASTERCAPS) & RC_BITBLT))
{
DeleteDC(pd.hDC);
MessageBox(hwnd,
"Printer cannot display bitmaps.",
"Device Error",
MB_OK);
break;
}

После этого:
// Устанавливаем флаг продолжения, используемый в AbortPrintJob
bPrint = TRUE;
// Регистрируем функцию AbortProc, которая используется для прерывания выполнения задания принтера
SetAbortProc(pd.hDC, AbortProc);
// Показываем немодальное диалоговое окно отмены
hdlgCancel = CreateDialog(hinst, (LPTSTR) "AbortDlg", hwnd, (DLGPROC) AbortPrintJob);
// Блокируе окно приложения
EnableWindow(hwnd, FALSE);

Когда приложение регистрирует AbortProc, GDI вызывает эту процедуру периодически во время выполнения задания принтера, чтобы определить окончание задания. Если пользователь отменит задание, GDI сообщит спулеру печати об удалении журнального файла из очереди печати и о переключении принтера в начальное состояние.

//Пример реализации процедуры отмены печати
BOOL CALLBACK AbortProc(HDC hdc, int nCode)
{
MSG msg;
while (PeekMessage((LPMSG) &msg, (HWND) NULL, 0, 0, PM_REMOVE))
{
// Обработка сообщений для окна диалога отмены
if (!IsDialogMessage(hdlgCancel, (LPMSG) &msg))
{
TranslateMessage((LPMSG) &msg);
DispatchMessage((LPMSG) &msg);
}
}
// возвращаем флаг продолжения печати (FALSE - прекратить печать)
return bPrint;
}

Приложение начинает задание, вызывая ф-ию StartDoc.
После начала задания, приложение может определять отдельные страницы в документе, вызывая ф-ии StartPage и EndPage
и делая соответствующие вызовы отдельных ф-ий GDI внутри этих "областей". После определения последней страницы, документ может быть закрыт вызовом EndDoc.
Следующий пример организовывает печать строки текста и растрового изображения. Строка центрирована в верхней части страницы, указывает имя файла изображения. Изображение центрировано вертикально и горизонтально на странице, печатается в тех же пропорциях, в каких отображается в окне приложения (принцип WYSIWYG).

di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "Bitmap Printing Test";
di.lpszOutput = (LPTSTR) NULL;
di.lpszDataType = (LPTSTR) NULL;
di.fwType = 0;

nError = StartDoc(pd.hDC, &di);
if (nError == SP_ERROR)
{
errhandler("StartDoc", hwnd);
goto Error;
}

nError = StartPage(pd.hDC);
if (nError <= 0)
{
errhandler("StartPage", hwnd);
goto Error;
}

// Получаем число пикселей-на-дюйм для данного дисплея
fLogPelsX1 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSX);
fLogPelsY1 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSY);

// Получаем число пикселей-на-дюйм для данного принтера
fLogPelsX2 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSX);
fLogPelsY2 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSY);

// Получаем коэффициент масштабирования для получения нужных пропорций изображения
if (fLogPelsX1 > fLogPelsX2) fScaleX = (fLogPelsX1 / fLogPelsX2);
else fScaleX = (fLogPelsX2 / fLogPelsX1);
if (fLogPelsY1 > fLogPelsY2) fScaleY = (fLogPelsY1 / fLogPelsY2);
else fScaleY = (fLogPelsY2 / fLogPelsY1);

// Получаем координаты верхнего левого угла центрированного изображения
cWidthPels = GetDeviceCaps(pd.hDC, HORZRES);
xLeft = ((cWidthPels / 2) - ((int) (((float) bmih.biWidth) * fScaleX)) / 2);
cHeightPels = GetDeviceCaps(pd.hDC, VERTRES);
yTop = ((cHeightPels / 2) - ((int) (((float) bmih.biHeight) * fScaleY)) / 2);

hdcMem = CreateCompatibleDC(pd.hDC);
if (!SelectObject(hdcMem, hbm)) errhandler("SelectObject Failed", hwnd);

// Для пропорциональной печати используем ф-ию StretchBlt
if (!StretchBlt(pd.hDC, xLeft, yTop,
(int) ((float) bmih.biWidth * fScaleX),
(int) ((float) bmih.biHeight * fScaleY),
hdcMem, 0, 0, bmih.biWidth, bmih.biHeight, SRCCOPY))
errhandler("StretchBlt Failed", hwnd);

DeleteDC(hdcMem);

// Получаем длину текста и его координаты
GetTextExtentPoint32(pd.hDC, ofn.lpstrFile, ofn.nFileExtension + 3, &szMetric);

xLeft = ((cWidthPels / 2) - (szMetric.cx / 2));
yTop = (szMetric.cy * 3);

// печатаем текст
TextOut(pd.hDC, xLeft, yTop, ofn.lpstrFile, ofn.nFileExtension + 3);

// Если пользователь нажал на кнопку отмены в диалоговом окне AbortPrintJob
// вызывается процедура AbortDoc, иначе спулер информируется о завершении печати страницы
nError = EndPage(pd.hDC);
if (nError <= 0)
{
errhandler("EndPage", hwnd);
goto Error;
}
// информируе драйвер о завершении печати документа
nError = EndDoc(pd.hDC);
if (nError <= 0) errhandler("EndDoc", hwnd);
Error:
EnableWindow(hwnd, TRUE);
// Уничтожаем диалоговое окно отмены
DestroyWindow(hdlgCancel);
// удаляем DC принтера
DeleteDC(pd.hDC);
Ответ отправил: JohnP (статус: 1-ый класс)
Ответ отправлен: 24.10.2006, 11:25
Оценка за ответ: 5


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2006, Портал RusFAQ.ru, Россия, Москва.
Идея, дизайн, программирование: Калашников О.А.
Email: adm@rusfaq.ru, Тел.: +7 (926) 535-23-31
Авторские права | Реклама на портале
Версия системы: 4.37 от 04.10.2006
Яндекс Rambler's Top100

В избранное