COM Delphi

Title: Overriding the Registration exports from a COM In-Process Automation Server or ActiveX OCX Control
Question: Ever needed additional registry keys relating to your configuration settings to be created after you have registered your In-Process Automation Server DLL or your OCX control, and wished that this could be done by the library/control?
Answer:
Many of us may need, at some point in time, to perform set operations on the registration or un-registration of either an In-Process Automation Server or an ActiveX OCX control that we provide our customers. This article demonstrates how to achieve this in an actual implementation.
By default when you create a new ActiveX Library you will get a project source file that looks something like the following:
library Project1;
uses
ComServ;
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
{$R *.RES}
begin
end.
The Exports currently provided refers to routines contained in the ComServ unit, and uses these as the defaults to provide the already determined basic functionality of registering the in-process server library, or the ActiveX control.
Obviously there is very little point in us re-creating this same functionality in our control. We would rather use the original routines, but provide some additional work to be done as well.
We can do this by providing our own routine to be exported from the DLL instead of the default, but also call the default routine to perform the majority of the standard ActiveX registration.
Example Project Source Code:
library ExampleCustomRegistration;
{******************************************************************************
Initial Author : Scott Price
Initially Created: 25-Feb-2002
Language : Object Pascal
Compiler Version : Delphi 3.02, 4.03, 5.01, 6.01 (UK)
Copyright : Information Technology Sector Limited, 1996-2001
Source Code Constraints:
========================
This source code is intended for educational purposes relating to the
implementation of overriding elements to a COM Object Library/OCX.
Operating Systems Tested On:
============================
Microsoft Windows(R) ME
Microsoft Windows(R) 2000, Service Pack 2
Design Notes:
=============
This particular unit was provided to help demonstrate the implementation of
the DllRegisterServer and DllUnRegisterServer functions exported by a COM
Object Library/OCX control, so as to perform additional work at the time of
registration of the container.
===============================================================================
NOTES:
- This is a "Do Nothing" unit which shows how to enhance the registration
process, but does NOT include any COM Objects itself!
===============================================================================
TODO - :
******************************************************************************}
uses
{ Borland Standard Units }
ComServ,
Dialogs,
Registry,
SysUtils,
Windows;
const
pscRegKey: PChar = 'SOFTWARE\Information Technology Sector\Examples\Overriding DllRegisterServer';
pscFileLocation: PChar = 'FileLocation';
pscRegWriteAccess: PChar = 'Unable to Create the New Registry Key! Please check you have'#13 +
'permissions to perform this Registration!';
{ Function: DllRegisterServer }
{ Description: This function tries to obtain the location/path of the DLL
and store this value into the System Registry! }
function DllRegisterServer: HResult; stdcall;
var
Reg: TRegistry;
pcModuleFileName: PChar;
sFileName: String;
begin
TRY
Reg:= TRegistry.Create;
TRY
Reg.RootKey:= HKEY_LOCAL_MACHINE;
{ Check if we need to register the Library with the First Registration }
if (Reg.KeyExists(pscRegKey) = False) then
if (Reg.OpenKey(pscRegKey, True) = True) then
TRY
Reg.WriteString('', 'Example Custom DllRegisterServer Registration');
{ In this case, always overwrite the setting with the
current location of the DLL }
GetMem(pcModuleFileName, MAX_PATH);
TRY
if (GetModuleFileName(HInstance, pcModuleFileName, (MAX_PATH - 1)) 0) then begin
sFileName:= StrPas(pcModuleFileName);
Reg.WriteString(pscFileLocation, sFileName);
end;
FINALLY
FreeMem(pcModuleFileName);
END;
FINALLY
Reg.CloseKey;
END
else
{ FAILED!! Can not write to the Registry, Make It Known!! }
ShowMessage(pscRegWriteAccess);
FINALLY
SysUtils.FreeAndNil(Reg);
END;
FINALLY
{ DON'T FORGET! ALWAYS call the DEFAULT ComServ function! }
Result:= ComServ.DllRegisterServer;
END;
end;
{ Function: DllUnRegisterServer }
{ Description: This function tries to register the location of the DLL
into the System Registry }
function DllUnRegisterServer: HResult; stdcall;
var
Reg: TRegistry;
begin
TRY
Reg := TRegistry.Create;
TRY
Reg.RootKey := HKEY_LOCAL_MACHINE;
{ If our registry key exists, then delete it }
if Reg.KeyExists(pscRegKey) then
Reg.DeleteKey(pscRegKey);
FINALLY
FreeAndNil(Reg);
END;
FINALLY
{ DON'T FORGET! ALWAYS call the DEFAULT ComServ function! }
Result := ComServ.DllUnregisterServer;
END;
end;
exports
{ NOTE: Here we call the state that the functions are those from the ComServ unit }
ComServ.DllGetClassObject,
ComServ.DllCanUnloadNow,
{ NOTE: Here we specify the local functions for export instead }
DllRegisterServer,
DllUnRegisterServer;
{$R *.RES}
begin
end.
===============================================================================
The above project source code is also attached to this article for your viewing pleasure. I hope this helps some of you.
Regards,
Scott Price.