Visual Data’s SmartCombo ActiveX control lets you create customized combo boxes of often-useful complexity. The methods for using the control are well thought out, although the documentation could use some work. In this review, I’ll show you the basics of using SmartCombo and discuss the more advanced features.
The control consists of several “buttons.” The standard down-arrow button is visible by default, but you can hide and show any button at either design or runtime. Each button has an associated constant that’s defined automatically when you add the SmartCombo component reference. All the buttons raise a ButtonClick event and pass the constant for the button that was clicked in a ButtonID parameter to a shared handler. You would normally create a Case statement to respond to a click on a particular button by checking the ButtonID parameter value passed to the ButtonClick event handler. For example:
Private Sub SmartCombo1_ButtonClick( _ ByVal ButtonID As VDSCOMBOLibCtl.vdsButtonID, _ ByVal SpinningEnded As Boolean) Select Case ButtonID ' handle the click on each visible button Case vbsDownArrow Case vbsUpSpinner Case vbsDownSpinner End SelectEnd Sub
Unlike in many other ActiveX controls?including some of Microsoft's?these defined constant names are well-chosen and easy to remember. SmartCombo doesn't accept a list of strings and associated ItemData like the standard ComboBox control does; instead, you assign the dropdown portion using a PictureBox or other control. That scheme makes the dropdown portion of SmartCombo entirely yours to control, using standard VB event handlers and code to build interactivity in the dropdown portion.
However, you do have to write the code to control the dropdown; it's not as automatic as creating a standard ComboBox. For example, you have to tell the control when to display the dropdown portion, and (for the most part) when to hide it, although the control hides the dropdown portion automatically if the user switches the focus to another control or form or takes any action that closes the window. Fortunately, the control's properties and methods make building relatively complicated controls extremely easy.
Suppose you wanted to create a dropdown control that contained an image showing a color gradient (as opposed to the common list of items). When a user clicks somewhere in the image, you want to show the selected color by filling a small PictureBox control with the selected color (see Figure 1).
|Figure 1: A form showing a SmartCombo "colorpicker" control. The color selected by the user appears in the small PictureBox next to the control.
Building this control with VB6 subclassing would be difficult, but using SmartCombo it took less than 5 minutes. First, add a component reference to the VDSCombo 1.0 Type Library. The SmartCombo control appears in your Toolbox. Place a SmartCombo somewhere on the form. Next, place a PictureBox on your form, assign a picture (or draw an image onto the control), and set the PictureBox's Visible property to False. Now you want the control to display the PictureBox as the dropdown portion. To do this, trap the click event when the user clicks the down arrow button to open the combo box. In the event handling code, check the SmartCombo.IsDropped property. If the user is opening the combo (IsDropped = False), call the SmartCombo.DropDown method and pass the hWnd property of the PictureBox. If the dropdown portion is already visible, call the CloseUp method to hide it.
Private Sub SmartCombo1_ButtonClick( _ ByVal ButtonID As VDSCOMBOLibCtl.vdsButtonID, _ ByVal SpinningEnded As Boolean) Static ignorenext As Boolean Select Case ButtonID Case vdsDownArrow If Not SmartCombo1.IsDropped Then ' show the dropdown portion SmartCombo1.DropDown Picture1.hWnd ' The DropDown method has other ' optional parameters discussed later ' in this review Else SmartCombo1.CloseUp ' hide the dropdown portion End If ' Case (handle other button clicks here) ' ... End SelectEnd Sub
The preceding code prompts SmartCombo to display the contents of the PictureBox in the dropdown portion of the control. The SmartCombo constant for the down-arrow button constant is vdsDownArrow. Any code you write to trap events in the PictureBox still works. In this instance, when the user selects a color, the Picture1_MouseDown event grabs the color, extracts the red, green, and blue values, formats them into a string, and places the result in the text portion of the SmartCombo control. Listing 1 shows the relevant code for the PictureBox shown in Figure 1.
The Point method returns the pixel color at a given point. The function returns -1 if the specified point is outside the bounds of the object calling the method?in this case, the PictureBox. The subroutine traps for that possibility and exits if it occurs.
You aren't limited to using PictureBoxes for the dropdown portion of the control--SmartCombo can display almost any control for which you can obtain a window handle. The documentation recommends that you use a container control, such as a PictureBox or Panel. You can even use the hWnd of another form, but only one on the same thread. You can make a SmartCombo combobox act more like a standard combobox by setting the dropdown portion to a ListBox control that you place on the screen. Finally, the documentation states that you can display menus from the current form or from another form in the dropdown portion, although I didn't test this feature.
Controlling the SmartCombo
When the user clicks the down arrow button on the SmartCombo control, call the DropDown method, and pass the hWnd of the window you want to display in the dropdown as the first parameter. The DropDown method has a number of additional parameters that let you control exactly how the control treats the dropdown portion. The following code shows a ButtonClick event handler with all the parameters. See Table 1 for an explanation.
Private Sub SmartCombo1_ButtonClick( _ ByVal ButtonID As VDSCOMBOLibCtl.vdsButtonID, _ ByVal SpinningEnded As Boolean) If ButtonID = vdsDownArrow Then SmartCombo1.DropDown List1.hWnd, _ vdsLeftToRight, vdsBottomToDown, vdsEdit, _ True, vdsRaisedResize, True, 0, 0 End IfEnd Sub
In addition to the standard combobox's down-arrow button, the SmartCombo control has several other "buttons" that you can configure at either design time or at run time, including vertical and horizontal "spinner" buttons, a checkbox that appears within the edit portion, and a right-arrow button. The last SmartCombo on the sample form (see Figure 2) has all the available buttons visible and enabled. The up/down spinner buttons change a numeric value in the edit portion of the control. The left/right spinner buttons change the font size of the caption. The checkbox and right-arrow buttons simply display message boxes when you click them. The caption portion of the control also functions as a button.
The various SmartCombo controls on the sample form display fixed and resizable borders. The fourth control "remembers" the last size set by the user. The "Show Matrix Example" button displays an example from the documentation that accompanies the control. Like Microsoft Word's table combo, this button lets you select a matrix of cells by moving the mouse over the control. If you hold the left mouse button down while you drag across the control, it resizes to show additional cells.
This control is very simple to use. It is extremely powerful and lets you add complex functionality to your user interfaces while minimizing screen space. I had a couple of odd experiences where the control refused to raise documented events, but removing the control and adding it back to the form eliminated the problem. I may have caused that by testing the control outside the bounds of its documented capabilities.
It's too bad this control wasn't available earlier in VB6's life cycle. I did test the control in VB.NET using COM Interop, which worked fine, although here you have to be more diligent in specifying values rather than accepting the defaults. I hope that Visual Data releases a .NET-compatible version soon. The documentation is adequate, although it could definitely be improved. I'd also like to see a few more properties and events added to the control. For example, it needs an event that fires before the dropdown portion closes.
It would be convenient if the control had a property that caused it to remember the window size for resizable dropdowns. And it would be nice if the control had properties that let you retrieve the size of the resizable dropdown (right now, you have to rely on the size of the contained window). All in all, despite the few minor glitches, I can recommend the SmartCombo control.