Farben per Farbauswahldialog auswählen

15.03.2006
Anders als in Visual Basic, wo Sie einfach per ActiveX-Komponente über das CommonDialog-Control einen Farbauswahldialog realisieren können, steht diese Kompontente für Access nicht zur Verfügung. Aber es gibt dennoch eine komfortable Möglichkeit, dem Benutzer einen Dialog zur Farbauswahl anzubieten. Die Lösung ist, wie so oft, die Windows API.

Die Windows API stellt einen Farbauswahldialog zur Verfügung, der die Standardfarben zur Auswahl anzeigt, aber auch in einer erweiterten Version (Bild 1) verfügbar ist, in der der Benutzer auch eigene Farben mischen und auswählen kann. Der Dialog gibt die Farbe dann als Long- Wert zurück.

Notwendige Deklarationen

Da Sie dazu die API-Funktion ChooseColorA nutzen müssen, ist es erforderlich, diese zunächst zu deklarieren, und zwar auf Modulebene innerhalb eines Standardmoduls (Listing 1).

Option Compare Database
'API-Deklarationen
Declare Function ChooseColor Lib "comdlg32.dll" _
Alias "ChooseColorA" (pChoosecolor As LPCHOOSECOLOR) As Long
'Notwendige Typ-Deklaration
Type LPCHOOSECOLOR
lStructSize As Long
hWnd As Long
hInstance As Long
rgbResult As Long
lpCustColors As String
Flags As Long
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
'Erforderliche Konstanten
Const CC_SOLIDCOLOR = &H80
Const CC_FULLOPEN = &H2

Sie benötigen außerdem einen Datentyp, den Sie ebenfalls mit der type-Anweisung auf Modulebene deklarieren, sowie zwei Konstanten CC_FULLOPEN und CC_SOLIDCOLOR. Sie legen zwei hexadezimale Werte fest, die bestimmen, ob die erweiterte Version des Dialogs oder nur die Standardfarben angezeigt werden sollen.

Aufrufen der API-Funktion

Der eigentliche Aufruf der API-Funktion erfolgt dann in einer Funktion, hier heißt sie getFarbe. Ihr übergeben Sie das Fenster-Handle von Access sowie bei Bedarf einen booleschen Wert, der bestimmt, ob die erweiterte Farbauswahl (true) oder der einfache Dialog (false) angezeigt werden soll. Wird der Parameter weggelassen, wird der Standardwert false verwendet.

Zunächst deklarieren Sie innerhalb der Funktion noch drei Variablen, die Variable typFarbauswahl bekommt den benutzerdefinierten Typ LPCHOOSECOLOR. Anschließend weisen Sie den einzelnen Teilen des benutzerdefinierten Datentyps die entsprechenden Werte zu. Dem Feld lStructSize weisen Sie dabei die Größe der Datenstruktur zu, die Sie mit der Len-Funktion ermitteln können. Das Feld hWnd bekommt den Parameter FensterHandle der Funktion zugewiesen. Über das Feld Flags bestimmen Sie die Optionen für die Ausgabe des Dialogfelds. Zunächst weisen Sie ihm die Konstante CC_SOLIDCOLOR zu und prüfen dann den Wert des optionalen Parameters. Hat er den Wert true, fügen Sie zum aktuellen Wert des Feldes Flags noch die Konstante CC_FULLOPEN hinzu, indem Sie den bitweisen OR-Operator verwenden.

Der Funktion ChooseColor übergeben Sie dann die Variablen typFarbauswahl, die die benutzerdefinierte Datenstruktur enthält. Der Rückgabewert der Funktion wird dann der Variablen lngErgebnis zugewiesen. Hat der Benutzer eine Farbe gewählt, hat sie einen Wert ungleich 0. Hat der Benutzer keine Farbe gewählt, sondern die Farbauswahl abgebrochen, gibt die APIFunktion 0 zurück. Das sollten Sie nun prüfen, damit die Funktion getFarbe einen gültigen Farbwert zurückgeben kann, den Sie bei Auswahl einer Farbe über das Feld rgbResult des Datentyps ermitteln können.

Festlegen des Rückgabewertes

Hat der Benutzer keine Farbe gewählt, legen Sie -1 als Rückgabewert der Funktion fest. Der Wert 0 ist hier nicht geeignet, weil 0 der Farbwert für die Farbe Schwarz ist. Sie könnten dann nicht mehr unterscheiden, ob der Benutzer die Farbwahl abgebrochen hat oder wirklich Schwarz als Farbe gewählt hat.

Public Function getFarbe(ByVal FensterHandle As Long, _
Optional ByVal boolErweiterteFarben As Boolean=False) As Long
Dim lngErgebnis As Long
Dim typFarbauswahl As LPCHOOSECOLOR
Dim lngBenutzerFarben As Long
typFarbauswahl.lStructSize = Len(typFarbauswahl)
typFarbauswahl.hWnd = FensterHandle
'Steuern der Anzeige
typFarbauswahl.Flags = CC_SOLIDCOLOR
'Prüfen, ob erweiterte Farbauswahl angezeigt werden soll.
If boolErweiterteFarben = True Then _
typFarbauswahl.Flags = typFarbauswahl.Flags Or CC_FULLOPEN
'Standard-Farben festlegen
typFarbauswahl.lpCustColors = String(16 * 4, 0)
'Dialog anzeigen und Ergebnis ermitteln
lngErgebnis = ChooseColor(typFarbauswahl)
If lngErgebnis <> 0 Then
'gewählte Farbe als Rückgabewert festlegen
getFarbe = typFarbauswahl.rgbResult
Else
'es wurde keine Farbe gewählt - Rückgabewert auf -1 festlegen
getFarbe = -1
End If
End Function

Möchten Sie nun den Farbauswahldialog anzeigen, müssen Sie nur noch die Funktion get-Farbe aufrufen und ihr das Fenster-Handle von Access übergeben, das Sie mit der hWnd-Eigenschaft des Application-Objekts ermitteln können (Listing 3).

Sub aufrufen()
Debug.Print getFarbe(Application.hWndAccessApp)
Debug.Print getFarbe(Application.hWndAccessApp, True)
End Sub

Umwandlung in hexadezimale Farben

Die Funktion gibt immer einen RGB-Wert des Typs Long zurück. Das ist nicht immer optimal. Benötigen Sie die Farbe beispielsweise für die Ausgabe von HTML-Code oder CSS-Code bei einem Datenexport, ist dazu eine Angabe im hexadzimalen Format besser geeignet. Um den Farbwert umzurechnen, können Sie die Funktion getHex aus Listing 4 verwenden. Die Funktion gibt den hexadezimalen Farbwert zurück, wie er in HTML- und CSS-Dateien benötigt wird.

Function toHex(lngFarbe As Long) As String
Dim intR As Integer 'ROT
Dim intG As Integer 'GRÜN
Dim intB As Integer 'BLAU
Dim strR As String 'ROT
Dim strG As String 'GRÜN
Dim strB As String 'BLAU
toHex = ""
'Ermitteln der einzelnen Farbanteile
intR = lngFarbe And &HFF&
intG = lngFarbe \ &H100& And &HFF&
intB = lngFarbe \ &H10000 And &HFF&
'Umwandeln in Hexadezimale Werte
strR = Hex(intR)
strG = Hex(intG)
strB = Hex(intB)
If Len(strR) < 2 Then
strR = "0" & strR
End If
If Len(strG) < 2 Then
strG = "0" & strG
End If
If Len(strB) < 2 Then
strB = "0" & strB
End If
toHex = "#" & strR & strG & strB
End Function