Rubrik: Grafik und Font | VB-Versionen: VB2005, VB2008 | 12.01.11 |
ColorDialog: benutzerdefinierte Farben vorgeben Die Eigenschaft "CustomColors" des "ColorDialog" erwartet Farben als R-G-B-Integer. | ||
Autor: Manfred Bohn | Bewertung: | Views: 15.686 |
ohne Homepage | System: Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Die "ColorDialog"-Klasse (Namespace: "System.Windows.Forms") stellt ein Standarddialogfeld dar, in dem die verfügbaren Farben angezeigt werden und das Steuerelemente enthält, mit denen benutzerdefinierte Farben erstellt bzw. gewählt werden können. Die "CustomColors"- Eigenschaft dieser Klasse ruft den im Dialogfeld angezeigten Satz benutzerdefinierter Farben ab oder legt diesen fest. Diese Farben sind in einem Integer-Array enthalten, dessen (max. 16) Elemente aus den zum Erstellen der Farbe erforderlichen RGB-Werten (rot, grün und blau) bestehen (VB-Doku, sinngemäß).
Obwohl die Eigenschaften dieses Farbwahl-Dialog mit Variablen des Typs "System.Drawing.Color" arbeiten, akzeptiert die "CustomColors"-Eigenschaft im übergebenen Array keine Integer-Werte, die per "ToArgb"-Methode dieser Struktur erstellt worden sind, sondern verlangt statt dessen R-G-B-Integer (=fehlender Alpha-Kanal). Solche Werte können durch die "RGB"-Funktion (in "Microsoft.VisualBasic.Information") gebildet werden.
Die Demo-Funktion "Color_Dialog" erwartet als zweiten Parameter ein Array benutzerdefinierter Farben des Typs System.Drawing.Color ("customcolors") und wandelt es in ein RGB-Array um. Der Benutzer muss im Dialog eine der vorgegebenen Farben wählen. Der ByRef-Parameter "Color_Index" meldet den Array-Index der gewählten Farbe oder bei Abbruch -1 bzw. Funktionsrückgabe "false".
Der Colordialog besitzt keine Titel-Eigenschaft und wird deshalb geeignet erweitert ("SetWindowText").
Imports System.Windows.Forms Public Class clsColorDialog Inherits System.Windows.Forms.ColorDialog Private Const WM_INITDIALOG As Integer = &H110 <System.Runtime.InteropServices.DllImport("user32.dll", _ CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _ Private Shared Function SetWindowText(ByVal hWnd As System.IntPtr, _ ByVal text As String) As Boolean End Function Private _Title As String = "Farbe wählen" Public Sub New(ByVal Title As String) MyBase.New() If Not String.IsNullOrEmpty(Title) Then _Title = Title End Sub Protected Overrides Function HookProc(ByVal hWnd As System.IntPtr, _ ByVal msg As Integer, ByVal wparam As System.IntPtr, _ ByVal lparam As System.IntPtr) As System.IntPtr If msg = WM_INITDIALOG Then SetWindowText(hWnd, _Title) Return MyBase.HookProc(hWnd, msg, wparam, lparam) End Function End Class
Die Demo-Funktion:
''' <summary>Dialog zur Auswahl einer Farbe aus benutzerdefinierter Vorgabe</summary> ''' <Title>Dialog-Überschrift</Title> ''' <param name="color_Index">Index der Farbvor- bzw. Rückgabe (oder -1)</param> ''' <param name="customcolors">Array mit benutzerdefinierten Farben</param> Public Function Color_Dialog(ByVal Title As String, _ ByVal customcolors() As Drawing.Color, _ ByRef Color_Index As Integer) As Boolean ' max. Zahl benutzerdefinierter Farben Const MaxColors As Integer = 16 Dim coloranz As Integer = 0, cc(MaxColors) As Integer ' Ab VB 2008: Verweis auf System.Linq erforderlich ' customcolors = (From x As Drawing.Color In customcolors Distinct).ToArray ' Umwandlung der benutzerdefinierten Farben in RGB-Integerwerte coloranz = customcolors.Length If coloranz > MaxColors Then coloranz = MaxColors For i As Integer = 0 To coloranz - 1 cc(i) = ColorToInteger(customcolors(i)) Next i For i As Integer = coloranz To 15 cc(i) = ColorToInteger(Drawing.Color.Black) Next i If Color_Index < 0 Or Color_Index > MaxColors - 1 Then Color_Index = 0 Dim Initcolor As Drawing.Color = customcolors(Color_Index) Color_Index = -1 Dim ok As Boolean = False Dim coldia As New clsColorDialog(Title) With coldia .AnyColor = False : .SolidColorOnly = False : .ShowHelp = False .FullOpen = False : .AllowFullOpen = False .CustomColors = cc Do .Color = Initcolor If .ShowDialog = Windows.Forms.DialogResult.Cancel Then Return False For i As Integer = 0 To coloranz - 1 If RGB_Equals(.Color, customcolors(i)) Then Color_Index = i : Return True End If Next i MsgBox("Sie müssen eine der " & CStr(coloranz) & _ " benutzerdefinierten Farben wählen", MsgBoxStyle.Information, "Farbe") Loop End With End Function
Private Function ColorToInteger(ByVal c As Drawing.Color) As Integer ' Alpha-Kanal wird ignoriert Return Microsoft.VisualBasic.Information.RGB(c.R, c.G, c.B) End Function
Private Function RGB_Equals(ByVal col1 As Drawing.Color, _ ByVal col2 As Drawing.Color) As Boolean If col1.R <> col2.R Then Return False If col1.G <> col2.G Then Return False If col1.B <> col2.B Then Return False Return True End Function
Anwendungsbeispiel:
Dim customcolors(5) As Drawing.Color, Color_Index As Integer = 2 ' Array füllen - als Vorgabe für benutzerdefinierte Farben customcolors(0) = Drawing.Color.Red customcolors(1) = Drawing.Color.FromName("GREEN") customcolors(2) = Drawing.Color.FromKnownColor(Drawing.KnownColor.Azure) customcolors(3) = Drawing.Color.FromArgb(255, 120, 140, 160) customcolors(4) = Drawing.SystemColors.ButtonFace customcolors(5) = Drawing.Color.FromName(ConsoleColor.DarkMagenta.ToString) If Color_Dialog("Farbauswahl", customcolors, Color_Index) Then Me.BackColor = customcolors(Color_Index) End If