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;
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;
相关文章推荐
- 父类与子类之间静态函数的调用以及函数参数的传递
- Flash与JS之间相互调用以及参数传递
- Android开发系列(十三):Intent实现Activity之间的转换以及startActivityForResult传递参数
- Vue.js 实现表单数据参数传递,以及不同独立按钮之间的参数传递
- Android消息机制之实现两个不同线程之间相互传递数据相互调用
- JavaScript实现页面之间传递参数的方法
- struts2重定向时传递参数的实现!以及传递参数为中文时的乱码问题解决!
- Android之用Handler实现主线程和子线程互相通信以及子线程和子线程之间的通信
- Swift - 纯代码实现页面segue跳转,以及参数传递
- c#方法中调用参数的值传递方式和引用传递方式,以及ref与out的区别
- vc里面怎样实现对话框之间传递变量的值
- 用javascript实现html页面之间的参数传递的四种方法
- 实现页面之间的参数传递
- angular中实现控制器之间传递参数的方式
- Lisp语言:函数的定义,调用以及参数的传递
- 如何实现IE中JS和VC之间的互相调用
- VirtuaBox的安装功能增强,可以实现主机与虚拟机之间的互相拷贝以及虚拟机的任意大小
- Android 使用intent.putExtra实现Activity之间的参数传递
- Swift - 纯代码实现页面segue跳转,以及参数传递
- js实现两个页面之间跳转参数传递