J'utilise du code pour activer le rendu de texte avec la méthode TextRenderer.DrawText. (Par défaut, DrawText ne peut copier qu'une transformation x et y directe à partir d'un objet graphique).Aide avec GDI + interop in .Net
Le code (C#) provient de: connect.microsoft.com. Voir ci-dessous pour une conversion VB.
Le code prend un objet graphique, crée un contexte de périphérique et copie la matrice de transformation à partir de l'objet graphique. Il fonctionne, mais je voudrais, aussi, pour régler le TextRenderingHint, donc j'ai essayé:
<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
Et puis après la déclaration SetClip, je place: GdipSetTextRenderingHint (hdc, someHint)
Cela me donne une erreur de violation d'accès à la mémoire, donc je pense que je devrais utiliser autre chose que hDC comme argument.
Je peux le faire fonctionner en créant le contexte de périphérique à partir de l'objet graphique d'origine, puis en créant un autre objet graphique à partir du contexte de périphérique. Je définis ensuite l'indice sur le nouvel objet graphique. Cela semble un peu compliqué alors je me demandais si c'était possible grâce à interop.
conversion de code 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
Eh bien, je n'ai jamais vu quelque chose comme ça avant quand j'ai fait interop. Je vois le sous-répertoire partagé New dans GDip qui appelle initialize pour charger la librairie. J'aurais supposé que la bonne lib serait automatiquement récupérée. Quoi qu'il en soit, pour ce que je fais, quand TexterRendererDC est créé, il copie la matrice de transformation et le clip de l'objet graphique fourni - rien d'autre. C'est un point discutable de toute façon, car la méthode DrawText essaie de transformer le contexte du périphérique en graphique pour obtenir l'indice de rendu. Par conséquent, ma solution compliquée, à la fin de ma question, est la seule voie à suivre. – Jules