The CColorPicker Class


The public CColorPicker class is a simple wrapper for the private FColorPicker form. As you saw with AllAbout earlier in this chapter, forms can’t be public and that’s just as well. The CColorPicker class hides all the form details that you don’t want users to see.


In the sample, a color picker dialog box pops up whenever you click the right mouse button. The MouseUp event procedure illustrates how CColorPicker changes the color:

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 2 Then
Dim getclr As New CColorPicker
Static clrLast As Long
' Load last color used
If clrLast <> 0& Then getclr.Color = clrLast
' Load dialog at given position and shape
getclr.Load Left + X, Top + Y, -chkWideForm
' Save chosen color for next time
clrLast = getclr.Color
' Change color of form and check boxes
AllColors clrLast
End If
End Sub

This color picker form can come in two shapes—the 16 by 3 cell shape familiar from Visual Basic version 4, and the 8 by 6 cell shape used in the current version. The Wide property controls the shape; the Color property sets the initial color and gets the selected color when the dialog box is finished. The Load command loads the dialog box and the dialog box doesn’t go away until the user selects a color or presses the escape key.


The implementation comes in two parts—CColorPicker and FColorPicker. CColorPicker just passes the work on to FColorPicker. The Load method gives you an idea of how simple this is:

Private frm As New FColorPicker

Sub Load(Optional ByVal Left As Single = -1#, _
Optional ByVal Top As Single = -1#, _
Optional ByVal Wide As Boolean = True)
frm.Wide = Wide
If Left <> -1# Then frm.Left = Left
If Top <> -1# Then frm.Top = Top
frm.Show vbModal
End Sub

The real work is done on the form. A quick summary of the imple­mentation follows:
I won’t explain the code in detail, but the Form_Paint sub will give you the flavor:

Private Sub Form_Paint()
Dim ix As Long, iy As Long
' Draw colors in their boxes
FillStyle = vbSolid
For ix = 1 To ixMax
For iy = 1 To iyMax
FillColor = aColor(ix, iy)
Line (((ix - 1) * 17) + 1, _
((iy - 1) * 17) + 1)-Step(15, 15), , B
Next
Next
DrawSelection ixCur, iyCur, True
End Sub

The only other point I want to make about the FColorPicker form is that its properties are Friends. Instead of this:

Public Property Get Color() As Long

you define this:

Friend Property Get Color() As Long

This is a global optimization that you can add to any form that shares information by providing properties or methods. Think about it. Forms are always private. When you declare a “public” property on a form, it’s not really public in the same way that a class method can be public. Nobody outside your application or component can see it—which happens to be the definition of Friend. So from a user standpoint, Public and Friend have exactly the same effect in forms. But internally they work differently.


A form is actually a kind of class, and like all classes, it uses COM to make its methods and properties available to other modules. A standard module, on the other hand, doesn’t work through COM and can therefore make its procedures available more directly. The Friend keyword makes classes work more like standard modules. I don’t know the technical details, but you can see the results in the TimeIt application. In native code, a Friend property on a form works about five times faster than an equivalent Public property.


Generally, properties on forms are just about the last place you’d voluntarily spend time optimizing. The better performance certainly isn’t going to make any visible difference when loading an FColorPicker form, but as Joe Hacker says: “If you can get better performance for free, take it—whether you need it or not.”


You can see more of the code in COLORPICKER.FRM, which as noted in “Using the CAbout class,” resides in VisualCore rather than VBCore.