2008. március 19., szerda

Adding custom registry information on registration


Problem/Question/Abstract:

How to add custom information to the registry at the time an ActiveX control is registered.

Answer:

There are a number of times an ActiveX control writer will wont to insert custom information into the registry when a control is registered, and then remove the information when the control is unregistered.  

For example, you often need to insert custom information into the registry if you are writing a plugin/addin for another program (Microsoft Office products all require this), or you may want to include some extra information about your control that is not put there automatically (see the article on making insertable controls).  With Visual Basic you have to make a .Reg file to do this.  Luckily, with Delphi, we can do better.

To do this you need to override the default initialization of your ActiveX control.  To do this you need to create a custom class that inherits from either TActiveFormFactory or TActiveXControlFactory depending if you are in an ActiveForm project or an ActiveX Control project.  (Note: TActiveFormFactory inherits from TActiveXControlFactory).

So, we create a new class call TMyFactory.  There is one procedure we want to override call UpdateRegistry.  It has one parameter call “Register”.  If this is true your control is being registered, if it is false your control is being unregistered.  

My sample class is shown below.

uses
  AxCtrls, Registry;

type
  TMyFactory = class(TActiveFormFactory)
  private

  public
    procedure UpdateRegistry(Register: Boolean); override;
  end;

implementation

{ TMyActiveFormFactory }

//---------------------------------------------------------
// UdateRegistry
//  This procedure is called anytime you're ActiveX control
//    registered or unregistered.
//  Params: Register;  if True you are being registered
//                     if False you are being unregistered
//---------------------------------------------------------

procedure TMyFactory.UpdateRegistry(Register: Boolean);
var
  oReg: TRegistry;
begin
  inherited;

  oReg := TRegistry.Create;
  try
    if Register then
    begin
      // add extra registration entries here
    end
    else
    begin
      // remove extra registration entries here
    end;
  finally
    oReg.Free;
  end
end;

When that is all done, go to the initialization section of your ActiveX control and change it to the following (the example is for an ActiveForm) and you are done.

initialization
  //TActiveFormFactory.Create(  // old class factory
  TMyFactory.Create(// your new class factory
    ComServer,
    TActiveFormControl,
    TActiveFormX,
    Class_ActiveFormX,
    1,
    '',
    OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,
    tmApartment);

Things to remember:

If you need your control’s ProgID or ClassID that information is already there, passed in with the constructor and saved in FClassID.  To get the ProgID use the function ClassIDToProgID found in ComObj.
Because this code is called during registration debugging is possible but very difficult.   Essentially you have to recompile the VCL to use debug DCU’s. Even then no guarantees with the UpdateRegistry function.
There are other functions and procedures that you can overwrite here.  Some commonly overwritten procedures include: Create, GetLicenseString, HasMachineLicense, ValidateUserLicense, and occasionally GetProgID.
Just because you put the information into the registry does not necessarily mean you want to take it out.  One case for this behavior is when you want a control to work for a while then stop (so a user is forced to buy the control).
You aren’t restricted to the registry; many programs are now using XML for loading plugins/addins instead of the Registry.

Nincsenek megjegyzések:

Megjegyzés küldése