我正在使用一些代码来使我能够使用TextRenderer.DrawText方法呈现旋转的文本。 (默认情况下,DrawText只能从图形对象复制直接的x和y转换)。在.Net中使用GDI + interop帮助
代码(C#)来自:connect.microsoft.com。请参阅下面的VB转换。
该代码需要一个图形对象,创建一个设备上下文并从图形对象复制变换矩阵。它的工作原理,但我想,也是,设置TextRenderingHint,所以我尝试:
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)> _
Public Shared Function GdipSetTextRenderingHint(ByVal graphics As HandleRef, ByVal textRenderingHint As System.Drawing.Text.TextRenderingHint) As Integer
End Function
然后是setClip的发言后,我把:GdipSetTextRenderingHint(HDC,someHint)
这给了我一个内存访问冲突错误,所以我想我应该使用除hDC以外的其他参数作为参数。
我可以通过从原始图形对象创建设备上下文,然后从设备上下文创建另一个图形对象来实现它。然后我在新的图形对象上设置提示。这似乎有点令人费解,所以我想知道是否可以通过互操作。
VB.Net代码转换:
Friend Class TextRendererDC
Implements IDeviceContext
Implements IDisposable
Private graphics As Graphics
Private dc As IntPtr
Private Sub New()
End Sub
Public Sub New(ByVal g As Graphics)
Me.graphics = g
End Sub
Public Function GetHdc() As IntPtr Implements System.Drawing.IDeviceContext.GetHdc
Dim xform As NativeMethods.XFORM
Dim clipRgn As IntPtr
Using transf As Matrix = Me.graphics.Transform
xform = New NativeMethods.XFORM(transf)
End Using
Using clip As Region = Me.graphics.Clip
clipRgn = clip.GetHrgn(Me.graphics)
End Using
Me.dc = Me.graphics.GetHdc()
Dim hDC As New HandleRef(Me, Me.dc)
Dim hRegion As New HandleRef(Nothing, clipRgn)
SetTransform(hDC, xform)
SetClip(hDC, hRegion)
// The below call creates a memory access violation.
NativeMethods.GdipSetTextRenderingHint(hDC, System.Drawing.Text.TextRenderingHint.AntiAliasGridFit)
Return Me.dc
End Function
Public Sub ReleaseHdc() Implements System.Drawing.IDeviceContext.ReleaseHdc
If Me.dc <> IntPtr.Zero Then
Me.graphics.ReleaseHdc()
Me.dc = IntPtr.Zero
End If
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
ReleaseHdc()
End Sub
Private Shared Sub SetTransform(ByVal hdc As HandleRef, ByVal xform As NativeMethods.XFORM)
NativeMethods.SetGraphicsMode(hdc, NativeMethods.GM_ADVANCED)
NativeMethods.SetWorldTransform(hdc, xform)
End Sub
Private Shared Sub SetClip(ByVal hdc As HandleRef, ByVal hRegion As HandleRef)
NativeMethods.SelectClipRgn(hdc, hRegion)
End Sub
Private Class NativeMethods
Public Const GM_ADVANCED As Integer = 2
<DllImport("Gdi32")> _
Public Shared Function SetGraphicsMode(ByVal hdc As HandleRef, ByVal mode As Integer) As Integer
End Function
<DllImport("Gdi32")> _
Public Shared Function SetWorldTransform(ByVal hDC As HandleRef, ByVal xform As NativeMethods.XFORM) As Boolean
End Function
<DllImport("Gdi32")> _
Public Shared Function SelectClipRgn(ByVal hDC As HandleRef, ByVal hRgn As HandleRef) As Integer
End Function
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, SetLastError:=True, ExactSpelling:=True)> _
Public Shared Function GdipSetTextRenderingHint(ByVal graphics As HandleRef, ByVal textRenderingHint As System.Drawing.Text.TextRenderingHint) As Integer
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Class XFORM
Public eM11 As Single
Public eM12 As Single
Public eM21 As Single
Public eM22 As Single
Public eDx As Single
Public eDy As Single
Public Sub New()
Me.eM11 = 1.0!
Me.eM22 = 1.0!
End Sub
Public Sub New(ByVal transform As Matrix)
Me.eM11 = 1.0!
Me.eM22 = 1.0!
Me.eM11 = transform.Elements(0)
Me.eM12 = transform.Elements(1)
Me.eM21 = transform.Elements(2)
Me.eM22 = transform.Elements(3)
Me.eDx = transform.Elements(4)
Me.eDy = transform.Elements(5)
End Sub
End Class
End Class
End Class
嗯,我以前从来没有见过类似的东西,我已经完成了互操作。我看到了GDip中的共享子New,它调用初始化来加载库。我会假定正确的lib将被自动拾取。无论如何,至于我为什么要这样做,当创建TexterRendererDC时,它会从提供的图形对象中复制转换矩阵和剪辑 - 没有别的。无论如何,当DrawText方法尝试将设备上下文转换为图形以获取呈现提示时,它现在是一个模拟点。因此,在我的问题结束时,我的解决方案是唯一的出路。 – Jules 2010-10-07 00:35:14