Adding Code to Your Application
The structure of your application remains the same as
when using a dialog box that does not contain an ActiveX control. See
Writing a Dialog Application Overview for details.
This section discusses programming specific to ActiveX controls.
Your application must call
COMINITIALIZE
before calling
DLGINIT
with a dialog box
that contains an ActiveX control. Your application must include the statement
USE IFCOM
to access
COMINITIALIZE. Your application must call
COMUNINITIALIZE
when you are
done using ActiveX controls, but not before calling
DLGUNINIT
for the dialog box
that contains the ActiveX control.
You can call the methods of an ActiveX control and
set and retrieve its property values using the interfaces generated by the
Intel Fortran Module Wizard or by using the IFAUTO routines. To do this, you
must have the object's IDispatch interface pointer. Use the
DLGGET
function with the
ActiveX control's name, the DLG_IDISPATCH control index, and an integer
variable to receive the IDispatch pointer. For example:
retlog = DlgGet( dlg, IDC_ACTIVEX, idispatch, DLG_IDISPATCH )
You do not need to specify the index DLG_IDISPATCH
because it is the default integer index for an ActiveX control.
However, the control's IDispatch pointer is not
available until after the control has been created and is only valid until the
dialog box is closed. The control is created during the call to
DLGMODALDLGMODELESS
or . If
you call
DLGGET
to retrieve the
IDispatch pointer before calling
DLGMODAL
or
DLGMODELESS
, the value
returned will be 0.
Do not call
COMRELEASEOBJECT
with the
iDispatch pointer returned by
DLGGET
. The dialog procedures
use a reference counting optimization since the lifetime of the control is
guaranteed to be less than the lifetime of the dialog box.
If you want to use a method or property of a control
before the dialog box is displayed to your application's user, you can use a
DLG_INIT callback. Call
DLGSETSUB
using the dialog
box name and the DLG_INIT index to define the callback. For example:
retlog = DlgSetSub( dlg, IDD_DIALOG, DlgSub, DLG_INIT )
The
DLG_INIT
callback is called after the
dialog box is created but before it is displayed (with callbacktype=DLG_INIT)
and immediately before the dialog box is destroyed (with
callbacktype=DLG_DESTROY). The
DLG_INIT
callback is the soonest that
the control's IDispatch pointer is available. The
DLG_DESTROY
callback is the latest that
this pointer is valid. After the
DLG_DESTROY
callback, the ActiveX
control is destroyed.
The following example shows using a
DLG_INIT
callback to reset
the state of a control property before it is destroyed:
SUBROUTINE mmplayerSub( dlg, id, callbacktype ) !DEC$ ATTRIBUTES DEFAULT :: mmplayerSub use iflogm use ifcom use ifauto implicit none type (dialog) dlg integer id, callbacktype include 'resource.fd' integer obj, iret logical lret if (callbacktype == dlg_init) then lret = DlgGet(dlg, IDC_ACTIVEMOVIECONTROL1, obj) ! Add any method or property calls here before the ! dialog box is displayed else if (callbacktype == dlg_destroy) then ! Reset the filename to "" to "close" the current file lret = DlgGet(dlg, IDC_ACTIVEMOVIECONTROL1, obj) iret = AUTOSETPROPERTY(obj, "FileName", "") endif END SUBROUTINE mmplayerSub
The module generated by the Fortran Module Wizard for
an ActiveX control contains a number of sections:
- ! CLSIDsParameters of derived type GUID which identify the ActiveX control class. Your application typically doesn't need to use this parameter.
- ! IIDsParameters of derived type GUID which identify source (event) interfaces of the ActiveX control. Your application can use these values in calls to DLGSETCTRLEVENTHANDLER (see below).
- ! EnumsParameters of type integer that identify constants used in the ActiveX control's interfaces.
- ! InterfacesInterfaces for the source (event) interfaces that are defined by the ActiveX control. There may be 0, 1, or more source interfaces implemented by the control. A control does not have to support events.
- ! Module ProceduresWrapper routines that make it easy to call the control's methods and get or retrieve the control's properties.
See the
Language Reference
for more information on using the method and
property interfaces generated by the Intel Fortran Module Wizard.
In addition to methods and properties, ActiveX
controls also define events to notify your application that something has
happened to the control. The dialog procedures provide a routine,
DLGSETCTRLEVENTHANDLER
, that
allows you to define a routine to be executed when an event occurs.
The
DLGSETCTRLEVENTHANDLER
function has the following interface:
integer DlgSetCtrlEventHandler( dlg, controlid, handler, dispid, iid )
The arguments are as follows:
dlg | (Input) Derived type DIALOG. Contains
dialog box parameters.
|
controlid | (Input) Integer. Specifies the identifier
of a control within the dialog box (from the .FD file).
|
handler | (Input) EXTERNAL. Name of the routine to be
called when the event occurs.
|
dispid | (Input) Integer. Specifies the member id of
the method in the event interface that identifies the event
|
iid | (Input, Optional) Derived type (GUID).
Specifies the Interface identifier of the source (event) interface. If not
supplied, the default source interface of the ActiveX control is used.
|
Consider the following function call:
ret = DlgSetCtrlEventHandler( dlg, IDC_ACTIVEMOVIECONTROL1, & ActiveMovie_ReadyStateChange, -609, IID_DActiveMovieEvents2 )
In this function call:
- IDC_ACTIVEMOVIECONTROL1identifies an ActiveMovie control in the dialog box.
- ActiveMovie_ReadyStateChangeis the name of the event handling routine.
- -609is the member id of the ActiveMovie's control ReadyStateChange event. You can get this number from:
- The module that the Fortran Module Wizard generated. There is a "MEMBERID = nn" comment generated for each method in a source interface (see the example below).
- The documentation of the ActiveX control.
- A tool that allows you to examine the type information of the ActiveX control, for example, the OLE/COM Object Viewer in the Microsoft Visual Studio* IDE.
- IID_DActiveMovieEvents2is the identifier of the source (event) interface.
The interface generated by the Intel Fortran Module
Wizard for the ReadyStateChange event follows:
INTERFACE !Reports that the ReadyState property of the ActiveMovie Control !has changed ! MEMBERID = -609 SUBROUTINE DActiveMovieEvents2_ReadyStateChange($OBJECT, ReadyState) INTEGER(4), INTENT(IN) :: $OBJECT ! Object Pointer !DEC$ ATTRIBUTES VALUE :: $OBJECT INTEGER(4) :: ReadyState !DEC$ ATTRIBUTES VALUE :: ReadyState !DEC$ ATTRIBUTES STDCALL :: DActiveMovieEvents2_ReadyStateChange END SUBROUTINE DActiveMovieEvents2_ReadyStateChange END INTERFACE
The handler that you define in your application must
have the same interface. Otherwise, your application will likely crash in
unexpected ways because of the application's stack getting corrupted.
Note that an object is always the first parameter in
an event handler. This object value is a pointer to the control's source
(event) interface, not the IDispatch pointer of the control. You can use
DLGGET
as described above to
retrieve the control's IDispatch pointer.