在 Windows 上打印 - 多个子窗口

Posted

技术标签:

【中文标题】在 Windows 上打印 - 多个子窗口【英文标题】:Printing on Windows - Multiple Child windows 【发布时间】:2014-04-23 04:27:08 【问题描述】:

我有一个包含多个子 HWND 的窗口(在屏幕外创建)的应用程序。如何打印?

我调用 PrintDdlg() 并获取打印 DC,很好。但是我如何告诉主窗口在 StartPage() / EndPage() 调用之间进行绘制?看来我得手动遍历孩子并调用绘制代码?或者我是否将 WM_PRINT(或 WM_PAINT?)消息发送到顶层窗口。

我可以在屏幕上打印一些东西,但并不明显我做得对。

例如:如果我为子窗口绘图,我通常会获取子窗口 DC 并使用它。但这会起作用吗,还是我只需要使用打印 DC - 换句话说,子窗口 DC 是否足够聪明,可以查看最高父级并确定我们正在打印?

我想如果有人看过这方面的一些最佳实践,我会很想看到它们。我能找到的所有打印文档都是简单的例子。

这是在 C++ 中,基本上是原始的 Win32 我正在更新十年前的打印循环。

现在我的解决方案是手动从后到前遍历窗口层次结构并告诉每个子窗口进行绘制。我遇到了文本缩放、原点(我可以看到的每个子窗口都在左上角绘制)和其他问题。当然,这些都可以手动修复。我现在要花几个小时看看实施 WM_PRINT 是否可行。 WM_PRINT 上的所有示例都涉及获取微观位图以绘制到基于内存的 DC 中。但是 WM_PRINT 的文档让人认为它是用于打印的。

【问题讨论】:

你用什么语言做这个?你用的是MFC之类的框架吗? 在我编辑时 - 我正在更新一个旧的应用程序,该应用程序可以打印,但会损坏。它是一个 C++ 应用程序,它有自己的基于 C 的框架。 我相信如果窗口不可见,它就不会被绘制? 你应该解释什么有效,什么不再有效,以及你做了什么改变。你使用PrintWindow API 吗? 您使用的是文档视图模式还是类似的模式? 【参考方案1】:

各种方法各有利弊。

    发送WM_PRINTCLIENT到窗口。并非所有窗口类型都支持此消息,但大多数标准控件都支持。尝试一下很容易。一个缺点是,如果打印机分辨率与屏幕分辨率相差很大,它可能无法很好地缩放。 通过从窗口的 DC 到内存 DC 执行 BitBlt 模拟屏幕捕获,然后将其 blit 到打印机 DC。这比第一种方法更便携,但您基本上被锁定在屏幕分辨率中。 重新设计应用程序,以便您拥有一个数据模型,您可以从中生成屏幕布局和打印机布局。这是一项繁重的工作,但它可以让您根据每个设备定制布局。

【讨论】:

嗯 - 这不是没有 Windows 窗体应用程序。它的 OpenGL,有一个抽象层,在可用时运行 OpenGL,在没有 gl 时运行 MoveTo/LineTo 等。所以所有的屏幕和打印机布局都“完成”了。我认为 WM_PRINT 可能会起作用,但会为我节省一点时间。在这个应用程序的 Mac 端,打印很“简单”——我只得到等效的 WM_PAINT 消息,所有视图都可以要求缩放、OpenGL 等并正常绘制。当我发出 WM_PAINT 时,子窗口绘制到它们自己的 DC,而不是打印 DC。这就是问题所在。【参考方案2】:

我在实际尝试之前发布了这个,但这可能就是我得到的全部:

在我的绘图抽象中,我将遍历每个类,然后绘制该类,并且在为每个子窗口调用我的内部自定义绘图方法之前,我将调用

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);

  

【讨论】:

以上是关于在 Windows 上打印 - 多个子窗口的主要内容,如果未能解决你的问题,请参考以下文章

windows 编程 —— 子窗口 与 子窗口控件

Qt 子窗口设置为透明

带有隐藏窗口的跨平台子进程

如何在 Electron 中保持多个子窗口打开?

带有多个菜单栏的 Win32 中的 Windows 应用程序?

C++中如何实现子进程打开控制台窗口