2010-10-06 34 views
0

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

回答

2

哇,符合 「一知半解可能是危險的」 模具。甚至不是原生的C++程序員直接調用gdiplus切入點,他們使用C++包裝在<gdiplus.h>

這裏的失效模式是你的程序加載錯誤版本的gdiplus.dll中,在c:\ Windows \ System32下。舊版本。正確的是在Windows並行緩存中,.NET的System.Drawing程序集包含代碼以確保它從緩存中獲取正確版本的DLL。

不是你得到的那個。你的甚至沒有初始化,GdiplusStartup從未被調用過。 KABOOM。

不知道你想要完成什麼。 Graphics類具有TextRenderingHint屬性,不需要殺手捅。

+0

嗯,我以前從來沒有見過類似的東西,我已經完成了互操作。我看到了GDip中的共享子New,它調用初始化來加載庫。我會假定正確的lib將被自動拾取。無論如何,至於我爲什麼要這樣做,當創建TexterRendererDC時,它會從提供的圖形對象中複製轉換矩陣和剪輯 - 沒有別的。無論如何,當DrawText方法嘗試將設備上下文轉換爲圖形以獲取呈現提示時,它現在是一個模擬點。因此,在我的問題結束時,我的解決方案是唯一的出路。 – Jules 2010-10-07 00:35:14