Когда я создавал COM-серверы во время выполнения, я использовал sth. как ниже. Идея состоит в том, чтобы перехватить исключение «класс не зарегистрирован» и попытаться зарегистрировать сервер на лету. При некотором поиске вы также найдете примеры, которые читают реестр для идентификатора класса, чтобы выяснить, зарегистрирован ли сервер activex ... Я адаптировал пример к некоторому MS Rich Text Box (richtx32.ocx), но не имеет значения.
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;