Using the Choose Color Dialog Box

by Steve Anderson

Using the Choose Color Dialog Box

All Visual Basic programmers have used the Common Dialog Control for opening, saving, choosing colors and more, but did you know that you can do all this by calling the DLL directly?

Why would you want to call the DLL directly?  The ActiveX control works fine!

Well, the Common Control DLL is permanently loaded with Windows, but the ActiveX version that is available in Visual Basic has to be loaded separately and more memory and resources will be required.  The other reason lies in there being several versions of the Common Control provided with Visual Basic and the hefty (140Kb) sized control has to distributed with all your applications making a much bigger application. If you are distributing your application over the internet or any other means where size matters then using the API is the solution.

This article will focus on using the API to display the choose color dialog box.

The Choose Color Dialog Box

The API function that is required to show the Color Dialog box is the ChooseColour API function, which has one parameter with passes a ChooseColour type structure to the API function and displays the common dialog box.

The ChooseColour Type structure has the following parameters:

lStructSize – This is the size of this type structure and you should set this parameter to the length of the structure

hWndOwner – You should set this parameter to the handle of the object that the colour will be applied to (e.g., text1.hwnd).  If you do not specify a handle, the user will be free to carry on using the application with the Colour dialog box still on the screen.

hInstance – In C++ and some other programming languages you can actually customise the dialog box, by adding extra buttons, parameters, etc…but this not possible in Visual Basic (as far as I know), so you should leave this parameter as Null (0&).

rgbResult – This is the parameter that contains the returned colour that the user selected from the Common Dialog box, which can be directly set into an object's backcolor or forecolor property, or transferred into a variable. You can even be set to the current back colour of an object, so the colour currently used is by default the colour selected in the common dialog control. (For information of setting the value of a currently used colour see the flags parameter).

lpCustColors – This is the parameter that is the cause of most problems. This is because it needs an array of custom colours to be set before calling. This seems easy enough, but the array needs to be passed in Unicode format, which isn't directly supported in Visual Basic.

Flags – The flags parameter contains information on the way you want to display the ChooseColour Common Dialog box and can be either one or a combination of the following.

  • CC_FULLOPEN - You will have noticed that the ChooseColour Common Dialog has the option to select a custom colour by clicking on the Define Custom Colours >> button. When displaying the Common Dialog box you have the option to open the custom colour part of the dialog box by default by passing this constant.  In fact this seems to be the most commonly used flag, as for instance the Appearance tab of the Display Control Panel Applet shows does the same when selecting a colour.
  • CC_PREVENTFULLOPEN - As you can display the custom colours part by default you can also prevent the user from displaying this part of the dialog box by passing this constant.  You may want to do this in the case where you want to restrict the user to only selecting the standard set of colours that are provided
  • CC_RGBINIT - You will recall me mentioning the ability to set the colour currently being used so that the colour that is being used is selected when displaying the Common Dialog box. You can do this by passing this constant and in rgbResult parameter you pass the colour currently being used. Unfortunately there is a little problem being that Visual Basic displays its colours in hexadecimal format. A simple way to get around this is the use the GetBKColour API function to return the correct type of value that can be passed. There is an example of this below in the structured class.
  • CC_SHOWHELP - This constant and the next one is not documented in this article, but are left an a task for the reader to accomplish. This constant simply displays a help button in the ChooseColour Common Dialog control and when clicked on sends a message to the owner window. You can the use these messages to display your own help.
  • CC_ENABLEHOOK - This is rather similar to CC_SHOWHELP as it sends messages from the Common Dialog box to the owner window of the Dialog Box. You can then create a message handler to use these messages to perform custom actions. This can be also thought of as sub-classing.

lCustData – Leave this as Null (0&).

lpfnHook – Leave this as Null (0&).

lpTemplateName – Leave this as Null (0&).

If the ChooseColour API function returns zero, then the user has clicked the Cancel button.

Now that you understand what is to passed to the API function in-order for it to work, we now need to put this into practice, by building a sample project that will:

  • Display the ChooseColour Common Dialog box
  • Allow selection of all colours including custom colours
  • When OK is clicked retrieve the chosen colour and set the form's back colour to the colour chosen.

First start a new standard-exe project, add a standard module to the project and a command button to form1. Set the command button's name and caption properties to ChooseColour.

Before we start, we need to ensure that all the correct declarations are in the standard module.

These are:

  lStructSize As Long
  hwndOwner 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

Public Declare Function ShowColour Lib _
"comdlg32.dll" Alias "ChooseColorA" _ 
(pChoosecolor As CHOOSECOLOR) As Long

Make sure these are correctly copied or the call will fail.

Go back to the click procedure of the ChooseColour command button on form1 as we now need to add the code make this work.

Below is the code that will make the function work correctly make sure that you understand how all of the code works by reading the detailed comments. This sample, will only demonstrate the basic opening of the common dialog box.

Private Sub ChooseColour_Click()

Dim CustomColours() As Byte
' Define array for custom colours.

ReDim CustomColours(0 To 15) As Byte
' Resize the array to hold the elements

Dim tChooseColour As CHOOSECOLOR
' Declare a user-defined variable for the ChooseColour
' type structure.

With tChooseColour

.hwndOwner = Me.hWnd
' Set the handle for the owner of the window.

.lpCustColors = StrConv(CustomColours, vbUnicode)
' Pass the custom colours array after converting
' it to Unicode using the StrConv function.

.flags = 0&
' For this sample, we do not need to use this.

.lStructSize = Len(tChooseColour)
' Set the size of the type structure

End With

If ShowColour(tChooseColour) = 0 Then MsgBox _
"You clicked on the 'Cancel' button", _
vbExclamation: Exit Sub

' Call the API function and display the ChooseColour
' Common Dialog box, and if the users clicks on cancel
' then the function will return 0.

Me.BackColor = tChooseColour.rgbResult
' Set the back colour of the form to the colour
' that the user selected.

End Sub

If you now run the application and click on the ChooseColour command button then the Common Dialog will be displayed.

Download choosecolor demonstration project.

You should now be able to implement the Color Dialog box into your application without using the chunky 140Kb common dialog box control.  Next week I will show you how to use the standard Page Setup dialog box that is not available with any OCX!  Stay tuned!

If you have any queries about this article, please email me.

This article was originally published on Wednesday Nov 20th 2002
Mobile Site | Full Site