2011. április 4., hétfő

Create a run-time invisible ActiveX Control


Problem/Question/Abstract:

How to create a run-time invisible ActiveX Control.

Answer:

Every so often there is a need for a control that can be placed on a form, manipulate it’s properties and run the form; then, gasp, the control is invisible to the user!  A common example of this is Visual Basic’s Timer control.  You set the interval, set enabled to true, and do something in the OnTime event and you are working.  All completely transparent to the user.   Delphi examples of this are the Delphi Timer and the ImageList controls.

As stated, this can be done for an ActiveX control running on a Visual Basic or VBA form.  In design time you see the control, in run-time you don’t.  So how is it done?

At the bottom of every ActiveForm with an Automation object is an Initialization section.  The default one created by Delphi looks like this:

initialization
  TActiveFormFactory.Create(
    ComServer,
    TActiveFormControl,
    TActiveFormX,
    Class_ActiveFormX,
    1,
    '',
    OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
    tmApartment);

The seventh field is MiscStatus, this tells the container about the controls default behavior and how to treat it, and this is the field we want to change.

The flag we need is OLEMISC_INVISIBLEATRUNTIME.  You add it to the field with an OR.  The end result follows:

TActiveFormFactory.Create(
  ComServer,
  TActiveFormControl,
  TActiveFormX,
  Class_ActiveFormX,
  1,
  '',
  OLEMISC_INVISIBLEATRUNTIME or OLEMISC_ACTSLIKELABEL,
  tmApartment);

You may notice that I replaced the OLEMISC_SIMPLEFRAME with OLEMISC_INVISIBLEATRUNTIME.  OLEMISC_SIMPLEFRAME mean that this control can hold other controls inside of it, acting like a container.  Most of the time this is not what you want for an invisible control.  

After you have made the change, compile the project and through it on a form.  The control will display the same behavior on a Visual Basic form, Microsoft Word document, Excel spreadsheet, VBA form, and even on a Delphi Form.

There is a separate issue here that also comes up, and that is sizing.  How do you get the control to come up at the correct size (say 32 by 32) and stay that size.

This has to be done in the constructor (setting the contstraints in this case will not work, since 32 by 32 is smaller than Delphi will allow you to size a form).

So in your constructor add code similar to this:

Self.Width := 32;
Self.Height := 32;

Self.Constraints.MaxWidth := 32;
Self.Constraints.MaxHeight := 32;
Self.Constraints.MinWidth := 32;
Self.Constraints.MinHeight := 32;

Nincsenek megjegyzések:

Megjegyzés küldése