如何在win32 c ++中打印预览?

我有一个绘图function,只需要一个HDC。 但是我需要展示一个精确的缩放版本。

所以目前我用打印机HDC和CreateCompatibleBitmap()与打印机的HDC一起使用CreateCompatibleDC()。

我以这种方式计算DC将具有打印机的确切宽度和高度。 而当我select字体到这个HDC,文本将按照打印机的规模。

不幸的是,我不能用StretchBlt()将HDC的像素复制到控制的HDC,因为它们是我猜想的不同的HDCtypes。

如果我使用与打印机页面相同的w,h作为窗口HDC创build“内存canvas”,字体会自动缩小为屏幕,而不是页面。

我应该CreateCompatibleDC()从窗口的DC和CreateCompatibleBitmap()从打印机的DC或什么?

如果有人能解释正确的方法来做到这一点。 (而且还有一些和打印机一样的东西)

那么,我会很感激!

…史蒂夫

Solutions Collecting From Web of "如何在win32 c ++中打印预览?"

取决于你想成为多么准确,这可能会变得困难。

有很多方法。 这听起来像你试图绘制到一个打印机大小的位图,然后缩小它。 要做到这一点的步骤是:

  1. 为打印机创建DC(或更好的IC-信息上下文)。
  2. 查询打印机DC,找出分辨率,页面大小,物理偏移量等。
  3. 为窗口/屏幕创建一个DC。
  4. 创建兼容的DC(内存DC)。
  5. 为窗口/屏幕创建一个兼容的位图,但大小应该是打印机页面的像素大小。 (这种方法的问题是这是一个巨大的位图,它可能会失败。)
  6. 选择兼容的位图到存储器DC中。
  7. 绘制到存储器DC,使用与绘制到实际打印机时相同的坐标。 (选择字体时,请确保将其缩放到打印机的逻辑英寸,而不是屏幕的逻辑英寸。)
  8. 将内存DC StretchBlt到窗口,这将缩小整个图像。 您可能想要使用拉伸模式进行试验,以查看您要显示的图像的最佳效果。
  9. 释放所有的资源。

但在你朝这个方向前,考虑一下替代方案。 这种方法涉及分配一个巨大的屏幕位图。 这可能会在资源匮乏的计算机上失败。 即使没有,你可能会挨饿其他应用程序。

在另一个答案中给出的图元文件方法是许多应用程序的不错选择。 我会从这开始的。

另一种方法是找出一些虚构的高分辨率单元中的所有尺寸。 例如,假设一切都在千分之一英寸。 然后你的绘图例程将这个虚构的单位缩放到目标设备使用的实际dpi。

最后一种方法(也可能是图元文件)的问题是GDI字体不能完美地线性缩放。 单个字符的宽度根据目标分辨率进行调整。 在高分辨率设备(如300+ dpi激光打印机)上,这种调整是微乎其微的。 但是,在96-dpi的屏幕上,这些调整会在一条线的长度上加上一个重要的错误。 因此,预览窗口中的文本可能会与打印页面上的比例不符(通常较宽)。

因此,硬核方法是在打印机上下文中测量文本,并在屏幕上下文中再次测量,并调整差异。 例如(使用编制的数字),您可以在打印机上下文中测量一些文本的宽度,然后输出到900个打印机像素。 假设打印机像素与屏幕像素的比例是3:1。 你会期望在屏幕上的相同文本为300屏幕像素宽。 但是你在屏幕上下文中测量,你会得到一个像325像素的值。 当你画到屏幕上时,你必须以某种方式使文字变窄25个像素。 你可以把角色拉近一些,或者选择一个稍微小一些的字体,然后把它们拉出来。

硬核方法涉及更多的复杂性。 例如,您可能会尝试检测打印机驱动程序所做的字体替换,并尽可能使用可用的屏幕字体进行匹配。

我有一个混合的大位图和硬核方法,祝你好运。 我没有为整个页面制作一个巨大的位图,而是为一行文本创建了一个足够大的位图。 然后,我将打印机大小绘制到离屏位图,然后将其拉伸到屏幕大小。 这样可以在字体质量轻微下降的情况下消除尺寸差异。 它适合于实际的打印预览,但是你不会想要建立一个所见即所得的编辑器。 单行位图足够小,可以实现这一点。

好消息是只有文字很难。 所有其他绘图都是坐标和大小的简单缩放。

我还没有使用GDI +,但我认为它消除了非线性字体缩放。 所以如果你使用的是GDI +,你只需要调整你的坐标。 缺点是我不认为GDI +上的字体质量好。

最后,如果您是Vista或更高版本的本机应用程序,请确保您已将流程标记为“支持DPI ”。 否则,如果用户使用的是高DPI屏幕,则Windows会对您说谎,并声称分辨率仅为96 dpi,然后对您绘制的任何内容进行模糊放大。 这会降低视觉质量,并使打印预览的调试更为复杂。 由于许多程序不能很好地适应更高的DPI屏幕,微软在Vista中默认添加了“高DPI缩放比例”。

编辑添加

另一个警告:如果用打印机大小的位图选择一个HFONT到内存DC中, 可能会得到与在实际打印机DC中选择相同的HFONT时所得字体不同的字体。 这是因为一些打印机驱动程序将替换内存中的普通字体。 例如,某些PostScript打印机将用内部PostScript字体替代某些常见的TrueType字体。

您可以先将HFONT选择到打印机IC中,然后使用GDI函数(如GetTextFaceGetTextMetrics ,或者GetOutlineTextMetrics来查找所选的实际字体。 然后,您可以创建一个新的LOGFONT,尝试更加贴近打印机的使用情况,将其转换为HFONT,并将其选入您的内存DC中。 这是一个非常好的实施的标志。

有一件值得尝试的事情是创建一个增强的图元文件DC,然后像平常一样绘制,然后使用打印机指标来缩放这个图元文件。 这是WTL BmpView示例所使用的方法 – 我不知道这将是多么准确,但它可能值得一看(应该很容易将相关的类移植到Win32,但WTL是Win32编程的一个很好的替代品可能值得使用。)

那么它会看起来不一样,因为你在打印机DC有更高的分辨率,所以你将不得不写一个排序转换功能。 我会用你可以工作的方法,但文本太小,只是乘以打印机窗口宽度的每个位置/字体大小除以源窗口宽度。