COM技术的插件片段
procedure TfrmMain.LoadExplorableClasses;
var
Count, i : integer;
Explorable : IExplorable;
Description : widestring;
MenuItem : TMenuItem;
begin
//get explorable server list
Count := GetExplorableClasses (FExplorableClasses);
if (Count > 0) then
begin
//hide "no explorable items found" menu item
miNoExplorableItem.Visible := False;
//get description for each and populate Explore >> submenu
for i := 1 to Count do
begin
//create Explorable plugin
Explorable := CreateComObject (FExplorableClasses [i]) as IExplorable;
//get plugin description
OleCheck (Explorable.GetDescription (Description));
//create new menu item
MenuItem := TMenuItem.Create (Self);
MenuItem.Caption := Description;
//hide FExplorableClasses array index in Tag
MenuItem.Tag := i;
//hook OnClick handler
MenuItem.OnClick := miExplorableItemClick;
//add to Explore >> submenu
miExplore.Add (MenuItem);
end;
end;
end;一般插件的写法片段procedure TFrmMain.loadPlugins;
var
files: tstrings; //存放文件查找结果的文件列表
i: integer;
MyPlugin: TMyPlugin; //存放插件信息的自定义的变量
NewMenu: TMenuItem;
GetCaption: TGetCaption; //获取插件标题的过程引用
begin
files := tstringlist.Create; //文件列表
Plugins := tlist.Create; //建立指针列表
//查找当前目录的子目录plugins下的 .dll文件,并存于 "files 文件列表"中
SearchFileExt(Extractfilepath(application.ExeName)+'Plugins\','.dll',files);
//从文件列表中加载找到的DLL
for i:=0 to files.Count-1 do
begin
myPlugin := TMyPlugin.Create;
myPlugin.Address := loadlibrary(pchar(files[i])); //装载DLL,返回句柄
if myplugin.Address=0 then
showmessage('加载'+files[i]+'失败!')
else begin
try
@GetCaption:=GetProcAddress(myPlugin.Address,'GetCaption'); //通过DLL句柄取得“获取插件标题”过程的入口地址
myPlugin.Caption:=GetCaption(application.Handle); //返回插件标题
myPlugin.Call:=GetProcAddress(myPlugin.Address,'ShowDLLForm'); //获取并保存窗体显示过程的入口地址
Plugins.Add(myPlugin); //加入至指针列表
//创建菜单,并将菜单标题OnClick事件赋值
NewMenu:=TMenuItem.Create(self);
NewMenu.Caption:=myplugin.Caption;
newmenu.OnClick:=PluginsClick; //绑定事件
NewMenu.Tag:=i; //用此标识作为插件事件的区分
plugins1.Add(newMenu); //加入菜单项
except
showmessage('初始化失败!');
raise;
end;
end;
end;
files.Free;
end;两者有什么区别?优缺点是什么?
procedure TfrmMain.LoadExplorableClasses;
var
Count, i : integer;
Explorable : IExplorable;
Description : widestring;
MenuItem : TMenuItem;
begin
//get explorable server list
Count := GetExplorableClasses (FExplorableClasses);
if (Count > 0) then
begin
//hide "no explorable items found" menu item
miNoExplorableItem.Visible := False;
//get description for each and populate Explore >> submenu
for i := 1 to Count do
begin
//create Explorable plugin
Explorable := CreateComObject (FExplorableClasses [i]) as IExplorable;
//get plugin description
OleCheck (Explorable.GetDescription (Description));
//create new menu item
MenuItem := TMenuItem.Create (Self);
MenuItem.Caption := Description;
//hide FExplorableClasses array index in Tag
MenuItem.Tag := i;
//hook OnClick handler
MenuItem.OnClick := miExplorableItemClick;
//add to Explore >> submenu
miExplore.Add (MenuItem);
end;
end;
end;一般插件的写法片段procedure TFrmMain.loadPlugins;
var
files: tstrings; //存放文件查找结果的文件列表
i: integer;
MyPlugin: TMyPlugin; //存放插件信息的自定义的变量
NewMenu: TMenuItem;
GetCaption: TGetCaption; //获取插件标题的过程引用
begin
files := tstringlist.Create; //文件列表
Plugins := tlist.Create; //建立指针列表
//查找当前目录的子目录plugins下的 .dll文件,并存于 "files 文件列表"中
SearchFileExt(Extractfilepath(application.ExeName)+'Plugins\','.dll',files);
//从文件列表中加载找到的DLL
for i:=0 to files.Count-1 do
begin
myPlugin := TMyPlugin.Create;
myPlugin.Address := loadlibrary(pchar(files[i])); //装载DLL,返回句柄
if myplugin.Address=0 then
showmessage('加载'+files[i]+'失败!')
else begin
try
@GetCaption:=GetProcAddress(myPlugin.Address,'GetCaption'); //通过DLL句柄取得“获取插件标题”过程的入口地址
myPlugin.Caption:=GetCaption(application.Handle); //返回插件标题
myPlugin.Call:=GetProcAddress(myPlugin.Address,'ShowDLLForm'); //获取并保存窗体显示过程的入口地址
Plugins.Add(myPlugin); //加入至指针列表
//创建菜单,并将菜单标题OnClick事件赋值
NewMenu:=TMenuItem.Create(self);
NewMenu.Caption:=myplugin.Caption;
newmenu.OnClick:=PluginsClick; //绑定事件
NewMenu.Tag:=i; //用此标识作为插件事件的区分
plugins1.Add(newMenu); //加入菜单项
except
showmessage('初始化失败!');
raise;
end;
end;
end;
files.Free;
end;两者有什么区别?优缺点是什么?
最讨厌COM要写注册表,本质上没有什么区别,有的只是一个是微软帮你订好的规范,一个是要你自己来订。
我更看好直接加载DLL!
你使用Depend之类的工具只能分析出4个基本的函数,内部函数是无法获取到的。
2。可以使用类似对象的方式进行访问。
使用Dll提供接口只能是平面的,比如提供函数。但是COM可以让你获取对象指针(当然是COM对象)
这样,对象的层次关系更为明显。
3。这是一个相对通用的二进制标准。插件开发者不需要先熟悉不同的特定的规范标准(当然要依照COM规范)。COM的弊端
1。需要换一种方式思考问题。
一般情况下,我们写代码都习惯于谁创建,谁释放。但是使用COM,通常你创建了就不由你释放了。对象
之间的有效性及同步问题比较麻烦。
2。多线程序的控制比较麻烦。
按一些书上的说明叫做线程套间。我没仔细看,但是感觉上比直接使用Dll的函数进行线程同步要麻烦很多。
3。对程序员的要求相对较高。
COM开发对开发人员的水平,以及对开发人员对COM机制的熟悉程度要求比较高。要想开发一个比较稳定的
COM插件相对来讲比使用DLL的函数更复杂一些。这是我的一些体会。