您的位置:首页 > 编程语言 > Delphi

Delphi框架中怎样实现主程序与插件之间的互相调用以及参数传递

2012-02-29 09:31 411 查看
插件工程的dpr文件引出了三个函数,分别是CreatDllMDIForm,FreeDllMDIForm和GetDllPluginSign,主程序中通过调用动态库中的这三个函数实现dll中窗口的创建,具体代码如下:

procedure LibraryProc(Reason: Integer);

begin

if Reason=DLL_PROCESS_DETACH then

if Assigned(DllApp) then

begin

Application:=DllApp;

Screen:=DllScreen;

end;

end;

procedure CreatDllMDIForm(var Form:TForm;App: TApplication;Scr:TScreen;Param:TMagicFrameParam;ParentForm:TForm); stdcall;

begin

gParam:=Param;

if DllApp=nil then

begin

DllApp:=Application;

Application:=App;

DllScreen:=Screen;

Screen:=Scr;

end;

if not IsCreated then

begin

try

//每个功能模块都需要修改的地方

//MDI子窗口Name,在一个系统中不允许重复

Form:=TfrmTemplate.Create(ParentForm);

frmTemplate:=TfrmTemplate(Form);

IsFree:=false;

IsCreated:=true;

except

end;

end;

end;

procedure FreeDllMDIForm(var Form:TForm);stdcall;

begin

if not IsFree then

begin

Form.Free;

Form:=nil;

IsFree:=true;

IsCreated:=false;

end;

end;

function GetDllPluginSign:string;stdcall;

begin

//与插件名字相同,用于验证

Result := 'PTemplate.dll';

end;

exports

CreatDllMDIForm,

FreeDllMDIForm,

GetDllPluginSign;

begin

DllApp:=nil;

DllScreen:=nil;

IsFree:=false;

IsCreated:=false;

DllProc:=@LibraryProc;

end.

在主程序中的调用代码如下:

procedure TModuleInfo.ShowForm(ParentForm:TForm);stdcall;

var

GetDllPluginSign:TGetDllPluginSign;

CreatDllMDIForm:TCreatDllMDIForm;

ServerFile,ClientFile:string;

mds:TMagicDataSet;

nSize:Cardinal;

LocalMachineName:Pchar;

strNote:string;

strMD5FileValue:string;

strTmp : string;

begin

//判断是否更新本地DLL

mds:=TMagicDataSet.Create(nil);

if not mds.Init(WebServerURL) then

begin

frmMainFrame.MsgBox.ErrorBox(mds.GetLastErrMsg);

mds.Free;

exit;

end;

if Handle=0 then//动态库尚未加载

begin

nSize:=255;

LocalMachineName:=StrAlloc(nSize*SizeOf(Char));

GetComputerName(LocalMachineName,nSize);

ServerFile:=ModulePath+FileName;

ClientFile:=ExeFilePath+ModulePath+FileName;

if mds.UpdateClientFile(ServerFile,ClientFile,NormalFile,strMD5FileValue,ParamStr(2)='cmdDebug') then

begin

if strMD5FileValue<>CONST_NOTNEEDEDUPDATE then

begin

mds.DBLogUpdate(UserID,UserCode,UserName,ClientFile,strMD5FileValue);

end;

end;

StrDispose(LocalMachineName);

//加载动态库

Handle:=LoadLibrary(PChar(ClientFile));

end;

mds.Free;

if Handle=0 then

exit;

@CreatDllMDIForm:=GetProcAddress(Handle, 'CreatDllMDIForm');

@GetDllPluginSign:=GetProcAddress(Handle, 'GetDllPluginSign');

if (@CreatDllMDIForm=nil)or(@GetDllPluginSign=nil) then

exit;

Param.ModuleID:=ModuleID;

Param.WebServer:=WebServerURL;

Param.Database:=Database;

Param.UserID:=UserID;

Param.DeptID:=DeptID;

Param.UserCode:=Usercode;

Param.UserName:=UserName;

Param.DeptName:=DeptName;

Param.ModuleName:=copy(FileName,1,Pos('.',FileName)-1);

Param.FtpServer.Server:=gFtpServer;

Param.FtpServer.Port:=gFtpPort;

Param.FtpServer.User:=gFtpUser;

Param.FtpServer.Pwd:=gFtpPwd;

Param.StatusPanel:=frmMainFrame.StatusBarMain.Panels.Items[1];

Param.ProgressBar:=frmMainFrame.ProBar;

Param.ImageList:=frmMainFrame.ilBizAction;

Param.Toolbar := frmMainFrame.tbarMain;

Param.Navigation := frmMainFrame.pnlTree;

Param.FrameObject := TStrHashMap.Create;

Param.FrameObject.PutValue('VclSkin',frmMainFrame.SkinData);

Param.FrameObject.PutValue('MainMenu',frmMainFrame.MainMenu_main);

if (UpperCase(GetDllPluginSign)<>UpperCase(FileName)) then

begin

frmMainFrame.MsgBox.WarningBox('调用模块失败,请确认插件的合法性!');

Exit;

end;

CreatDllMDIForm(Form,Application,SCreen,Param,ParentForm);

if Form<>nil then

begin

if MDIWindowMax then

Form.WindowState := wsMaximized;

Form.Show;

IsFormCreated := true;

end

else

frmMainFrame.MsgBox.WarningBox('调用模块失败,请重试!');

end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: