Distributing Delphi Application which uses an ActiveX control
What's the best way to package the activex dll with the delphi application? If I just compile it, when I send it to somebody else it gives them errors because they don't have the Activ开发者_运维知识库eX dll registered.
What you ought to do is create an installer. There are several programs that will let you do that. I prefer InnoSetup, which is open-source, written in Delphi, and works really well. Just put your ActiveX DLL into the install package with your EXE and tell InnoSetup where it needs to go, (in the same folder as your app, in Sys32, or in a handful of other predefined locations,) and it takes care of the rest for you.
When I was creating COM servers at run-time I used sth. like the below. The idea is to catch the "class not registered" exception and attempt to register the server on the fly. With some search, you'll also find examples that read the registry for the class identifier to find out if an activex server is registered... I adapted the example to some 'MS Rich Text Box' (richtx32.ocx) but it wouldn't make a difference.
uses
comobj;
function RegisterServer(ServerDll: PChar): Boolean;
const
REGFUNC = 'DllRegisterServer';
UNABLETOREGISTER = '''%s'' in ''%s'' failed.';
FUNCTIONNOTFOUND = '%s: ''%s'' in ''%s''.';
UNABLETOLOADLIB = 'Unable to load library (''%s''): ''%s''.';
var
LibHandle: HMODULE;
DllRegisterFunction: function: Integer;
begin
Result := False;
LibHandle := LoadLibrary(ServerDll);
if LibHandle <> 0 then begin
try
@DllRegisterFunction := GetProcAddress(LibHandle, REGFUNC);
if @DllRegisterFunction <> nil then begin
if DllRegisterFunction = S_OK then
Result := True
else
raise EOSError.CreateFmt(UNABLETOREGISTER, [REGFUNC, ServerDll]);
end else
raise EOSError.CreateFmt(FUNCTIONNOTFOUND,
[SysErrorMessage(GetLastError), ServerDll, REGFUNC]);
finally
FreeLibrary(LibHandle);
end;
end else
raise EOSError.CreateFmt(UNABLETOLOADLIB, [ServerDll,
SysErrorMessage(GetLastError)]);
end;
function GetRichTextBox(Owner: TComponent): TRichTextBox;
begin
Result := nil;
try
Result := TRichTextBox.Create(Owner);
except on E: EOleSysError do
if E.ErrorCode = HRESULT($80040154) then begin
if RegisterServer('richtx32.ocx') then
Result := TRichTextBox.Create(Owner);
end else
raise;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
[...]
RichTextBox := GetRichTextBox(Self);
RichTextBox.SetBounds(20, 20, 100, 40);
RichTextBox.Parent := Self;
[...]
end;
精彩评论