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:
Public Type CHOOSECOLOR 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.