我尝试使用WinAPI而不是(System.Drawing.Printing.PrintDocument)来准备打印文档,因为Graphic.DrawString不能正确呈现高棉语。只有TextRendering.DrawText才能正确呈现它。我相信Graphic是GDI +包装器,而TextRendering.DrawText正在使用GDI。此外,PrintDocument不适用于TextRendering.DrawText。
Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" _
(ByVal lpDriverName As String, ByVal lpDeviceName As String, _
ByVal lpOutput As String, ByVal lpInitData As DEVMODE) As Long
Private Declare Function EndDoc Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function StartDoc Lib "gdi32" Alias "StartDocA" (ByVal hdc As Long, ByVal lpdi As DOCINFO) As Long
Private Declare Function StartPage Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndPage Lib "gdi32" (ByVal hdc As Long) As Long
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'' Getting Printer hDC
Dim printHandler As Long = CreateDC(Nothing, "Send To OneNote 2010", Nothing, Nothing)
Dim docInfo As New DOCINFO
docInfo.cbSize = Len(docInfo)
docInfo.lpszDatatype = Nothing
docInfo.lpszOutput = Nothing
docInfo.lpszDocName = "Testing"
StartDoc(printHandler, docInfo)
StartPage(printHandler)
Dim g As Graphics = Graphics.FromHdc(printHandler)
TextRenderer.DrawText(g, "Hello World", Me.Font, New Point(10, 10), Color.Black)
EndPage(printHandler)
EndDoc(printHandler)
End Sub
这是我的尝试。它在这行代码上失败:Dim g As Graphics = Graphics.FromHdc(printHandler)
。好像Long是64位而IntPtr是32位。
有没有解决方法呢?
答案 0 :(得分:2)
VB.NET的所有P / Invoke定义都是错误的。您显然已经从针对VB 6的项目或网站中复制了它们,但.NET已经发生了很多变化。
正确的定义如下:
<DllImport("gdi32.dll", SetLastError:=False, CharSet:=CharSet.Auto)> _
Private Shared Function CreateDC(lpszDriver As String, _
lpszDevice As String, _
lpszOutput As IntPtr, _
ByRef lpInitData As DEVMODE) As IntPtr
End Function
<DllImport("gdi32.dll", SetLastError:=False)> _
Private Shared Function EndDoc(hdc As IntPtr) As Integer
End Function
<DllImport("gdi32.dll", SetLastError:=False)> _
Private Shared Function StartDoc(hdc As IntPtr, ByRef lpdi As DOCINFO) As Integer
End Function
<DllImport("gdi32.dll", SetLastError:=False)> _
Private Shared Function StartPage(hdc As IntPtr) As Integer
End Function
<DllImport("gdi32.dll", SetLastError:=False)> _
Private Shared Function EndPage(hdc As IntPtr) As Integer
End Function
很有可能你对DEVMODE
和DOCINFO
结构的定义也是错误的。您可能使用Long
代替IntPtr
作为指针类型,并将Long
和Integer
混合用于数字类型,因为这些类型的含义从VB 6更改为VB.NET。
您可能根本不需要DEVMODE
结构,如果是,您可以将CreateDC
函数定义替换为:
<DllImport("gdi32.dll", SetLastError:=False, CharSet:=CharSet.Auto)> _
Private Shared Function CreateDC(lpszDriver As String, _
lpszDevice As String, _
lpszOutput As IntPtr, _
lpInitData As IntPtr) As IntPtr _
End Function
并传递IntPtr.Zero
lpInitData
lpszOutput
,就像IntPtr.Zero
所指示的那样,the documentation - NULL
的指示实际上等同于DOCINFO
对于指针类型。
<StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)> _
Private Structure DOCINFO
Dim cbSize As Integer
Dim lpszDocName As String
Dim lpszOutput As String
Dim lpszDatatype As String
Dim fwType As Integer
End Structure
结构将声明为:
fwType
根据the documentation,Private Const DI_APPBANDING As Integer = &H1
成员可以是以下任何常量:
Private Const DI_ROPS_READ_DESTINATION As Integer = &H2
所有这些都说......你知道在.NET世界中有更简单的打印方式,对吗?