Schieberegler DGV Farbe ändern

  • VB.NET

Es gibt 51 Antworten in diesem Thema. Der letzte Beitrag () ist von Peter329.

    Schieberegler DGV Farbe ändern

    Hi,

    ich hatte vor einiger Zeit einen ähnlichen Thread gestartet (Schieberegler Farbe ändern) - das Problem hier ist damit verwandt aber eben nicht indentisch - deshalb habe ich einen neuen Thread gestartet.

    Ich habe eine recht große DGV - die Navigation erfolgt u.a. über den "vertikalen Schieberegler". Leider ist auch hier die Position des Schieberegelers nur schwer zu erkennen ... (s. Anhang)

    Das erschwert das Arbeiten mit der DGV enorm ... Leider kann man in .Net die Hintergrundfarbe der Scrollbars einer DGV nicht einstellen.

    Natürlich habe ich nach dem gelösten Thread eine Umgehung - ich überlagere den Schieberegler durch eine VSCROLLBAR und spiegele das Scroll Ereginis in die Datagridview. Aber das ist natürlich eine sehr "schweinische" Umgehung.

    Besser wäre es, eine "saubere Lösung" zu finden. Das hatten wir ja schon in dem anderen Thread .... die entsprechende WindowsMessage abfangen und die Eigenschaft ändern. Das Prinzip ist also klar - nur scheitert es an meinem Detailwissen ... wie lautet denn der Message Code ... und wie die Eigenschaft ...

    Vielleicht hat das ja schonmal jemand gemacht .... im Netz bin ich diesbezüglich leider nicht fündig geworden ...

    LG
    Peter
    Bilder
    • s 2022-08-28 16-11-490.jpg

      45,59 kB, 560×363, 61 mal angesehen
    Eine Möglichkeit: Den ganzen WndProc-Kram für das DGV zu machen. Dann musst Du aber ne eigene DGV-Klasse machen, die vom normalen erbt.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Friend Class ColorizedDGV : Inherits DataGridView
    2. Private Const WM_CTLCOLORSCROLLBAR As Integer = &H137
    3. <DllImport("gdi32.dll", EntryPoint:="CreatePatternBrush")> Private Shared Function CreatePatternBrush(ByVal hBitmap As IntPtr) As IntPtr : End Function
    4. <DllImport("gdi32.dll", EntryPoint:="CreateSolidBrush")> Private Shared Function CreateSolidBrush(ByVal crColor As Integer) As IntPtr : End Function
    5. <DllImport("gdi32.dll", EntryPoint:="DeleteObject")> Private Shared Function DeleteObject(ByVal hObject As IntPtr) As Integer : End Function
    6. Private hBmp As IntPtr = IntPtr.Zero
    7. Private hBrush As IntPtr = IntPtr.Zero
    8. Private hBmpBrush As IntPtr = IntPtr.Zero
    9. Private Bmp As Bitmap = Nothing
    10. Friend Sub Init()
    11. hBrush = CreateSolidBrush(&HFF00FF&)
    12. Bmp = New Bitmap(4, 4, PixelFormat.Format24bppRgb)
    13. Using G As Graphics = Graphics.FromImage(Bmp)
    14. G.FillRectangle(Brushes.Yellow, 0, 0, 2, 2)
    15. G.FillRectangle(Brushes.Red, 2, 2, 2, 2)
    16. End Using
    17. hBmp = Bmp.GetHbitmap
    18. hBmpBrush = CreatePatternBrush(hBmp)
    19. End Sub
    20. Friend Sub CleanUp()
    21. If Not Equals(hBrush, IntPtr.Zero) Then DeleteObject(hBrush)
    22. If Not Equals(hBmpBrush, IntPtr.Zero) Then DeleteObject(hBmpBrush)
    23. If Not Equals(hBmp, IntPtr.Zero) Then DeleteObject(hBmp)
    24. Bmp.Dispose()
    25. End Sub
    26. Protected Overrides Sub WndProc(ByRef m As Message)
    27. If m.Msg = WM_CTLCOLORSCROLLBAR Then
    28. Select Case m.LParam
    29. Case Controls(1).Handle '<-- das 2. Control im DGV ist derdiedas vertikale ScrollBar
    30. If Not Equals(hBrush, IntPtr.Zero) Then
    31. m.Result = hBrush
    32. End If
    33. End Select
    34. Else
    35. MyBase.WndProc(m)
    36. End If
    37. End Sub
    38. End Class

    Bilder
    • colorizedDGV.png

      1,07 kB, 302×211, 39 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hi

    Die Abfrage (Select Case) nach dem hwnd der Scrollbar und alles was zu CreatePatternBrush gehört, kann man sich auch schenken. Das macht nur Sinn wenn da mehrere Scrollbars vorhanden sind die unterschiedlich eingefärbt werden sollen.
    Mfg -Franky-

    VaporiZed schrieb:

    Case Controls(1).Handle '<-- das 2. Control im DGV ist derdiedas vertikale ScrollBar

    Ich halte es für riskant einfach über den Index zu gehen, eine Änderung dort von MS und du wunderst dich.

    So ist das besser:( @Peter329 )

    VB.NET-Quellcode

    1. Protected Overrides Sub WndProc(ByRef m As Message)
    2. If m.Msg = WM_CTLCOLORSCROLLBAR Then
    3. If hBrush = IntPtr.Zero Then
    4. Return
    5. End If
    6. Dim t As Type = Control.FromHandle(m.LParam).GetType()
    7. Select Case t
    8. Case GetType(HScrollBar)
    9. m.Result = hBrush
    10. Case GetType(VScrollBar)
    11. m.Result = hBrush
    12. End Select
    13. Else
    14. MyBase.WndProc(m)
    15. End If
    16. End Sub
    @-Franky-

    Das ist teils korrekt. Vorhanden sind beim DataGridView default 2(eine H und eine V), auch wenn diese nicht sichtbar sind. Auch wenn bei einer kein Brush zugewiesen werden soll macht das sinn unterscheiden zu können.

    Da VaporiZed über den Index ging, und nur 1 verändert, ging ich nun davon aus das es so gewollt ist, also musste ich ja zwischen der horizontalen und der vertikalen unterscheiden, wäre sonst ja keine Verbesserung des Codes gewesen, weil nicht mehr differenziert würde. Damit das also ein wertigeres Beispiel ist, der Switch. Gut, If/Else If hätte es auch getan, ich mag Switches mehr, daher ohne nach zu denken getippt, auch wenn es in dem Fall ja nur 2 Fälle sein können.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „BitBrösel“ ()

    @BitBrösel

    Dann haben wir beide Recht/Unrecht. ;) Die Unterscheidung per GetType ist besser als über den Index. Ich bin davon ausgegangen das Peter329 beide Scrollbars mit dem gleichen Brush einfärben möchte.
    Mfg -Franky-
    Vielen Dank erst mal für die Antworten.

    Ich habe diesmal einige Schwierigkeiten die Lösungsvorschläge umzusetzen. Basis ist eine Form mit einer VSCROLLBAR und zwei DGVs.

    Zuerst habe ich das Coding von @BitBrösel ausprobiert:

    VB.NET-Quellcode

    1. Protected Overrides Sub WndProc(ByRef m As Message)
    2. If m.Msg = WM_CTLCOLORSCROLLBAR Then
    3. If hBrush = IntPtr.Zero Then
    4. Return
    5. End If
    6. Dim t As Type = Control.FromHandle(m.LParam).GetType()
    7. Select Case t
    8. Case GetType(HScrollBar)
    9. m.Result = hBrush
    10. Case GetType(VScrollBar)
    11. m.Result = hBrush
    12. End Select
    13. Else
    14. MyBase.WndProc(m)
    15. End If
    16. End Sub


    Das funktioniert zwar für die VSCROLLBAR nicht aber für die DGVs. (s. Anhang)

    Irgendwie werden die Scrollbars der DGV nicht erkannt.

    Ich habe dann den Vorschlag von @VaporiZed mit der Ableitung der Klasse von DGV versucht:

    VB.NET-Quellcode

    1. Friend Class ColorizedDGV : Inherits DataGridView


    In diesem Fall bleibt die VSCROLLBAR grau (was ja auch in Ordung ist, da es nur um die DGV geht), aber die DGVs bleiben leider auch grau. Die WndProc wird gar nicht angsprungen !

    Ich vermute mal stark, dass ich statt der DGV eine "ColorizedDGV" in die Form zeichnen muss ... nur wie mache ich das. Die DGV zeichne ich, indem ich in der Toolbox die DGV anklicke und dann in die Form ziehe. Aber wie mache ich daraus eine "ColorizedDGV" ?

    Übrigens: ich will die Hintergrundfarbe für ALLE Schieberegler in der gleichen Weise setzen.

    Ich hoffe, ihr könnt mir ein bissl weiter helfen ...
    Bilder
    • s 2022-08-29 11-18-527.jpg

      24,43 kB, 635×393, 37 mal angesehen

    Peter329 schrieb:

    Ich vermute mal stark, dass ich statt der DGV eine "ColorizedDGV" in die Form zeichnen muss ... nur wie mache ich das. Die DGV zeichne ich, indem ich in der Toolbox die DGV anklicke und dann in die Form ziehe. Aber wie mache ich daraus eine "ColorizedDGV" ?


    Zeichnen? Nein!
    Füge deinem Projekt eine Klasse Hinzu nenn sie wie VaporiZed es tat, dann kannst du seinen Code erstmal 1:1 rein kopieren, danach kannste das so machen:

    VB.NET-Quellcode

    1. Protected Overrides Sub WndProc(ByRef m As Message)
    2. If m.Msg = WM_CTLCOLORSCROLLBAR Then
    3. If hBrush = IntPtr.Zero Then
    4. Return
    5. End If
    6. m.Result = hBrush
    7. Else
    8. MyBase.WndProc(m)
    9. End If
    10. End Sub


    Dann kompilierst du einmal, danach hast du diese ColorizedDGV in der ToolBox und kannst sie auf's Form werfen.
    Wichtig ist dann, das du auch dafür sorgst, das der Brush nicht Intptr.Zero ist. In der Klasse von VaporiZed ist eine Sub mit den Namen Init, die solltest du auch callen, in der Form -Klasse ColorizedDGV1.Init(). Man könnte auch im Konstruktor den Brush erstellen.

    Falls du das WndProc in der Klasse des Forms überschrieben hattest, das kann nicht gehen, das muss du zwingend in der anderen Klasse haben.(Die abgeleitete DGV)
    @Peter329 Löse das Problem mit einem separaten Projekt, Form, MyDataGridView und los.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ok, das hat mir gefehlt ! Jetzt habe ich erfolgreich die Colorized DGV in meine Form einfügen können.

    Ich hab versucht das Coding zu vereinheitlichen und zu vereinfachen. Insbesondere habe ich das Erstellen der Brush in das MainLoad und das Löschen der Brush in das MainClose Event verlagert, damit das nur einmalig zu Beginn und am Ende des Programms ausgeführt wird. Dazu habe ich die ensprechenden Variablen in ein Public Module verschoben:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Module Module1
    3. Public Const WM_CTLCOLORSCROLLBAR = &H137
    4. Public hBmp As IntPtr = IntPtr.Zero
    5. Public hBrush As IntPtr = IntPtr.Zero
    6. Public hBmpBrush As IntPtr = IntPtr.Zero
    7. Public Bmp As Bitmap = Nothing
    8. <DllImport("gdi32.dll", EntryPoint:="CreatePatternBrush")>
    9. Public Function CreatePatternBrush(
    10. ByVal hBitmap As IntPtr) As IntPtr
    11. End Function
    12. <DllImport("gdi32.dll", EntryPoint:="CreateSolidBrush")>
    13. Public Function CreateSolidBrush(ByVal crColor As Integer) As IntPtr
    14. End Function
    15. <DllImport("gdi32.dll", EntryPoint:="DeleteObject")>
    16. Public Function DeleteObject(ByVal hObject As IntPtr) As Integer
    17. End Function
    18. End Module


    Die Funktionsaufrufe können jetzt nicht mehr SHARED sein ... ich hoffe, das macht nichts !

    So sieht die Main Form aus:

    VB.NET-Quellcode

    1. Imports System.Drawing.Imaging
    2. Public Class Form1
    3. Private Sub Form1_Load(ByVal sender As Object,
    4. ByVal e As System.EventArgs) Handles Me.Load
    5. Dim Data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    6. For k = 1 To 10
    7. For i = 0 To Data.Length - 1
    8. Dim digit = Data.Substring(i, 1)
    9. DataGridView1.Rows.Add(digit)
    10. DataGridView2.Rows.Add(digit)
    11. ColorizedDGV1.Rows.Add(digit)
    12. ColorizedDGV2.Rows.Add(digit)
    13. Next
    14. Next
    15. ' GDI Brush von einer Farbe erstellen
    16. hBrush = CreateSolidBrush(&H4010&)
    17. ' anstelle von CreateSolidBrush kann auch jede andere
    18. ' GDI32 Brush-API verwendet werden. zB. CreatePatternBrush
    19. ' Bitmap erstellen
    20. Bmp = New Bitmap(4, 4, PixelFormat.Format24bppRgb)
    21. ' etwas in die Bitmap reinzeichnen
    22. Using G As Graphics = Graphics.FromImage(Bmp)
    23. G.FillRectangle(Brushes.Yellow, 0, 0, 2, 2)
    24. G.FillRectangle(Brushes.Red, 2, 2, 2, 2)
    25. End Using
    26. ' GDI Handle der Bitmap ermitteln
    27. hBmp = Bmp.GetHbitmap
    28. ' GDI Brush vom Handle der Bitmap erstellen
    29. hBmpBrush = CreatePatternBrush(hBmp)
    30. End Sub
    31. Private Sub Form1_FormClosing(ByVal sender As Object,
    32. ByVal e As System.Windows.Forms.FormClosingEventArgs) _
    33. Handles Me.FormClosing
    34. ' ist ein GDI Brush vorhanden
    35. If Not Equals(hBrush, IntPtr.Zero) Then
    36. ' GDI Brush löschen
    37. DeleteObject(hBrush)
    38. End If
    39. ' ist ein GDI Brush vorhanden
    40. If Not Equals(hBmpBrush, IntPtr.Zero) Then
    41. ' GDI Brush löschen
    42. DeleteObject(hBmpBrush)
    43. End If
    44. ' ist ein GDI Bitmap vorhanden
    45. If Not Equals(hBmp, IntPtr.Zero) Then
    46. ' GDI Bitmap löschen
    47. DeleteObject(hBmp)
    48. End If
    49. 'Bitmap löschen
    50. Bmp.Dispose()
    51. End Sub
    52. 'Background color SCROLLBAR
    53. Protected Overrides Sub WndProc(ByRef m As Message)
    54. If m.Msg = WM_CTLCOLORSCROLLBAR Then
    55. If hBrush = IntPtr.Zero Then
    56. Return
    57. End If
    58. Dim t As Type = Control.FromHandle(m.LParam).GetType()
    59. Select Case t
    60. Case GetType(HScrollBar)
    61. m.Result = hBrush
    62. Case GetType(VScrollBar)
    63. m.Result = hBrush
    64. End Select
    65. Else
    66. MyBase.WndProc(m)
    67. End If
    68. End Sub
    69. End Class


    Und das ist die Definition der Colorized DGV

    VB.NET-Quellcode

    1. Friend Class ColorizedDGV : Inherits DataGridView
    2. 'Background color DGV SCROLLBAR
    3. Protected Overrides Sub WndProc(ByRef m As Message)
    4. If m.Msg = WM_CTLCOLORSCROLLBAR Then
    5. Select Case m.LParam
    6. '2. Control of DGV is vertical scrollbar
    7. Case Controls(1).Handle
    8. If Not Equals(hBrush, IntPtr.Zero) Then
    9. m.Result = hBrush
    10. End If
    11. End Select
    12. Else
    13. MyBase.WndProc(m)
    14. End If
    15. End Sub
    16. End Class


    Und das ist das Ergebnis .... s. Anhang

    die Scrollbars und die Regler der Colorized DGVs sind doch jetzt sehr schön lesbar.

    Danke also erst einmal für eure Hilfe. Ohne euch hätte ich das nicht hinbekommen!

    Jetzt habe ich aber doch noch eine Frage: Um das in meine diversen Projekte einzubauen, muss ich die DGVs neue definieren und durch eine "Colorized DGV" ersetzen. Das wäre in manchen Fällen mit enormem Aufwand verbunden ...

    Ist denn die Sache mit der "Colorized DGV" wirklich erforderlich ? Ich muss doch nur die WndProc Message von der DGV abfangen, um die Hintergrundfarbe des Schiebereglers zu ändern. Das müsste doch auch mit der originalen DGV funktionieren ?

    Have a nice day
    Peter
    Bilder
    • s 2022-08-29 14-58-101.jpg

      36,5 kB, 645×468, 38 mal angesehen
    @Peter329 Deine Aufteilung auf Modul, Form und Klasse widerspricht allen Regeln der objektorientierten Programmierung.
    Mache das ordentlich und der Aufwand, das in andere Projekte einzubinden ist minimal.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Peter329 schrieb:

    Ich muss doch nur die WndProc Message von der DGV abfangen, um die Hintergrundfarbe des Schiebereglers zu ändern. Das müsste doch auch mit der originalen DGV funktionieren ?
    NativeWindow kann glaub so initialisiert werden, dass es auf WndProc eines Controls horcht.
    Aber ziemlich advanced, was du da vorhast.

    Peter329 schrieb:

    Ist denn die Sache mit der "Colorized DGV" wirklich erforderlich ? Ich muss doch nur die WndProc Message von der DGV abfangen, um die Hintergrundfarbe des Schiebereglers zu ändern. Das müsste doch auch mit der originalen DGV funktionieren ?



    Ich denke es ist erforderlich. In C++ kann man das WndProc durchaus gut "umleiten", aber in .Net keine Ahnung.

    @RodFromGermany Könnte man da was mit SetWindowsHookEx und idHook WH_CALLWNDPROC unter .Net machen? @Peter ich probier das heute Abend mal aus.

    RodFromGermany schrieb:

    @Peter329 Deine Aufteilung auf Modul, Form und Klasse widerspricht allen Regeln der objektorientierten Programmierung.


    Hmm ... offen gestanden war mir das gar nicht bewusst, dass ich hier gegen alle guten Sitten verstoße. Natürlich bin ich gern gelehrig und folgsam, wenn ... ja wenn ich nur wüsste was ich falsch mache und wie es richtig sein müsste ! Die Sache mit dem Module1.vb ist nicht ok ? Hmmm .... wie sollte ich sonst eine Brush anwendungsweit anlegen ?

    LG
    Petger
    @BitBrösel Wahrscheinlich meinst Du den ErfinderDesRades.
    Ich bevorzuge es, dem UserControl (wie auch immer) seine eigene WndProc() zu geben,
    das hat ja @Peter329 in seiner Class ColorizedDGV getan.
    Da muss nichts gehookt werden.

    Peter329 schrieb:

    wie sollte ich sonst eine Brush anwendungsweit anlegen ?
    Die gehören lokal in die jeweilige Klasse, wie es vom Designer gelebt wird.

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Die API Funktionen und Konstanten auszulagern ist nicht falsch, aber das gehört eher in eine Klasse anstatt eine Module. Wenn du dann die API functionen als "Public shared" deklarierst, kannste ja statisch drauf zugreifen, also keine Instanz nötig.
    Und das hier hat RFG bemängelt:

    VB.NET-Quellcode

    1. Public hBmp As IntPtr = IntPtr.Zero
    2. Public hBrush As IntPtr = IntPtr.Zero
    3. Public hBmpBrush As IntPtr = IntPtr.Zero
    4. Public Bmp As Bitmap = Nothing


    Sollte eher private in jeder Klasse sein wo du das brauchst. Verwendest du es genau so in mehreren Klassen, mach eine basisklasse und lass die anderen davon erben.(Oder auch nicht, weil .Net hat ja keine mehrfachvererbung) ;( Dein DGV könnte also garnicht zusätzlich davon erben.

    RodFromGermany schrieb:

    das hat ja @Peter329 in seiner Class ColorizedDGV getan.


    Ja, aber er hätte lieber was damit er nicht alle seine DGV's gegen das neue austauschen muss, da fällt mir nichts anderes ein das WndProc vom standard DGV auf der Form zu hooken und ans WndProc der Form umzuleiten.

    @Peter329 Mach dir eine Dll daraus, auf die verweist du dann einfach in deinen Projekten, besser als die Klasse in jedem Projekt zu haben.

    @RodFromGermany Nein, du warst schon gemeint. Ich weis nicht inwiefern der ErfinderDesRades sich mit dem nativen Zeugs auskennt, bei dir bin ich mir ziemlich sicher das du dich damit vermutlich gut auskennst.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „BitBrösel“ ()

    Ok, das habe ich verstanden ... entweder ich packe die Brush in eine eigene Klasse (was mir dann ein bissl großes Geschütz für so eine kleine Brush ist oder aber ich nehme das mit auf in die Klasse "Colorized DGV":

    VB.NET-Quellcode

    1. Imports System.Drawing.Imaging
    2. Imports System.Runtime.InteropServices
    3. Friend Class ColorizedDGV : Inherits DataGridView
    4. Private Const WM_CTLCOLORSCROLLBAR = &H137
    5. Private hBmp As IntPtr = IntPtr.Zero
    6. Private hBrush As IntPtr = IntPtr.Zero
    7. Private hBmpBrush As IntPtr = IntPtr.Zero
    8. Private Bmp As Bitmap = Nothing
    9. <DllImport("gdi32.dll", EntryPoint:="CreatePatternBrush")>
    10. Private Shared Function CreatePatternBrush(
    11. ByVal hBitmap As IntPtr) As IntPtr
    12. End Function
    13. <DllImport("gdi32.dll", EntryPoint:="CreateSolidBrush")>
    14. Private Shared Function CreateSolidBrush(ByVal crColor As Integer) As IntPtr
    15. End Function
    16. <DllImport("gdi32.dll", EntryPoint:="DeleteObject")>
    17. Private Shared Function DeleteObject(ByVal hObject As IntPtr) As Integer
    18. End Function
    19. Friend Sub Init()
    20. hBrush = CreateSolidBrush(&H4010&) 'Define background color
    21. Bmp = New Bitmap(4, 4, PixelFormat.Format24bppRgb)
    22. Using G As Graphics = Graphics.FromImage(Bmp)
    23. G.FillRectangle(Brushes.Yellow, 0, 0, 2, 2)
    24. G.FillRectangle(Brushes.Red, 2, 2, 2, 2)
    25. End Using
    26. hBmp = Bmp.GetHbitmap
    27. hBmpBrush = CreatePatternBrush(hBmp)
    28. End Sub
    29. Friend Sub CleanUp()
    30. If Not Equals(hBrush, IntPtr.Zero) Then DeleteObject(hBrush)
    31. If Not Equals(hBmpBrush, IntPtr.Zero) Then DeleteObject(hBmpBrush)
    32. If Not Equals(hBmp, IntPtr.Zero) Then DeleteObject(hBmp)
    33. Bmp.Dispose()
    34. End Sub
    35. 'Background color DGV SCROLLBAR
    36. Protected Overrides Sub WndProc(ByRef m As Message)
    37. If m.Msg = WM_CTLCOLORSCROLLBAR Then
    38. Select Case m.LParam
    39. '2. Control of DGV is vertical scrollbar
    40. Case Controls(1).Handle
    41. If Not Equals(hBrush, IntPtr.Zero) Then
    42. m.Result = hBrush
    43. End If
    44. End Select
    45. Else
    46. MyBase.WndProc(m)
    47. End If
    48. End Sub
    49. End Class


    Jetzt müsste das doch der reinen Lehre genüge tun.

    Blöderweise muss ich jetzt aber noch etwa im Load Event die Funktion "Init()" für jede Colorized DGV aufrufen:

    VB.NET-Quellcode

    1. ColorizedDGV1.Init()
    2. ColorizedDGV2.Init()


    Und natürlich brauch es das "Cleanup()" etwa im Closing Event:

    VB.NET-Quellcode

    1. ColorizedDGV1.CleanUp()
    2. ColorizedDGV2.CleanUp()


    Kann man das nicht auch automatisieren (etwa im Konstruktor und im Dispose Event ?)

    Hab ich das jetzt alles richtig verstanden ? Ich hoffe, ihr habt ein wenig Geduld mit mir.

    LG
    Peter
    Hi

    Deine Klasse ColorizedDGV besitzt auch eine Sub New sowie ein Finalize. Im ersteren erstellst den Brusch und im letzteren löscht den Brush. Ach ja, werf alles zu CreatePatternBrush raus und dieses Select Case im WndProc wo du auf das hwnd der Scrollbar prüfst. Das brauchst Du nicht. ;)
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Ok .... das hätte ich mir eigentlich selbst beantworten können ... Ich habe Init() in New() und Cleanup() in Finalize() geändert und schon funktioniert die Sache auch ohne Aufruf.

    Eine Kleinigkeit ist mir jetzt aber doch noch aufgefallen. Es wird leider nur der vertikale Schieberegler eingefärbt. Kriegt man den horizontalen Regler vielleicht auch noch zu fassen ? (s. Anhang)
    Bilder
    • s 2022-08-29 16-43-280.jpg

      15,62 kB, 249×341, 36 mal angesehen