WinForms - Caret bei TextBox und RichTextBox ändern.

    • Allgemein

      WinForms - Caret bei TextBox und RichTextBox ändern.

      Hey Leute,

      wollte auch mal ein kleines Tutorial schreiben.

      Thema: Wie ändert man das (den?) Caret bei einer TextBox, bzw. RichtTextBox?

      Das (der?) Caret ist der blinkende Cursor, der die aktuelle Position in der TextBox anzeigt. Ich werde im Folgenden zeigen, wie man seine eigene TextBox (RichTextBox) mit angepasstem Caret erstellt. Dazu wird eine neue Klasse erzeugt und diese erbt vom entsprechenden Control.

      VB.NET-Quellcode

      1. Public Class CaretTextBox : Inherits TextBox
      2. End Class


      Um das Caret zu ändern, benötigt man 2 Windows-API-Aufrufe:

      VB.NET-Quellcode

      1. Public Class CaretTextBox : Inherits TextBox
      2. Private Declare Sub CreateCaret Lib "user32.dll" Alias "CreateCaret" (ByVal hWnd As IntPtr, ByVal SrcImage As IntPtr, _
      3. ByVal ImageWidth As Integer, ByVal ImageHeight As Integer)
      4. Private Declare Sub ShowCaret Lib "user32.dll" Alias "ShowCaret" (ByVal hWnd As IntPtr)
      5. End Class


      CreateCaret benötigt ein gültiges Handle (hier das Handle der Textbox), das Handle des Bitmaps und eine Höhe und eine Breite.
      ShowCaret benötigt ein gültiges Handle (auch das Handle der Textbox).

      Ich werde die Bitmap-Datei als Ressource in das Projekt einbinden. Als vernüftige Grösse des Bitmaps hat sich Breite: 10px und Höhe: 12px herausgestellt. Bei der Erstellung des Bitmaps muss man aufpassen, da die Farben invertiert werden. Also, kehrt bei der Erstellung die Farben um, um beim Benutzen die Richtigen zu erhalten. Als Grafik hab ich das VBP-Logo verwendet.

      VB.NET-Quellcode

      1. Public Class CaretTextBox : Inherits TextBox
      2. Private Declare Sub CreateCaret Lib "user32.dll" Alias "CreateCaret" (ByVal hWnd As IntPtr, ByVal SrcImage As IntPtr, _
      3. ByVal ImageWidth As Integer, ByVal ImageHeight As Integer)
      4. Private Declare Sub ShowCaret Lib "user32.dll" Alias "ShowCaret" (ByVal hWnd As IntPtr)
      5. Private _bmp As New Bitmap(My.Resources.vbp)
      6. End Class


      Nun gilt es, die entsprechenden Methoden der Basisklasse zu überschreiben. Bei einer gewöhnlichen TextBox genügt es, OnGotFocus() zu behandeln. Bei einer RTB müssen noch 2 weitere überschrieben werden.

      VB.NET-Quellcode

      1. Public Class CaretTextBox : Inherits TextBox
      2. Private Declare Sub CreateCaret Lib "user32.dll" Alias "CreateCaret" (ByVal hWnd As IntPtr, ByVal SrcImage As IntPtr, _
      3. ByVal ImageWidth As Integer, ByVal ImageHeight As Integer)
      4. Private Declare Sub ShowCaret Lib "user32.dll" Alias "ShowCaret" (ByVal hWnd As IntPtr)
      5. Private _bmp As New Bitmap(My.Resources.vbp)
      6. Protected Overrides Sub OnGotFocus(e As System.EventArgs)
      7. MyBase.OnGotFocus(e)
      8. CreateCaret(Me.Handle, _bmp.GetHbitmap(), 0, 0)
      9. ShowCaret(Me.Handle)
      10. End Sub
      11. End Class


      Dies genügt, um euer eigenes Bitmap als Caret zu verwenden. Da diese Klasse von TextBox erbt, findet ihr das Control nach dem ersten Starten des Projekts, in eurer Toolbar und könnt es verwenden, wie eine normale TextBox. Für die Parameter Width und Height habe ich 0 verwendet. Dies bewirkt, dass die Originalgrösse des Bitmaps verwendet wird.

      Bei einer RichtTextBox müssen wie gesagt 2 weitere Methoden der Basisklasse überschrieben werden. Das Vorgehen ist das Selbe, darum gibts für die RichtTextBox den kompletten Code.

      VB.NET-Quellcode

      1. Public Class CaretRichTextBox : Inherits RichTextBox
      2. Private Declare Sub CreateCaret Lib "user32.dll" Alias "CreateCaret" (ByVal hWnd As IntPtr, ByVal SrcImage As IntPtr, _
      3. ByVal ImageWidth As Integer, ByVal ImageHeight As Integer)
      4. Private Declare Sub ShowCaret Lib "user32.dll" Alias "ShowCaret" (ByVal hWnd As IntPtr)
      5. Private _bmp As New Bitmap(My.Resources.vbp)
      6. Protected Overrides Sub OnTextChanged(e As System.EventArgs)
      7. MyBase.OnTextChanged(e)
      8. CreateCaret()
      9. End Sub
      10. Protected Overrides Sub OnGotFocus(e As System.EventArgs)
      11. MyBase.OnGotFocus(e)
      12. CreateCaret()
      13. End Sub
      14. Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)
      15. MyBase.OnMouseDown(e)
      16. CreateCaret()
      17. End Sub
      18. Private Sub CreateCaret()
      19. CreateCaret(Me.Handle, _bmp.GetHbitmap(), 0, 0)
      20. ShowCaret(Me.Handle)
      21. End Sub
      22. End Class


      Warum das Verhalten der beiden Controls hier abweicht, kann ich leider nicht beantworten.

      Im Anhang findet ihr das Projekt.

      Viel Spass beim Probieren.... 8o
      Dateien
      • CaretChange.zip

        (77,34 kB, 148 mal heruntergeladen, zuletzt: )
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o