动态装载OCX,高手请进!高分赠送!

Michaelyfj 2002-01-14 01:34:47
一个ActiveX可视控件已经注册成功,我想在Delphi的应用程序中把
这个ActiveX空间动态创建,并把控件显示在Form上,有没有什么办法?
...全文
425 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
Michaelyfj 2002-04-22
  • 打赏
  • 举报
回复
我要的是运行时加载,看类型库有什么用?
foxnt 2002-04-21
  • 打赏
  • 举报
回复
DELPHI的菜单里就有生成类型库的拉。自己好好看看。:(
hugeant 2002-04-20
  • 打赏
  • 举报
回复
我也帮着升一升,说不定哪个路过的高手看见了
hugeant 2002-04-16
  • 打赏
  • 举报
回复
没人知道?
hugeant 2002-04-15
  • 打赏
  • 举报
回复
我也正在找这个问题的答案
在程序运行时,如果发现有一个OCX空间可以实现部分功能,就想调入并且加以
配置,以丰富界面,
程序编译时还不知道该OCX的存在

强烈关注中!! 谁能提供答案,我也给分
foxnt 2002-04-15
  • 打赏
  • 举报
回复
CreateOLE(COM)Object就是。
但是你必须有类型库.
MSHawk 2002-04-15
  • 打赏
  • 举报
回复
你可以使用OLECONTAINER来加载啊。
nne998 2002-04-15
  • 打赏
  • 举报
回复
ole.....
武稀松 2002-04-15
  • 打赏
  • 举报
回复
是使用createoleobject来加载的。你自己研究去吧!
Michaelyfj 2002-04-15
  • 打赏
  • 举报
回复
to mshawk(憨憨):
用OleContainer实现,你能给个例子吗?
Michaelyfj 2002-04-15
  • 打赏
  • 举报
回复
to foxnt:
在运行时如何产生类型库.
scripting 2002-04-15
  • 打赏
  • 举报
回复
我非常感兴趣
Michaelyfj 2002-04-11
  • 打赏
  • 举报
回复
这个问题非的解决不可
Michaelyfj 2002-03-18
  • 打赏
  • 举报
回复
我是说已经注册,在应用程序运行时如何把OCX加载到指定的界面上
Michaelyfj 2002-03-15
  • 打赏
  • 举报
回复
哪里有这方面的文章或源代码
qiubolecn 2002-03-15
  • 打赏
  • 举报
回复
你用createoleobject不行么?
huangbin277 2002-03-15
  • 打赏
  • 举报
回复
hah
武稀松 2002-03-15
  • 打赏
  • 举报
回复
让Delphi应用程序在运行时自动注册ActiveX控件

Flier@stu.ccnu.edu.cn

在使用Delphi或VB等可视化编程语言制作程序时,常常会用到大量的ActiveX控件(后缀
为OCX的控件或后缀为DLL的类型库),他们为应用程序的开发提供了简便的途径。但是
这些ActiveX控件在应用程序发布后,在用户的计算机上必须进行注册。用现有的安装程
序制作软件虽然可以很好地解决这个问题,但这样做的代价往往太大,一个安装程序本
身就有几十甚至几百KB,造成程序发行版本臃肿不堪。而且每次系统重装时都必须重新
安装一遍,如果直接把安装后程序复制到其它机器上也无法直接运行。
其实我们可以通过在程序中加入特殊的处理代码很简单地解决这个问题。
一般我们使用一个ActiveX的方法分为两种:一种是直接把可视化的ActiveX控件放到程
序中;另一种是在运行时根据需要实时建立。
如果是直接使用,则应用程序在初始化的过程中会自动寻找、创建所需的ActiveX控件,
如果控件没有注册,初始化程序会产生一个异常,我们只需要捕捉这个异常并处理之即
可。
在程序主Form中加入一个新的方法(Delphi 5中可以直接使用ApplicationEvents)
TfrmMain = class(TForm)

protected
procedure MyException(Sender: TObject; E: Exception);

procedure TfrmMain.MyException(Sender: TObject; E: Exception);
begin

if E is EOleSysError then
begin
if HRESULT(EOLESysError(E).ErrorCode) = REGDB_E_CLASSNOTREG then
RegisterOcx;
end
else
Application.ShowException(E);

end;
并将此方法赋值给系统Application变量,在主Form的OnCreate事件里加入一行
procedure TfrmMain.FormCreate(Sender: TObject);
begin

Application.OnException := MyException;

end;
Application是一个系统自动建立的变量,他管理着整个应用程序,他的OnException属
性所指向的方法可以替换缺省的异常处理。我们在这里建立了自己的异常处理方法,其
中对异常类的检测“if E is EOleSysError then”确认是否是对ActiveX控件操作产生
的异常, 代码“if HRESULT(EOLESysError(E).ErrorCode) = REGDB_E_CLASSNOTREG t
hen” 再进一步检测看看ActiveX控件是否是因为没有注册而出现错误,如果是,则注册
之。RegisterOcx是一个自定义的方法,我们等一会再讨论他。这里的EOLESysError.Er
rorCode是一个HRESULT类型属性,他保存着对ActiveX控件操作发生错误的错误代码,详
细信息请查阅帮助或MSDN资料。
如果是在运行时动态建立ActiveX控件,则直接处理建立时的异常即可,如

try
DemoOcx := CreateOleObject(‘Demo.Demo’);
except
on E:EOleSysError do
if HRESULT(E.ErrorCode) = CO_E_CLASSSTRING then
begin
if RegisterOcx then
DemoOcx := CreateOleObject(‘Demo.Demo’);
else
begin
MessageDlg('控件注册失败,程序无法正常使用!', mtError, [mbAbort], 0)
;
Application.Terminate;
end;
end
else
raise;

注意这里我是使用的按名字(ProgramID)创建的方法,因此Delphi首先调用了一次CLSID
FromProgID函数,把ProgramID转换成相应的ClassID,所以这里产生的异常不是类未注
册(REGDB_E_CLASSNOTREG),而是类名称字符串错误(CO_E_CLASSSTRING)。如果要使
用别的创建方法,可以按这个思路改变检测ErrorCode的不同值……
至此我们已经可以捕捉到所有的因为类未注册而产生的异常,然后我们来处理他:

const
OCX_FILENAME = ‘demo.ocx’;

function TfrmMain.RegisterOcx: Boolean;
var
SystemDir: string;
function RegisterIt(const FileName: string): Boolean;
var
si: TStartupInfo;
pi: TProcessInformation;
begin
FillChar(si, SizeOf(si), 0);
with si do
begin
cb := SizeOf(si);
wShowWindow := SW_HIDE;
dwFlags := STARTF_USESHOWWINDOW;
end;
Result := CreateProcess(PChar(SystemDir + 'RegSvr32.exe'),
PChar(' /s "' + FileName + '"'),
nil, nil, False, 0, nil, nil, si, pi);
end;
begin
SystemDir := NormalDir(GetSystemDir);
if FileExists(OCX_FILENAME) then
Result := RegisterIt(NormalDir(ExtractFilePath(ParamStr(0))) + OCX_FILEN
AME)
else if FileExists(SystemDir + OCX_FILENAME) then
Result := RegisterIt(SystemDir + OCX_FILENAME)
else
with dlgOpenOCX do
begin
InitialDir := SystemDir;
FileName := OCX_FILENAME;
if Execute then
Result := RegisterIt(FileName)
else
Result := False;
end;
end;
首先取得系统目录(/windows/system)的路径到SystemDir变量(这里用到了NormalDir和
GetSystemDir两个函数是从RXLib控件包里摘抄下来的,见后面附带的代码),然后检测
在当前目录,系统目录下是否存在需要注册的控件,如果没有找到则要求用户指定其存
放的位置(dlgOpenOCX是一个TopenDialog),如果找到了或者用户指定了,则调用子函
数RegisterIt注册之。
注册ActiveX控件可以使用Windows自带的一个注册工具RegSvr32.exe,他在Windows的系
统目录里可以找到,我们给他“/s”参数让他不产生注册成功信息,而且通过修改Tsta
rtupInfo内容让其在后台运行即不显示DOS Box。(其实RegSvr32也是直接调用OCX控件
的一个DllRegisterServer函数注册控件的)。至此,整个ActiveX自动注册机制已经完
成,你可以放心地发布带有ActiveX控件的应用程序了。
所有代码在NT 4.0SP6、Delphi 4和5下调试通过
附:GetSystemDir和NormalDir函数的代码
function NormalDir(const DirName: string): string;
begin
Result := DirName;
if (Result <> '') and not (Result[Length(Result)] in [':', '\']) then
begin
if (Length(Result) = 1) and (UpCase(Result[1]) in ['A'..'Z']) then
Result := Result + ':\'
else
Result := Result + '\';
end;
end;
function GetSystemDir: string;
var
Buffer: array[0..1023] of Char;
begin
SetString(Result, Buffer, GetSystemDirectory(Buffer, SizeOf(Buffer)));
end;

※ 来源:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: 202.114.32.13]
Michaelyfj 2002-02-27
  • 打赏
  • 举报
回复
?
ntserver4 2002-02-09
  • 打赏
  • 举报
回复
不如这样
begin
winexec('regsvr32 你的OCX.ocx', 0);
end;
加载更多回复(32)

829

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧