Winapi 文本输出在屏幕和打印机上的显示方式不同

Winapi 文本输出在屏幕和打印机上的显示方式不同,winapi,printing,vb6,dpi,Winapi,Printing,Vb6,Dpi,我们有一个用于打印的VB6应用程序,目前无法在.NET中重写。:)我们希望解决的问题是打印文本与UI预览不完全匹配。我们有一个自定义文本框控件,分别使用ExtTextOut和TextOut处理绘制和打印。它们的输出应该相同,但如果字体相同,屏幕或打印机上的文本可能会更大。高度是完美的,只是间距和字符宽度不同。我还不确信这是字体紧排问题,但区别确实取决于打印机DPI的间距和字符宽度。DPI越高,差异越大。4000 DPI会使字符变得更细。但我可以确信,我们在某个地方处理DPI是错误的 下面的代码来

我们有一个用于打印的VB6应用程序,目前无法在.NET中重写。:)我们希望解决的问题是打印文本与UI预览不完全匹配。我们有一个自定义文本框控件,分别使用ExtTextOut和TextOut处理绘制和打印。它们的输出应该相同,但如果字体相同,屏幕或打印机上的文本可能会更大。高度是完美的,只是间距和字符宽度不同。我还不确信这是字体紧排问题,但区别确实取决于打印机DPI的间距和字符宽度。DPI越高,差异越大。4000 DPI会使字符变得更细。但我可以确信,我们在某个地方处理DPI是错误的

下面的代码来自设置字体和打印一些文本的打印方面

fntHeight = MulDiv(m_Font.SIZE, GetDeviceCaps(printerDC, LOGPIXELSY), 72)

fnt = CreateFont(-fntHeight, 0, escapement, escapement, FW_BOLD, Font.Italic, Font.Underline, _
Font.Strikethrough, Font.Charset, 0, CLIP_LH_ANGLES, FontQuality, 0, Font.Name)

SelectObject(printerDC, fnt)

TextOutW(printerDC, x, y, StrPtr(strOutputText), Len(strOutputText))
UI的绘制代码基本相同。用户看到的问题是:用户界面不是一个很好的工具,无法判断文本字段的大小是否太小,因为如果打印机DC上的文本略宽于屏幕DC,则最后一个字符(如句点)将被截断

此差异因字体大小而异,在28时,差异为0。它可以很容易地在+14和-14之间变化,打印或绘制的文本宽度更大。到目前为止,我还无法找出是什么导致TextOut、ExtTextOut和GetTextExtentPoint32给出不同的结果

此代码计算差异,并由paint事件用于尝试调整间距以解释差异,但如果我们能够首先找出差异的原因,则会更好,因为它无法解释字符宽度差异。GetTextExtentPoints32隐藏在对TextWidthU的调用后面

' Call GetTextExtentPoint32W(hdc, StrPtr(strText), Len(strText), textSize)
printerTextWidth = TextWidthU(printerDC, strOutputText) * (screenXdpi / printerXdpi)
screenTextWidth = TextWidthU(UserControl.hdc, strOutputText)
totalDifference = printerTextWidth - screenTextWidth

文本光栅化器对齐像素边界上的所有字符。例如,字母“i”对于96 DPI可以有3个像素的宽度,但是对于192 DPI可以有5、6或7个像素的宽度。如果要匹配屏幕宽度和打印机宽度,应根据打印机分辨率计算宽度,并适当调整屏幕位置

您可以调整单个字母、整字的位置,或保持屏幕布局不变,但可以根据打印机文本大小剪切或延伸右边距

MS Word调整字母位置(注意字母之间的间距):

有趣的起点:

这就是原因。那篇文章很有帮助。