例子:
//------------------------
unit UnitMenu;
interface
uses
controls,comctrls,classes,windows,sysutils,
menus,dialogs, UnitAppConfig,forms;
type
TActionCmd = procedure (handle:Thandle;loginInf
loginInfo);stdcall;
procedure MenuClick(Sender:TObject);
implementation
uses dmunit;
procedure MenuClick(Sender:TObject);
var
menuID:string;
actcmd:string;
dllName:string;
dllH:THandle;
appPath:string;
ActionCmd:TActionCmd;
begin
appPath := extractFilePath(application.ExeName);
appPath := appPath+'Dll/';
menuID := (Sender as TMenuItem).Name; // name 保存的是 MenuID 的值
with DM.adoqryTemp do
begin
if active then close;
sql.Clear;
sql.Add('select actcmd,dllName,isexit from menu where menuID='''+Menuid+'''');
open;
if FieldByName('isExit').AsBoolean then
begin
application.Terminate;
exit;
end;
if FieldByName('actcmd').IsNull or FieldByName('dllName').IsNull then
begin
messagebox(0,pchar('无法找到要执行的命令,请与管理员联系'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;
actcmd:=FieldByName('actcmd').AsString;
dllName:=FieldByName('dllname').AsString;
close;
if (actcmd='') or (dllname='') then
begin
messagebox(0,pchar('无法找到要执行的命令,请与管理员联系'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;
dllH := loadlibrary(pchar(appPath+dllname));
if dllH = 0 then
begin
messagebox(0,pchar('无法找到动态链接库'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;
try
@ActionCmd := windows.getProcAddress(dllH,pchar(actcmd));
if @ActionCmd = nil then
begin
messagebox(0,pchar('无效的执行命令'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;
//showmessage(loginInfo^.constr);
try
ActionCmd(application.Handle,LoginInfo);
finally
actionCmd := nil;
end;
finally
FreeLibrary(dllH);
end;
end;
end;
end.
我的例子是从数据库中读数据,然后动态创建菜单,给每个菜单动态添加事件,所有的事件
是根据 菜单项的 Name(保存的是数据库里的 id),来读数据库中的 dll 文件名,以及导出的函数名,来执行该 dll 的函数
主程序就是一个框架,程序具体的实现都是由 dll 一实现