我正在使用一些代碼來使我能夠使用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