为了使代码简洁,我个人喜欢在工程中独立添加一个Unit单元(File New -- Unit),然后将所有要输出的函数体定义在此单元中,不要忘记将引用到的窗体的Unit也uses进来。我命名这个单元为UnitEntrance,在ShowDLLForm函数中初始化了要显示的窗口并调用Show方法显示,HALL会将登陆的用户名用参数传递过来,得到用户名后就可以进行一些权限控制,表现在界面初始化上。
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;
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' {FormOfficialDetail},
UnitOfficialMainForm in 'UnitOfficialMainForm.pas' {FormOfficialMain},
UnitOfficeEntrance in 'UnitOfficeEntrance.pas',
UnitOfficialClass in '../../Public/Library/UnitOfficialClass.pas',
UnitMyDataAdatper in '../../Public/Library/UnitMyDataAdatper.pas',
UnitMyHeaders in '../../Public/Library/UnitMyHeaders.pas';
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;
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;
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;