Microsoft KB Archive/107872
Article ID: 107872
Article Last Modified on 1/8/2003
- Microsoft Visual Basic 3.0 Professional Edition
This article was previously published under Q107872
The following article contains the complete contents of the TN001.TXT file installed in the CDK directory of the Professional Edition of Visual Basic version 3.0 for Windows.
Microsoft Visual Basic 3.00
Microsoft Corporation Technical Notes
TN001.TXT: Support for DT_OBJECT Properties
This note describes how to use OLE Automation by creating a custom control property whose data type is DT_OBJECT.
The Visual Basic version 3.0 Control Development Kit allows you to create custom controls that support OLE Automation. A custom control can define a DT_OBJECT type property, whose value is a 4-byte pointer to an IDispatch interface. If your control can contain or refer to an OLE object, you may want to expose this ability via a property of type DT_OBJECT.
This allows you to use Visual Basic statements such as:
Dim MyObject As OBJECT Set MyObject = Control.Object MyObject.Method...
or, more directly:
OLE has strict guidelines for maintaining reference counts on interface pointers. Functions that return interface pointers increment the reference count on the pointer on behalf of the caller. For example, calling VBGetControlProperty for a DT_OBJECT property causes the returned interface pointer to be incremented. However, the caller is responsible for eventually releasing the reference to the interface pointer by using IUnknown::Release().
If the property is PF_fGetMsg, you are responsible for incrementing the reference count on the interface pointer you return in your VBM_GETPROPERTY message code.
You may want to create a control that is an OLE container, meaning that you expose a pointer to an IDispatch interface via a DT_OBJECT property. When the OLE object is initially created within the control, the control could establish a connection to the OLE object by setting a pointer to an IDispatch interface via IUnknown::QueryInterface(). The reference count for the interface pointer would then be incremented from zero to one.
When the control is destroyed, or the control causes the OLE object it contains to be released, the control would also need to release the interface pointer using IUnknown::Release(). If the DT_OBJECT property is PF_fGetData, then all reference count maintenance associated with fetching the property is automatically handled by Visual Basic. If, on the other hand, the DT_OBJECT property is PF_fGetMsg, you would need to call IUnknown::AddRef() on the interface pointer in your VBM_GETPROPERTY message code.
If there is no valid IDispatch interface, VBGetControlProperty returns NULL (DWORD 0).
Because the IDispatch interface pointer can be used only at run time, you cannot save or load an interface pointer while saving or loading a form. For this reason, you cannot use the PF_fSaveData flag on your DT_OBJECT property.
You might want use to PF_fSaveMsg to enable you to do more sophisticated processing at save or load time. For example, you could handle VBM_SAVEPROPERTY by serializing the OLE object corresponding to the interface pointer into the form file, and handle VBM_LOADPROPERTY by deserializing the object and getting a pointer to an IDispatch interface to it to set your property.
A property defined as DT_OBJECT cannot be set. This means that you cannot use the property flags PF_fSetData or PF_fSetMsg. In addition, you should specify the PF_fNoRuntimeW flag for a DT_OBJECT property.
Because you cannot view or modify the value of a DT_OBJECT property at design time, you should specify the PF_fNoShow flag for your DT_OBJECT property.
You should not designate a DT_OBJECT property as the default property for your control.
Additional query words: ENDUSER 3.00