Delphi的EXE程序如何用写代码调用ActiveX!!急!(100分)

  • 主题发起人 主题发起人 Rot007
  • 开始时间 开始时间
R

Rot007

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大侠:
本人项目组想用Delphi的EXE程序直接调用各个小模块(小模块都是生成的OCX),便于将来客户需要客户端用浏览器调用各业务模块的OCX,这样很简单实现两种客户端方式实现业务模块的调用;
项目组想不通过Import控件这样静态调用,想通过写Delphi代码直接动态调用各个OCX,像调用DLL一样实现,现在自动注册已经实现,请问有经验如何实现动态调用和传参数方法?
急!!!!!!!!!!!!!!!!
 
谁来帮忙啊
我也不懂啊...........
 
关注,答出我多给100分!!!!!!!
 
參考幫助,
CreateObject
CreateOleObject
或在 delphi6 開發人員指南
有詳細介紹
 
Aiirii,能否具体一点源代码,
动态调用更新各业务模块的版本就很容易,现在PM很急叫我研究出来
 
这有个资料你看看呗
Delphi中动态加载ActiveX控件

如何在Delphi中动态加载ActiveX控件?其实很简单!嗯,大家做好了,下面以ShockWaveFlash控件为例讲解如何动态加载ActiveX控件!

首先,我们知道,ActiveX控件都有TypeLib或者导出单元的,因此我们首先应该生成一个Object Pascal格式的单元来封装这个ActiveX控件,这个封装过程Delphi可以全自动完成,我们不必要写任何代码!首先,在Delphi菜单Component-->Import ActiveX Control,在弹出的对话框中(如下图):

选择ShockWave Flash,然后点击Install...,然后选择你需要安装的包,默认采取dclusr.dpk即可!然后弹出Package DPK窗口(如下图):

此时我们点击[Install]工具按钮即可,默认情况下, 新的控件将被安装到ActiveX控件页面,此时我们可以和普通控件一样使用这个Flash控件了,但是我们要动态创建的话,也很简单,首先,我们在uses部分添加ShockwaveFlashObjects_TLB单元,然后在FormCreate事件中,添加代码:
procedure TForm1.FormCreate(Sender: TObject);
begin
OpenDialog1.Filter :='SWF Files (*.SWF)|*.SWF';
with OpenDialog1 do
if Execute then
with TShockwaveFlash.Create(Self) do
begin
Height := 100;
Width := 100;
Top := 30;
Align := alClient;
Parent := Self;
Visible := True;
OnFSCommand :=MyCommand;
Movie := FileName;
Play;
end;
end;

procedure TForm1.MyCommand(Sender: TObject
const command,
args: WideString);
begin
Caption :=Format('Command:%s,Args:%s',[Command,args]);
end;
这样我们就可以动态生成和使用ActiveX控件了,实际上,是非常简单的,和普通的控件没有任何区别。上面的代码必须先导入类型库,限制了应用,如果我们要动态创建任意的ActiveX控件那么该怎么办呢?可以利用OLE Container控件来达到我们的目的!我们可以动态创建TOLEContainer控件,然后OleContainer有可以动态创建任意的对象,例如:
procedure TForm1.Button1Click(Sender: TObject);
begin
OleContainer1.CreateObject(Edit1.Text,False);
OleContainer1.DoVerb(ovShow);
end;
然后我们运行程序,在Edit里面输入'ShockwaveFlash.ShockwaveFlash.1'点击Button1,然后在Edit里面输入Word.Document,然后点击Button,你会发现我们已经能够动态创建任意的ActiveX控件了。 :-)
注意,若目标机器上面没有安装OCX控件,我们可以在程序的最开始使用WinExec或者ShellExecute()运行regsvr32 来注册OCX控件即可,否则可能无法创建控件。
 
呵呵,我告诉你个方法,不用注册,就可以调用,
免注册,但有前提,你的ocx不能互相调用,
也可以调用DLL中封装的com对象
例子代码如下:是个调用串口控件的例子:

下面是用上面的函数从ocx 文件中创建对象的例子
此处创建了一个 MSCOMM32 的串口控件,
调用了此控件的 AboutBox 的对话框,

不管此ocx 文件是否已经注册到系统中,下面的程序都会正常执行

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComObj, ActiveX;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
ocxhdl: THandle;
comm: Variant;
end;

const
CLASS_MSComm: TGUID = '{648A5600-2C6E-101B-82B6-000000000014}';


var
Form1: TForm1;

function CreateComObjectFromDll(CLSID: TGUID
DllHandle: THandle): IUnknown;

implementation

{$R *.dfm}

function CreateComObjectFromDll(CLSID: TGUID
DllHandle: THandle): IUnknown;
var
Factory: IClassFactory;
DllGetClassObject: function(const CLSID, IID: TGUID
var Obj): HResult;
stdcall;
begin
DllGetClassObject := GetProcAddress(DllHandle, 'DllGetClassObject');
if Assigned(DllGetClassObject) then
begin
DllGetClassObject(CLSID, IClassFactory, Factory);
Factory.CreateInstance(nil, IUnknown, Result);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ocxhdl := LoadLibrary('mscomm32.ocx');
if ocxhdl < 32 then
ShowMessage('error');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
comm := CreateComObjectFromDll(CLASS_MSComm, ocxhdl) as IDispatch;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
comm.AboutBox;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
comm := Null;
end;

end.

怎么样,还满意吧?
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleCtrls, StdCtrls, Buttons;

type
TMyOleCtrl=class(TOleControl)
private
FOleData:TControlData2;
FClassID:TGUID;
FEventID:TGUID;
procedure InitControlData
override;
public
constructor Create(AOwner: TComponent;ClassID,EventID:TGUID);
end;

TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TMyOleCtrl }

constructor TMyOleCtrl.Create(AOwner: TComponent
ClassID, EventID: TGUID);
begin
FClassID:=ClassID;
FEventID:=EventID;
inherited Create(Aowner);
end;

procedure TMyOleCtrl.InitControlData;
begin
FOleData.ClassID:=FClassID;
FOleData.EventIID:=FEventID;
FOleData.EventCount:=0;
FOleData.LicenseKey:=nil;
FOleData.Flags:=$0000001D;
FOleData.Version:=401;
FOleData.FontCount:=0;
ControlData := @FOleData;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
Const CID:TGUID='{67C0A2BB-C711-4FDD-BE4A-A5C507EDB8DF}'
//换成你自己的ActiveXClassID
EID:TGUID='{D670DE09-0CC5-4AC4-AA33-5AEAEC98409A}';//换成你自己的ActiveXEventIID
var V:TMyOleCtrl;
begin
V:=TMyOleCtrl.Create(application,CID,EID);
V.Parent:=Self;
end;

end.
 
TYZhang,为什么在编译环境下Project一直在Running状态?非编译环境下执行不会,很不好调试?
 
调用后,当前的可执行文件一直留有进程,退出可执行文件,Running状态,一直调用ActiveX
如何解决问题?
 
动态调用如何释放OCX,现在Exe退出后,Windows一直保留进程?搞不懂,期盼高手继续指点!
 
现在只剩下传递参数问题了,用TYZhang的方法不知道如何传参数?
 
我的方法多好,楼主竟然不用!
 
我现在把OCX当着DLL调用,不用注册,也可以通过调用的接口函数传参数,就是EXE主界面调用ACtiveX的界面比较难看!
 
后退
顶部