ActiveX Controls and Visual FoxPro 5.0

Microsoft Corporation

Overview

Microsoft® ActiveX™ controls provide additional functionality to a Microsoft Visual FoxPro™ application. Visual FoxPro version 5.0 includes a set of ActiveX controls (.OCX files) that you can add to and distribute with your applications. You can add ActiveX controls to a form in an application by using the Visual FoxPro OLE container control.

ActiveX controls are installed by default if you choose the Complete installation option when you install Visual FoxPro. If you did not choose this option, you can run Visual FoxPro Setup again at any time and install only the ActiveX controls. ActiveX controls are installed in the SYSTEM directory in Windows® 95 or the SYSTEM32 directory in Windows NT®.

ActiveX Controls Included in Visual FoxPro 5.0

The following table lists the .OCX files shipped with Visual FoxPro and the ActiveX controls contained in each file.

File Controls
COMCTRL32.OCX ImageList
ListView
ProgressBar
Slider
StatusBar
TabStrip
Toolbar
TreeView
COMDLG32.OCX Common Dialogs
DBLIST32.OCX MSDataCombo
MSDataList
FOXHWND.OCX Visual FoxPro HWND
FOXTLIB.OCX Visual FoxPro Foxtlib
GRID32.OCX Grid
MCI32.OCX Microsoft Multimedia
MSACAL70.OCX Calendar
MSCOMM32.OCX Microsoft Comm
MSMAPI32.OCX Microsoft MAPI Message
Microsoft MAPI Session
MSOUTL32.OCX Outline
PICCLP32.OCX PicClip
RICHTX32.OCX RichTextBox
SYSINFO.OCX SysInfo
TABCTL32.OCX SSTab
THREED32.OCX Threed Checkbox
Threed Command Button
Threed Frame
Threed Group Push Button
Threed Option Button
Threed Panel

For additional information about adding ActiveX controls to your applications, see Chapter 16, "Adding OLE," in the Developer's Guide.

Distributing ActiveX Controls Included with Visual FoxPro

Distribution rights of an ActiveX control are determined by the control's creator. Be sure you have distribution rights for any ActiveX controls you distribute with a Visual FoxPro application. All of the ActiveX controls included with Visual FoxPro can be distributed with the applications you create.

Note   The MediaView 1.41 ActiveX control (MEDV141N.OCX), installed with the Visual FoxPro online documentation, cannot be added to or distributed with your applications. This ActiveX control is intended only for browsing the Visual FoxPro online documentation in an interactive Visual FoxPro session.

Using ActiveX Controls in Visual FoxPro

ActiveX controls can be placed on a Visual FoxPro form through the OLE container control. When you place an OLE container control on a form, the Insert Object dialog box appears. To add an ActiveX control to the form, choose the Insert Control option button. The Control Type list appears. From this list you can choose an ActiveX control to place on the form. If the ActiveX control you'd like to place on the form isn't in the Control Type list, choose the Add Control button. Choosing the Add Control button displays the Browse dialog box, allowing you to locate the ActiveX control you'd like to place on the form.

ActiveX controls can also be added to a form by choosing the View Classes button on the Form Controls toolbar and then choosing ActiveX Controls. An icon for each ActiveX control appears on the toolbar. To place an ActiveX control on the form, click its icon and then click the form where you'd like the ActiveX control to appear.

ActiveX Tips and Tricks

The following sections discuss tips and tricks for applications that use ActiveX controls.

Object Keyword

A new Object keyword has been added to Visual FoxPro 5.0 so you can specify properties for ActiveX controls before they are instantiated. The Object keyword indicates to Visual FoxPro that the property value should be applied when the ActiveX control is instantiated. If the Object keyword is not included, a custom property for the ActiveX control is created when the control is instantiated. Note that the Object keyword must be immediately preceded by a period.

The following example adds the ActiveX Outline control (MSOUTL32.OCX) to a form. The Object keyword is used to specify the BackColor property for the Outline control before the control is instantiated. Run the example, remove the Object keyword from the program line containing the BackColor property, and run the example again to see the effect of the Object keyword on the Outline control.

PUBLIC frmOLETest

frmOLETest = CREATEOBJECT('Form')  && Create a form
frmOLETest.Visible = .T. && Display the form

* The following line adds the outline control to the form.

frmOLETest.ADDOBJECT('OCXTest', 'BlueOLEControl', ;
    'MSOutl.Outline')

frmOLETest.OCXTest.AddItem('Item One')  && Add an item to the control
frmOLETest.OCXTest.AddItem('Item Two')  && Add an item to the control

DEFINE CLASS BlueOLEControl AS OLEControl

    * Use the Object keyword to set the Backcolor
    * property for the outline control.
    
    .Object.Backcolor = 16776960  && Light blue
    
    * Set properties of the OLE container control.
    Height = 100
    Width = 200
    Visible = .T.
ENDDEFINE

Passing Arrays to ActiveX Controls

If you pass an array to an ActiveX control—for example, if you call one of the control's methods and want to pass it an array—you must pass the array by reference. If you pass the array by value (the default), only the first element will be passed.

Programmatically Adding ActiveX Controls to an OLE Container Control

You can use ADDOBJECT( ) to add an ActiveX control to an OLE container control programmatically at run time. The third argument in ADDOBJECT( ) is the OLE class ID for the ActiveX control. To determine the OLE class ID for an ActiveX control, add the ActiveX control to a form. The class ID for the ActiveX control appears in the OLEClass property in the Properties window.

The following example demonstrates how you can programmatically add the ActiveX ProgressBar control contained in COMCTRL32.OCX to a form. Note the third argument of ADDOBJECT( ) (COMCTL.ProgCtrl.1) that specifies the OLE class ID for the ActiveX ProgressBar control.

PUBLIC oForm
oForm = CREATEOBJECT("Form")  && Create a form

* The following line adds the ProgessBar control to the form.

oForm.ADDOBJECT("OleProgress", "OLEControl", "COMCTL.ProgCtrl.1")

* The following lines specify the location
* and size of the ProgressBar control. 

oForm.OleProgress.Top = 5
oForm.OleProgress.Left = 5
oForm.OleProgress.Height = 25
oForm.OleProgress.Width = 289

oForm.OleProgress.Visible = .T. && Display the ProgessBar
oForm.Visible = .T. && Display the Form

FOR i = 1 to 10
    oForm.OleProgress.Value = i * 10  && Update the ProgressBar
    = INKEY(1)  && Wait one second
ENDFOR

Note   If an ActiveX control is programmatically added to an OLE container control, the ActiveX control must be properly registered on the computer on which the Visual FoxPro application is run. Proper registration of the ActiveX control is the responsibility of the developer who distributes an application that uses ActiveX controls. The ActiveX controls included with Visual FoxPro (with the exception of MEDV141N.OCX, the MediaView 1.41 ActiveX control) are licensed to be distributed with any application.

The preferred method for distributing an application utilizing the ActiveX controls included with Visual FoxPro is to add ActiveX controls to .VCX visual class libraries. The .VCX visual class libraries are included in the Setup Wizard distribution directory, and the setup created by the Setup Wizard will automatically register the ActiveX controls on the computer on which the distributed application is installed.

For more information about distributing ActiveX controls with your applications, see "Including ActiveX Components" in Chapter 25, "Building an Application for Distribution" in the Developer's Guide.

ActiveX Troubleshooting

The following sections discuss problems you might encounter with ActiveX controls and suggest workarounds for the problems.

Support for ActiveX Controls

Because ActiveX controls are independent modules, not developed in or specifically for Visual FoxPro, they might exhibit behavior different than that of native Visual FoxPro controls. You might also experience problems when using them in Visual FoxPro or find that they work differently than they do in other programs.

For example, Visual FoxPro treats ISimpleFrame controls as true containers. Visual FoxPro also supports the ability to subclass ActiveX controls. Both of these features affect the language used when working with ActiveX controls. Some of the samples that you find in the control's documentation might need to be modified to work correctly in Visual FoxPro.

If you are experiencing a problem with a control, you might find that a workaround or a more recent version of the control is available. For the most up-to-date information, search the Visual FoxPro Knowledge Base using the keyword "ActiveX." The Knowledge Base contains sample code, version information, and known issues concerning ActiveX controls.

Automatically Resizing Panel Controls in Forms

If you add an ActiveX Threed Panel Control (as an OLE container control) to a form and then set its AutoSize property to 2 - AutoSize Panel Height To Caption, you might experience problems in redrawing the control. The control might appear very thin and might not allow you to reset its height. To correct this problem, reset its Caption property by double-clicking it in the Properties window. This causes the Caption property to be set to "(None)," and allows you to resize the panel as required.

Binding RichTextBox Controls to Memo Fields

If you attempt to bind a Microsoft RichTextBox control directly to a memo field in a table (by setting the control's ControlSource property to the name of the memo field), Visual FoxPro displays an error when you run the form, and unbinds the control. To work around this problem, you can copy the contents of the field to a variable that is updated whenever the record pointer is moved. Then bind the control to the variable instead of directly to the memo field. For an example of how to create this type of binding, see "Use the RichText Control" in the Solutions Sample.

ToolTips for Controls Inside ISimpleFrame Controls

To display ToolTip text for a control inside an ISimpleFrame ActiveX control (for example, for a command button inside an ActiveX SSTab control) set the ShowTips property of the ActiveX control itself to True. For controls outside of ISimpleFrame ActiveX controls, set the ShowTips property of the form to True.

Getting Help for Controls Inside ISimpleFrame Controls

If you put a native Visual FoxPro control inside an ISimpleFrame control (for example, if you put a command button inside an ActiveX SSTab control), you cannot display context-sensitive Help (What's This Help) for that control.

Moving Between SSTab Control Tabs in Design Mode

If you create a form that contains an SSTab control, then run the form from the Form Designer, and then return to design mode, you might not be able to display the first tab in the control by clicking it. If this occurs, you can try clicking it several times, or you can click on the very edge of the tab.

Using ISimpleFrame Controls in Page Frames

You might experience the following problems when working with ISimpleFrame controls (such as a Threed Frame control) in pages in a page frame:

If you place an ISimpleFrame control on one page in a page frame and then display the form, the control might initially appear on all pages. To prevent the control from appearing on any page except the page on which you placed it, set the control's Visible property to true in the page's Activate method and to false in its Deactivate method. Depending on what page is initially active when the form is run, you might also have to set the control's Visible property to false in the Activate method of the page that first appears.

If you place an ISimpleFrame control on a page in a form-based class, the control might appear on the Windows desktop when you create an instance of the class and show it. If so, you can correct the problem using this code in the Init method of the form:

* On the following line,2 represents
* the page on which the control appears.

THIS.PageFrame1.ActivePage = 2
THIS.Draw
THIS.PageFrame1.ActivePage = 1   && default page

Dragging and Dropping ActiveX Controls

You might not be able to establish drag and drop behavior for certain ActiveX controls. For example, you cannot drag ISimpleFrame controls. In other cases, you might find that establishing drag and drop between ActiveX controls results in an error.

Disabling or Enabling VTABLE Binding

Some ActiveX controls are documented to support VTABLE binding but do not fully do so. VTABLE binding allows the control's host to bind "early" to its members (properties and methods) for better performance. If the control does not support VTABLE binding, Visual FoxPro might experience a fatal error in the module OLEAUT32.DLL, or you might see a message such as "Not enough storage space is available to complete this operation."

If so, you can temporarily disable VTABLE binding by calling the new SYS(2333) function. The syntax is:

SYS(2333, 0)

After disabling VTABLE binding, you can create an instance of the control. Then reset VTABLE binding by calling SYS(2333,1) so that other ActiveX controls can take advantage of the speed increases offered by VTABLE binding.

Note   If you are testing ActiveX controls in Microsoft Visual Basic® version 4.0, you will not encounter this problem because that version of Visual Basic does not support VTABLE binding.

You can also create an entry in the Windows Registry to disable VTABLE binding for individual controls, which saves you the trouble of disabling it each time you want to create another instance of the control. To do so, create an entry using the following Registry key, in which clsid represents the class id of the control for which you are disabling VTABLE binding:

HKEY_CLASSES_ROOT\NoDualInterface\{clsid}

For example, you can disable VTABLE binding for the Internet Explorer Shell control by making this entry in the Registry:

HKEY_CLASSES_ROOT\NoDualInterface\{EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B}

ActiveX Control Help

Many of the ActiveX controls that ship with Visual FoxPro were originally created for use with other applications such as Visual Basic and Microsoft Access. When an ActiveX control is placed on a form and you press F1 for Help on the control, the Help that displays is from the original application, not Visual FoxPro.

If you place the SysInfo ActiveX control on a form, there is no Help available for the control through F1. For information about this control, see the SysInfo control Help file (SYSINFO.HLP) in the SYSTEM or SYSTEM32 directory.

The Visual FoxPro HWND (FOXHWND.OCX) and Visual FoxPro Foxtlib (FOXTLIB.OCX) ActiveX controls were created for use with Visual FoxPro. Visual FoxPro Help contains information about these controls.

ActiveX Interfaces Supported by Visual FoxPro

The following tables list the ActiveX features (Table 1) and interfaces (Table 2) supported by Visual FoxPro. These features and interfaces will be of interest to developers of ActiveX controls designed for use with Visual FoxPro.

Table 1: Supported Features

Embedded objects from in-process servers
Inside-out activation
Visual editing of embedded objects
Idispatch for events
Simple data binding
Extended control—Visible
Extended control—Default
ACTIVATEWHENVISIBLE
INSIDEOUT
INVISIBLEATRUNTIME
ALWAYSRUN
ACTSLIKEBUTTON
ACTSLIKELABEL
NOUIACTIVATE
ALIGNABLE
TAG
SIMPLEFRAME
SETCLIENTSITEFIRST
Keyboard: Tab handling including tab order
Keyboard: Default Button
Keyboard: Mnemonics
Keyboard: Escape Button

Table 2: Supported Interfaces

IadviseSink::OnRename
IadviseSink::OnSave
IadviseSink::OnClose
IOleInPlaceSite::CanInPlaceActivate
IOleInPlaceSite::OnInPlaceActivate
IOleInPlaceSite::OnUIActivate
IOleInPlaceSite::GetWindowContext
IOleInPlaceSite::OnUIDeactivate
IOleInPlaceSite::OnInPlaceDeactivate
IOleInPlaceSite::OnPosRectChange
IOleInPlaceSite::GetWindow
IOleInPlaceSite::ContextSensitiveHelp
IoleControlSite::LockInPlaceServer
IoleControlSite::OnControlInfoChanged
IoleControlSite::TransformCoords
IoleControlSite::TranslateAccelerator
IoleControlSite::OnFocus
IoleInPlaceFrame::GetWindow
IoleInPlaceFrame::ContextSensitiveHelp
IoleInPlaceFrame::GetBorder
IoleInPlaceFrame::RequestBorderSpace
IoleInPlaceFrame::SetBorderSpace
IoleInPlaceFrame::SetActiveObject
IoleInPlaceFrame::InsertMenus
IoleInPlaceFrame::SetMenu
IoleInPlaceFrame::RemoveMenus
IoleInPlaceFrame::SetStatusText
IoleInPlaceFrame::EnableModeless
IoleInPlaceFrame::TranslateAccelerator
IoleContainer::EnumObjects
Idispatch—Backcolor
Idispatch—DisplayName
Idispatch—Font
Idispatch—ForeColor
Idispatch—LocaleID
Idispatch—UserMode
Idispatch—UIDead
Idispatch—ShowGrabHandles
Idispatch—ShowHatching
Idispatch—DisplayAsDefaultButton
Idispatch—SupportsMnemonics
IpropertyNotifySink::OnChanged
IpropertyNotifySink::OnRequestEdit
IerrorInfo—OLE Automation Exceptions
IpersistStorage
IpersistStream or IPersistStreamInit

Additional Information on the Web

For additional information about creating ActiveX controls for applications such as Visual FoxPro, see the MSDN Online Web site at http://msdn.microsoft.com/default.asp or Microsoft’s Web site dedicated to all things ActiveX at http://www.microsoft.com/com/tech/activex.asp.