在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言 2、接口设计 插件程序的基本实现 unit UnitOfficeEntrance; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms; function ShowDLLForm( AHandle : THandle; ACaption : string; AUserID : string ) : boolean; stdcall; function FreeDLLForm( AHandle : THandle; ACaption : string; AUserID : string ) : boolean; stdcall; implementation uses UnitOfficialMainForm; // 改成MAINFORM的unit var DLL_Form : TFormOfficialMain; // 改成MAINFORM的NAME // ----------------------------------------- // Name: ShowDLLForm // Func: DLL插件调用入口函数 // Para: AHandle 挂靠程序句柄; ACaption 本窗体标题 // Rtrn: N/A // Auth: CST // Date: 2005-6-3 // ----------------------------------------- function ShowDLLForm( AHandle : THandle; ACaption : string; AUserID : string ) : boolean; begin result := true; try Application.Handle := AHandle; // 挂靠到主程序容器 DLL_Form := TFormOfficialMain.Create( Application ); // 改成MAINFORM的NAME try with DLL_Form do begin Caption := ACaption; StatusBar.Panels.Items[ 0 ].Text := AUserID; // Configure UI Show; end; except on e : exception do begin DLL_Form.Free; end; end; except result := false; end; end; // ----------------------------------------- // Name: FreeDLLForm // Func: DLL插件调用出口函数 // Para: AHandle 挂靠程序句柄 // Rtrn: true/false // Auth: CST // Date: 2005-6-11 // ----------------------------------------- function FreeDLLForm( AHandle : THandle; ACaption : string; AUserID : string ) : boolean; begin Application.Handle := AHandle; // 挂靠到主程序容器 if DLL_Form.Showing then DLL_Form.Close; // 如果窗口打开先关闭,触发FORM.CLOSEQUERY可取消关闭过程 if not DLL_Form.Showing then begin DLL_Form.Free; result := true; end // 仍然打开状态,说明CLOSEQUERY.CANCLOSE=FALSE else begin result := false; end; end; end. DLL工程文件代码如下:
library Official; { Important note about DLL memory management: ShareMem must be the first unit in your library’s USES clause AND your project’s (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses SysUtils, Classes, UnitOfficialDetailForm in ’ UnitOfficialDetailForm.pas ’, UnitOfficialMainForm in ’ UnitOfficialMainForm.pas ’, UnitOfficeEntrance in ’ UnitOfficeEntrance.pas ’, UnitOfficialClass in ’ .. .. PublicLibraryUnitOfficialClass.pas ’, UnitMyDataAdatper in ’ .. .. PublicLibraryUnitMyDataAdatper.pas ’, UnitMyHeaders in ’ .. .. PublicLibraryUnitMyHeaders.pas ’; {$R *.res} exports ShowDLLForm, FreeDLLForm; // 接口函数 begin end. 插件程序一旦调用了DLL窗口,窗口实例将会保持在HALL窗口的上层,因此不用担心遮挡的问题。 容器程序的实现 type //定义接口函数类型,接口函数来自DLL接口 TShowDLLForm = Function(AHandle:THandle; ACaption: String; AUserID:string):Boolean;stdcall; TFreeDLLForm = Function(AHandle:THandle; ACaption: String; AUserID:string):boolean;stdcall; 显示调用库函数需要如下几个步骤: var ShowDLLForm: TShowDLLForm; //DLL接口函数实例 FreeDLLForm: TFreeDLLForm; begin try begin APlugin.ProcAddr := LoadLibrary(PChar(sPath)); APlugin.FuncFreeAddr := GetProcAddress(APlugin.ProcAddr,’FreeDLLForm’); APlugin.FuncAddr := GetProcAddress(APlugin.ProcAddr ,’ShowDLLForm’); @ShowDLLForm:=APlugin.FuncAddr ; @FreeDLLForm:=APlugin.FuncFreeAddr; if ShowDllForm(Self.Handle, APlugin.Caption , APlugin.UserID) then Result:=True
4、一个具体的实现方法
type //定义插件信息类 TMyPlugins = class Caption:String; //DLL窗体标题 DllFileName:String; //DLL文件路径 WndClass:String; //窗体标识 UserID:string; //用户名 ProcAddr:THandle; //LOADLIBRARY载入的库句柄 FuncAddr:Pointer; //SHOWDLLFORM函数指针 FuncFreeAddr:Pointer; //FREEDLLFORM函数指针 end;
为每个插件创建一个TMyPlugins的实例,下文会讨论对这些实例的初始化方法。 //----------------------------------------- //Name: OpenPlugin //Func: 插件信息类控制过程: 初始化==》设置权限==》载入DLL窗口 //Para: APlugin-TMyPlugins; sAlias别名; iFuncValue权限值 //Rtrn: N/A //Auth: CST //Date: 2005-6-2 //----------------------------------------- procedure TFormHall.OpenPlugin(AFromActn: TAction ;APlugin:TMyPlugins; sAlias:string; sUserID:string); var hWndPlugin:HWnd; begin //判断插件窗口是否已经载入 hWndPlugin:=FindWindow(PChar(APlugin.WndClass),nil); if hWndPlugin <> 0 then //插件窗口已经载入 begin if not IsWindowVisible(hWndPlugin) then begin AFromActn.Checked := True; ShowWindow(hWndPlugin,SW_SHOWDEFAULT); //显示 end else begin AFromActn.checked := False; ShowWindow(hWndPlugin,SW_HIDE) ; end; Exit; //离开创建插件过程 end; //初始化插件类实例 if not InitializeMyPlugins(APlugin,sAlias) then begin showmessage(’初始化插件类错误。’); exit; end; //获得当前权限值 APlugin.UserID := sUserID; //载入DLL窗口 if not LoadShowPluginForm(APlugin) then begin showmessage(’载入中心插件出错。’); exit; end; end; //----------------------------------------- //Name: InitializeMyPlugins //Func: 初始化MYPLUGIN实例 (Caption | DllFileName | IsLoaded) //Para: APlugin-TMyPlugins //Rtrn: N/A //Auth: CST //Date: 2005-6-2 //----------------------------------------- function TFormHall.InitializeMyPlugins(APlugin:TMyPlugins; sAlias:String):Boolean; var strSQL:string; myDA:TMyDataAdapter; begin Result:=False; myDA:=TMyDataAdapter.Create; strSQL:=’SELECT * FROM SystemModuleList WHERE modAlias=’+QuotedStr(sAlias); try myDA.RetrieveData(strSQL); except on E:Exception do begin result:=false; myDA.Free ; exit; end; end; try begin with myDA.MyDataSet do begin if Not IsEmpty then begin APlugin.Caption:= FieldByName(’modName’).Value; APlugin.DllFileName := FieldByName(’modFile’).Value; APlugin.WndClass := FieldByName(’modWndClass’).Value ; result:=True; end; Close; end; //end of with...do... end; //end of try except on E:Exception do begin Result:=False; myDA.Free ; Exit; end; //end of exception end; //end of try...except myDA.Free ; end; //----------------------------------------- //Name: LoadShowPluginForm //Func: 载入DLL插件并显示窗口 //Para: APlugin-TMyPlugins //Rtrn: true-创建成功 //Auth: CST //Date: 2005-6-2 //----------------------------------------- function TFormHall.LoadShowPluginForm (const APlugin:TMyPlugins):boolean; var ShowDLLForm: TShowDLLForm; //DLL接口函数实例 FreeDLLForm: TFreeDLLForm; sPath:string; //DLL文件的完整路径 begin try begin sPath:=ExtractFilepath(Application.ExeName)+ ’plugins’ + APlugin.DllFileName ; APlugin.ProcAddr := LoadLibrary(PChar(sPath)); APlugin.FuncFreeAddr := GetProcAddress(APlugin.ProcAddr,’FreeDLLForm’); APlugin.FuncAddr := GetProcAddress(APlugin.ProcAddr ,’ShowDLLForm’); @ShowDLLForm:=APlugin.FuncAddr ; @FreeDLLForm:=APlugin.FuncFreeAddr; if ShowDllForm(Self.Handle, APlugin.Caption , APlugin.UserID) then Result:=True else Result:=False; end; except on E:Exception do begin Result:=False; ShowMessage(’载入插件模块错误,请检查PLUGINS目录里的文件是否完整。’); end; end; end;
4) DLL窗口控制 procedure TFormHall.ClosePlugin(aPLG:TMyPlugins); var FreeDLLForm:TFreeDLLForm; begin if aPLG.ProcAddr = 0 then exit; if aPLG.FuncFreeAddr = nil then exit; @FreeDLLForm:=aPLG.FuncFreeAddr; if not FreeDLLForm(Application.Handle,’’,’’) then showMessage(’err’); end;
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论