用DLL实现插件处理DEMO

{本程序演示内容:

实现自定义插件功能的处理! 插件DLL存放程序目录下的Plugins子目录中。}

//第一个插件的项目文件内容

library  Plugins ;

uses
   SysUtils ,
   Classes ,
   PluginsFrm  in  'PluginsFrm.pas'  {FrmPlugins} ;

{$R *.res}
exports
   GetCaption ,  ShowDllForm ;
begin
   //...
end .

//第一个插件项目的表单文件内容

unit  PluginsFrm ;

interface

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

type
   TFrmPlugins  =  class ( TForm )
     Label1 :  TLabel ;
   private
     { Private declarations }
   public
     { Public declarations }
   end ;
   //函数声明,各插件可约定这些过程
function  GetCaption ( aHandle :  tHandle ):  pchar ;  stdcall ;  //取得插件标题
function  ShowDllForm ( aHandle :  THandle ;  ACaption :  string ):  boolean ;  stdcall ;  //显示窗体
var
   FrmPlugins :  TFrmPlugins ;

implementation

{$R *.dfm}

//输出标题

function  GetCaption ( aHandle :  tHandle ):  pchar ;  stdcall ;
begin
   application . Handle  :=  aHandle ;
   Result  :=  '插件演示 01' ;
end ;

//打开窗体

function  ShowDllForm ( aHandle :  THandle ;  ACaption :  string ):  boolean ;
begin
   Result  :=  True ;
   application . Handle  :=  aHandle ;
   with  TFrmPlugins . Create ( application )  do
   begin
     try
       caption  :=  ACaption ;
       showmodal ;
     finally
       free ;
     end ;
   end ;
end ;
end .

//主控程序源码
unit  UnPluginMain ;

interface

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

type
   //定义接口函数类型
   TShowDllForm  =  function ( aHandle :  THandle ;  ACaption :  string ):  boolean ;  stdcall ;  //窗体显示
   TGetCaption  =  function ( aHandle :  tHandle ):  pchar ;  stdcall ;  //取标题,用于菜单项
   //定义TMyPlugin类,存放 Caption、Address,Call信息
   TMyPlugin  =  class
     Caption :  string ;                     //存取加载后的DLL中GetCaption返回的标题
     Address :  THandle ;                    //存取加载后的DLL的句柄
     Call :  Pointer ;                       //存取ShowDllForm函数的句柄,指针类型
   end ;
   //定义结束
   TFrmPluginMain  =  class ( TForm )
     MainMenu1 :  TMainMenu ;
     File1 :  TMenuItem ;
     Exit1 :  TMenuItem ;
     N1 :  TMenuItem ;
     PrintSetup1 :  TMenuItem ;
     Print1 :  TMenuItem ;
     N2 :  TMenuItem ;
     SaveAs1 :  TMenuItem ;
     Save1 :  TMenuItem ;
     Open1 :  TMenuItem ;
     New1 :  TMenuItem ;
     Plugins1 :  TMenuItem ;
     Memo1 :  TMemo ;
     procedure  FormCreate ( Sender :  TObject );
     procedure  FormDestroy ( Sender :  TObject );
     procedure  Exit1Click ( Sender :  TObject );
   private
     { Private declarations }
     procedure  LoadPlugins ;               //初始化插件(装入插件,并在菜单提供调用)
     procedure  PluginsClick ( Sender :  TObject );  //插件菜单点击事件
     procedure  FreePlugins ;               //释放插件
   public
     { Public declarations }
   end ;

var
   FrmPluginMain :  TFrmPluginMain ;
   ShowDllForm :  TShowDllForm ;             //声明接口函数类型
   Plugins :  TList ;                        //指针列表,存放每一个DLL加载后的相关信息
   StopSearch :  boolean ;

implementation

{$R *.dfm}
//查找文件,并存于Files中

procedure  SearchFileExt ( const  Dir ,  Ext :  string ;  Files :  TStrings );
var
   found :  TSearchRec ;
   Sub :  string ;
   i :  integer ;
   Dirs :  TStrings ;
   Finished :  integer ;
begin
   StopSearch  :=  false ;
   Dirs  :=  tstringlist . create ;
   finished  :=  findfirst ( dir  +  '*.*' ,  63 ,  Found );
   while  ( finished  =  0 )  and  not  ( StopSearch )  do
   begin
     if  ( Found . Name [ 1 ]  <>  '.' )  then
     begin
       if  ( found . attr  and  faDirectory  =  faDirectory )  then
         dirs . add ( dir  +  found . name )       //加入到目录列表
       else  if  POS ( UpperCase ( Ext ),  UpperCase ( found . name ))  >  0  then
         files . add ( dir  +  found . name );
     end ;
     finished  :=  findnext ( found );
   end ;
   findclose ( found );
   if  not  StopSearch  then
     for  i  :=  0  to  dirs . count  -  1  do
       searchfileext ( Dirs [ i ],  Ext ,  Files );
   Dirs . Free ;
end ;
//装载插件

procedure  TFrmPluginMain . loadPlugins ;
var
   files :  tstrings ;
   i :  integer ;
   MyPlugin :  TMyPlugin ;
   NewMenu :  TMenuItem ;
   GetCaption :  TGetCaption ;               //过程
begin
   files  :=  TStringlist . Create ;
   try
     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 ]));
       if  myplugin . Address  =  0  then
         showmessage ( '加载'  +  files [ i ]  +  '失败!' )
       else
       begin
         try
           @ GetCaption  :=  GetProcAddress ( myPlugin . Address ,  'GetCaption' );
           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 ;
   finally
     FreeAndNil ( files );
   end ;
end ;

//插件菜单项点击事件

procedure  TFrmPluginMain . PluginsClick ( Sender :  TObject );
begin
   //根据菜单项的TAG属性对应函数调用的地址
   @ ShowDllForm  :=  TMyPlugin ( plugins [ tmenuitem ( sender ). Tag ]). Call ;
   // showdllform(application.Handle,'test');
     //执行ShowDllForm函数
   if  not  Showdllform ( application . handle ,  TMyPlugin ( plugins [ TMenuItem ( sender ). Tag ]). Caption )  then
     showmessage ( '打开窗体错误!' );
end ;
//释放插件

procedure  TFrmPluginMain . FreePlugins ;
var
   i :  integer ;
begin
   for  i  :=  0  to  plugins . Count  -  1  do
   begin
     freelibrary ( tmyplugin ( plugins [ i ]). Address );
   end ;
   plugins . free ;
end ;

procedure  TFrmPluginMain . FormCreate ( Sender :  TObject );
begin
   LoadPlugins ;
end ;

procedure  TFrmPluginMain . FormDestroy ( Sender :  TObject );
begin
   FreePlugins ;
end ;

procedure  TFrmPluginMain . Exit1Click ( Sender :  TObject );
begin
   close ;
end ;

end .
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、中文简繁互换:在简体中文和繁体中文之间进行转换。 2、进制转换:在二进制、八进制、十进制、十六进制之间相互转换。 3、人民币大小写互换:在Excel中,很多时候需要将小写的金额数字转换成大写,而Excel提供的函数转换出来的格式并不符合中国人的习惯,所以... 4、数字签名:对Excel表格中的内容进行签名保护,主要是防止提供者提供的内容被非法修改。可以用于Excel公文的电子签名,实现真正的无纸办公... 5、保存为图片文件:相当于Excel的照相机功能(有过之而无不及)。可以将Excel中的单元格区域、Shape对象、图片、图表等(甚至是组合形式)以gif、jpg、bmp等各式保存到磁盘中。 6、全功能批注----真正所见即所得的批注编辑器。 7、VB/VBA代码归纳与重写:对VB/VBA代码进行混淆,大大降低代码的可读性,是一种保护VB/VBA代码的很有效的方法。详细的注释说明和一目了然的名称将有助于设计阶段的调试和查错,但是代码一旦发布后,这些优点将会使黑客轻而易举地破解你的成果,呵呵,用这个吧,保证黑客对您的VB/VBA代码一点兴趣和胃口都没有!! 8、解除Excel文档的内部密码。很多时候,我们需要设置Excel表格/工作簿的保护密码,可是随着时间的推移,这些密码很可能遗忘了,怎么办?很着急啊!!!哈哈,用这个保证在2分钟之内解决问题(换个角度:不要再自欺欺人了,Excel的内部密码形同虚设)。 9、信息加密/解密。对Excel文档中的一些敏感信息进行加密处理,即使文档被破解了,里面的信息仍然很安全。可以说这个功能是对Excel安全的一个有力补充。 10、工程代码锁定解锁器。可以撤销Excel的VBA保护密码(对word、Access同样有效) 11、控制和保存功能。这个功能能满足我们不用记一个密码就能非常有效地保护我们的Excel文档,而且可以免除来自微软的威胁。 12、Cookie管理器。在信息时代,没有网络怎么可以?上网时间长了,就会发现在临时文件夹中挤满了cookies,不但占据磁盘空间,而且还可能泄露秘密。用“清理cookie”命令吧,又觉得有些没有必要删,否则下次还得再输一遍;一个一个删吧,东西太多,想都不能想。怎么办??用这个啊!!只要一次性设置要保留的cookie并选中“退出Excel时自动清理”即可。以后只要退出Excel,你的cookies目录中就不会再有其它乱七八糟的cookie了。 13、超级预览。可以根据当前的选择内容自动调整预览对象。如果选中的是单元格区域,就只预览你选中的区域;如果选中的是图表,则仅预览选中的图表;如果只是一个单元格,则自动显示分页符... ... 14、屏幕锁定。当我们需要临时离开电脑而又不想关闭Excel文档时(并不局限于Excel文档,也可以是其它,但前提是要运行Excel),可以启动这个功能,这样其他人就不可能看到您不希望他们看到的东西。 15、尝试打开忘记密码的文件。暴力破解Excel的打开密码,注意:这个仅对拥有密码设计方案的人有效。 16、Excel加载项/宏管理器。对当前Excel环境下的加载宏/加载项/VBA加载项进行列表,并可以查看相关属性、修改运行状态,甚至是一键破解。 17、Excel对象管理器,可以批量转换Excel中的对象(图片、Shape、图表等)到图片文件; 18、在Excel中播放背景音乐、定时执行特定的程序、整点报时,一定很惬意... 19、屏幕录像及捕捉。哦,这个功能很强大啊。可以截取屏幕图像、录制屏幕变化、图片格式转换、批量bmp转成AVI文件、AVI文件转成动画GIF文件、图片标注... ...强大的不行啦,赶快去看看吧。快捷键:Ctrl+Alt+SpaceBar 或者 Ctrl+左WinKey(微软左徽标键) 20、DLL神探,DLL的最大威胁就是注入到系统进程中,让人防不胜防... 21、一键恢复Excel的系统菜单。这个功能... ... 22、Excel版简易游戏。只是几个可以在Excel中玩的游戏... 23、计划横道图(甘特图)。偶觉得还是用Excel来做横道图最方便了... ... 24、偶将呆板的网络调查和网络投票移植到OBS.DLL中了,变被动为主动! 。。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值