Library sample chapters
ActiveX controls
Property Pages
Just browsing the code produced by the wizard is sufficient to understand how property pages work. The PropertyPage object is similar to a form and supports many of the Form object's properties, methods, and events, including Caption, Font, and all the keyboard and mouse events. You might even implement property pages that work as drag-and-drop servers or clients if you need to.
Property pages have their peculiarities, of course. For one, you can control the size of the page using the StandardSize property, which can be assigned one of the values 0-Custom (the size is determined by the object), 1-Small (101-by-375 pixels), or 2-Large (179-by-375 pixels). Microsoft suggests that you create custom-sized pages that aren't larger than the space that you actually need because values other than 0-Custom might display incorrectly at different screen resolutions.
You might notice in Figure 17-15 that the property page doesn't include the OK, Cancel, and Apply buttons that you usually find on standard property pages. Those buttons, in fact, are provided by the environment, and you don't have to add them yourself. The communication between the property page and the environment occurs through properties and events of the PropertyPage object. If the project is associated with a help file, a Help button is also displayed.
When the page loads, the PropertyPage object receives the SelectionChanged event. In this event, your code should load all the controls in the page with the current values of the corresponding properties. The SelectedControls collection returns a reference to all the controls in the form that are currently selected and that will be affected by the property page. For example, this is the code in the SelectionChanged event procedure for the General page of the SuperListBox control:
Private Sub PropertyPage_SelectionChanged()
txtCaption.Text = SelectedControls(0).Caption
txtAllItems.Text = SelectedControls(0).AllItems
chkEnabled.Value = (SelectedControls(0).Enabled And vbChecked)
cboShowPopupMenu.ListIndex = SelectedControls(0).ShowPopupMenu
cboBoundPropertyName.Text = SelectedControls(0).BoundPropertyName
Changed = False
End Sub
When the contents of any field on the page is modified, the code in its Change or Click event should set the PropertyPage's Changed property to True, as in these examples:
Private Sub txtCaption_Change()
Changed = True
End Sub
Private Sub cboShowPopupMenu_Click()
Changed = True
End Sub
Setting the Change property to True automatically enables the Apply button. When the user clicks on this button (or simply switches to another property page), the PropertyPage object receives an ApplyChanges event. In this event, you must assign the values on the property page to the corresponding ActiveX control's properties, as in the following example:
Private Sub PropertyPage_ApplyChanges()
SelectedControls(0).Caption = txtCaption.Text
SelectedControls(0).AllItems = txtAllItems.Text
SelectedControls(0).Enabled = chkEnabled.Value
SelectedControls(0).ShowPopupMenu = cboShowPopupMenu.ListIndex
SelectedControls(0).BoundPropertyName = cboBoundPropertyName.Text
End Sub
One more custom event is associated with PropertyPage objects-the EditProperties event. This event fires when the property page is displayed because the developer clicked on the ellipsis button beside a property name in the Properties window. (This button appears if the property has been associated with a specific property page in the Procedure Attributes dialog box.) You usually take advantage of this property to automatically move the focus on the corresponding control on the property page:
Private Sub PropertyPage_EditProperty(PropertyName As String)
Select Case PropertyName
Case "Caption"
txtCaption.SetFocus
Case "AllItems"
txtAllItems.SetFocus
' etc. (other properties omitted...)
End Select
End Sub
You might also want to disable or hide all other controls on the page, but this is rarely necessary or useful.
Working with multiple selections
The code produced by the Property Page Wizard accounts for only the simplest situation-that is, when only one ActiveX control is selected on the form. To build robust and versatile property pages, you should make them work also with multiple controls. Keep in mind that property pages aren't modal, and therefore the developer is allowed to select (or deselect) controls on the form even when the page is already visible. Each time a new control is added to or removed from the SelectedControls collection, a SelectionChanged event fires.
The standard way to deal with multiple selections is as follows. If the selected controls on the form share the same value for a given property, you fill the corresponding field on the property page with that common value; otherwise, you leave the field blank. This is a modified version of the SelectionChanged that accounts for multiple selections:
Private Sub PropertyPage_SelectionChanged()
Dim i As Integer
' Use the property of the first selected control.
txtCaption.Text = SelectedControls(0).Caption
' If there are other controls, and their Caption property differs from
' the Caption of the first selected control, clear the field and exit.
For i = 1 To SelectedControls.Count - 1
If SelectedControls(i).Caption <> txtCaption.Text Then
txtCaption.Text = ""
Exit For
End If
Next
' The AllItems property is dealt with in the same way (omitted ...).
' The Enabled property uses a CheckBox control. If values differ, use
' the special vbGrayed setting.
chkEnabled.Value = (SelectedControls(0).Enabled And vbChecked)
For i = 1 To SelectedControls.Count - 1
If (SelectedControls(i).Enabled And vbChecked) <> chkEnabled.Value
Then
chkEnabled.Value = vbGrayed
Exit For
End If
Next
' The ShowPopupMenu enumerated property uses a ComboBox control.
' If values differ, set the ComboBox's ListIndex property to _1.
cboShowPopupMenu.ListIndex = SelectedControls(0).ShowPopupMenu
For i = 1 To SelectedControls.Count - 1
If SelectedControls(i).ShowPopupMenu <> cboShowPopupMenu.ListIndex
Then
cboShowPopupMenu.ListIndex = -1
Exit For
End If
Next
' The BoundPropertyName property is dealt with similarly (omitted ...).
Changed = False
txtCaption.DataChanged = False
txtAllItems.DataChanged = False
End Sub
The DataChange properties of the two TextBox controls are set to False because in the ApplyChange event you must determine whether the developer entered a value in either of those fields:
Private Sub PropertyPage_ApplyChanges()
Dim ctrl As Object
' Apply changes to Caption property only if the field was modified.
If txtCaption.DataChanged Then
For Each ctrl In SelectedControls
ctrl.Caption = txtCaption.Text
Next
End If
' The AllItems property is deal with in the same way (omitted ...).
' Apply changes to the Enabled property only if the CheckBox control
' isn't grayed out.
If chkEnabled.Value <> vbGrayed Then
For Each ctrl In SelectedControls
ctrl.Enabled = chkEnabled.Value
Next
End If
' Apply changes to the ShowPopupMenu property only if an item
' in the ComboBox control is selected.
If cboShowPopupMenu.ListIndex <> -1 Then
For Each ctrl In SelectedControls
ctrl.ShowPopupMenu = cboShowPopupMenu.ListIndex
Next
End If
' The BoundPropertyName property is dealt with similarly (omitted ...).
End Sub
Advanced techniques
I want to mention a few techniques that you can use with property pages and that aren't immediately obvious. For example, you don't need to wait for the ApplyChanges event to modify a property in selected ActiveX controls: You can update a property right in the Change or Click event of the corresponding control on the property page. You can therefore achieve in the property page the same behavior that you can implement in the Properties window by assigning a property the Text or Caption procedure ID.
Another easy-to-overlook feature is that the PropertyPage object can invoke Friend properties and methods of the UserControl module because they're in the same project. This gives you some additional flexibility: For example, the UserControl module can expose one of its constituent controls as a Friend Property Get procedure so that the Property Page can directly manipulate its attributes, as you can see in the code at below.
' In the SuperListBox UserControl module
Friend Property Get Ctrl_List1() As ListBox
Set Ctrl_List1 = List1
End Property
A minor annoyance of this approach is that the PropertyPage code accesses the UserControl through the SelectedControls collection, which returns a generic Object, whereas Friend members can only be accessed through specific object variables. You can work around this issue by casting the elements of the collection to specific object variables:
' In the PropertyPage module Dim ctrl As SuperListBox ' Cast the generic control to a specific SuperListBox variable. Set ctrl = SelectedControls(0) ' Now it is possible to access Friend members. ctrl.Ctrl_List1.AddItem "New Item"
The last technique that I'm showing you is likely to be useful when you're developing complex UserControls with many properties and constituent controls, such as the Customer ActiveX control that I introduced earlier in this chapter. Surprisingly, it turns out that you can use the UserControl even on a property page that's associated with itself. Figure 17-16 shows an example of this technique: The General property page uses an instance of the Customer ActiveX control to let the developer assign the properties of the Customer control itself!
Figure 17-16.
A property page that uses an instance of the UserControl object defined in
its own project.
The beauty of this approach is how little code you need to write in the PropertyPage module. This is the complete source code of the property page shown in Figure 17-16:
Private Sub Customer1_Change(PropertyName As String)
Changed = True
End Sub
Private Sub PropertyPage_ApplyChanges()
' Read all properties in one loop.
Dim propname As Variant
For Each propname In Array("CustomerName", "Address", "City", _
"ZipCode", "Country", "Phone", "Fax")
CallByName SelectedControls(0), propname, VbLet, _
CallByName(Customer1, propname, VbGet)
Next
End Sub
Private Sub PropertyPage_SelectionChanged()
' Assign all properties in one loop.
Dim propname As Variant
For Each propname In Array("CustomerName", "Address", "City", _
"ZipCode", "Country", "Phone", "Fax")
CallByName Customer1, propname, VbLet, _
CallByName(SelectedControls(0), propname, VbGet)
Next
End Sub
Notice how the code takes advantage of the CallByName function to streamline multiple assignments to and from the properties in the UserControl.
Related articles
Related discussion
-
Run-time error '91'
by converter2009 (1 replies)
-
VB6 Runtime error 381 subsript out of range Error
by Uncle (2 replies)
-
passing and reading parameters from using Shell
by jigartoliya (0 replies)
-
Convert C++ code to VB6
by mawcot (4 replies)
-
listbox scrollbar
by Dennijr (10 replies)
I also looking for the control for years, but still can't get a good one, some control only make a form transparent instead of a control like picturebox, some control only copy the picture of background under it, isn't real transparent. some controls have transparent background but the transparent area is a hole that you can click controls behind it in z-order. I ever tried the following code in a form:
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Global Const GWL_EXSTYLE = (-20)
Global Const WS_EX_TRANSPARENT = &H20&
add a textbox on the form and a picturebox named picturebox1 over it, in form_load event add this code:
SetWindowLong picturebox1.hwnd, GWL_EXSTYLE, WS_EX_TRANSPARENT
the problems are, only when content of textbox change(by code), the picturebox was changed to transparent, second, when then picturebox resized, the picturebox was changed back to white.usually.
dear sir, if you have got a ideal method to make this control, would you please send me a copy? thank a lot.
i want to create a transperent picturebox behind it i will put internet control / webbrowser.
user will able to see the webpage and unable to click on web page ,
and he would not be able to select text / image .
is it possible to create such a activx picture box . i need it urgently . please reply.as soon as possible
In .NET it is possible to show properties to users of comoponents during runtime. Is there a method to show PropertyPages during Runtime of a VB 6.0 ActiveX control?
Thanks
In .NET it is possible to show properties to users of comoponents during runtime. Is there a method to show PropertyPages during Runtime of a VB 6.0 ActiveX control?
Thanks
Does anyone know how can I convert a *.vbp (visual basic project) into an activex control to use it on a Web Page?
Is it possible to digitally sign an already packaged Active X control or does the code have to be signed.
I want to sign MsRdpClient so we can use it on our intranet without changing IE security settings in the GPO.
Thanks
Hi
very thanx from givig imediate reply.
I have a property page for ActiveX control & if i right click on that control in client design view its show popup menu & in that option is property after clicking it shows the property page what ever i made But the same proprprty page I wan tto display at run time . cos i m developing active control like Rational Rose. so that user ca draw the flow digram & at that time (run time) user can be able to change the property at run time its Background , style etc so it is possible to show the property page at run time
Plz comments
Thanx
Regards
Mahesh
Hi
I want to show the property page at run time for a activeX control so that user can change the backgroun color & style of drawing .
any buddy knows how to show ?
plz comment
Thanx
Regards
adadf
Deep and clear. It was just I was looking for. Great! Thank you.
This thread is for discussions of ActiveX controls.