Печать в Windows — несколько дочерних окон

У меня есть приложение с окном (созданным вне экрана), в котором есть несколько дочерних HWND. Как мне это распечатать?

Я вызываю PrintDdlg () и получаю печать DC, хорошо. Но как мне сказать, чтобы главное окно рисовало между вызовами StartPage () / EndPage ()? Кажется, мне нужно вручную пройти через детей и вызвать код розыгрыша? Или я отправляю сообщение WM_PRINT (или WM_PAINT?) В окно верхнего уровня.

Я могу напечатать некоторые вещи на экране, но не очевидно, что я делаю это правильно.

Например: если я рисую для дочернего окна, я обычно получаю дочерний Windows DC и использую его. Но сработает ли это, или мне нужно использовать только DC для печати — другими словами, достаточно ли умного DC для дочернего окна, чтобы взглянуть на верхний родительский элемент и выяснить, что мы печатаем?

Я думаю, если бы кто-нибудь видел некоторые лучшие практики по этому вопросу, мне было бы любопытно увидеть их. Вся документация для печати я могу найти только для тривиальных примеров.

Это на C ++ с в основном сырым Win32. Я обновляю десятилетний цикл печати.

Прямо сейчас мое решение состоит в том, чтобы вручную пройти через иерархию окон сзади и вперед и указать каждому дочернему окну рисовать. У меня проблемы с масштабированием текста, происхождением (каждое дочернее окно отображается слева вверху, которое я вижу) и другими проблемами. Конечно, все это можно исправить вручную. Теперь я собираюсь потратить часы, чтобы посмотреть, будет ли работать WM_PRINT. Все примеры на WM_PRINT имеют дело с получением микроскопической битовой карты для рисования в DC на основе памяти. Но документы для WM_PRINT заставляют задуматься о печати.

0

Решение

Существуют различные подходы со множеством плюсов и минусов.

  1. послать WM_PRINTCLIENT к окну. Не все типы окон поддерживают это сообщение, но большинство стандартных элементов управления поддерживают. Это довольно легко попробовать. Один недостаток заключается в том, что он может плохо масштабироваться, если разрешение принтера сильно отличается от разрешения экрана.
  2. Эмулируйте снимок экрана, выполняя BitBlt из DC окна в DC памяти и затем перетаскивая это в DC принтера. Это более переносимо, чем при первом подходе, но вы по существу привязаны к разрешению экрана.
  3. Переработайте приложение, чтобы у вас была модель данных, из которой вы генерируете как макет экрана, так и макет принтера. Это большая работа, но она позволяет настроить макет для каждого устройства.
0

Другие решения

Я публикую это ДО того, как я попробую, но это может быть все, что я получу:

В моей абстракции рисования я рассмотрю каждый класс, затем нарисую этот класс, и непосредственно перед вызовом моего внутреннего пользовательского метода рисования для каждого дочернего окна я вызову

SetViewportOrgEx (расположение дочерних окон в главном окне)
SetViewportExtEx (экстент дочерних окон в главном окне)

Возможно также ScaleViewportExtEx ()

Так что-то вроде:

HDC printDC = fromPrintDlg.dc;
void MyPaneClass::DrawForPrint(mainWindow, printDC)
{
for (child window* chWin in main window)
{
Point offset = GetOffsetfromMainWindow(chWin);
Size size = GetWindowSize(chWin);
SetViewportOrgEx(printDC ,offset);
SetViewportExtEx(printDC , size);
ScaleViewportExtEx(printDC , printerPixelsPerInch/screenPPI);

chWin->DrawSelf();
// reccursively call, but keep main top window ref:
chWin->DrawForPrint(mainWindow, printDC);

}
}
0

По вопросам рекламы [email protected]