博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
主控程序之主窗体
阅读量:7021 次
发布时间:2019-06-28

本文共 3417 字,大约阅读时间需要 11 分钟。

使用TRzMenuController控件只是为了增加主菜单的皮肤效果,可清除此控件

主控程序的主窗口单元要实现的需求如下:

1.自动识别并加载各个已经注册的插件;

2.自动识别并加载各个已经注册的插件中的各个模块(自动生成系统的主菜单,自动生成各菜单项的点击事件);

unit uMainForm;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Menus, Loader, Buttons, uInterface, DB
  ,Masks, ExtCtrls, ToolWin, ADODB, RzCommon;

type

  TMainForm = class(TForm)
    mainmenu1: TMainMenu;
    cdsLibrary: TADOTable;
    cdsMenu: TADOTable;
    N11: TMenuItem;
    RzMenuController1: TRzMenuController;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FDllsPath: string;
    FDllList: TStringList;
    FLoaders: array of TLoader;
    FLoadersContainer: TStringList;
    procedure RunForm(DLLName, aClassName: string);
    procedure CreateMenu(Dataset: TDataSet; Menu: TMainMenu);
    procedure MenuItemClick(Sender: TObject);
  public
    { Public declarations }
  end;

var

  MainForm: TMainForm;

implementation

uses uDM;

{$R *.dfm}

procedure TMainForm.MenuItemClick(Sender: TObject);

begin
  if cdsMenu.Locate('ModuleId', TMenuItem(Sender).Hint, []) then  // TMenuItem(Sender).Hint=ModuleId
    RunForm(cdsMenu.FieldByName('DLL').AsString, cdsMenu.FieldByName('ClassName').AsString);
end;

procedure TMainForm.RunForm(DLLName, aClassName: string);

var
  i: Integer;
begin
  if DLLName = '' then Exit;
  if aClassName = '' then Exit;
  i := FLoadersContainer.IndexOf(DLLName);
  if i = -1 then Exit;
  TLoader(FLoadersContainer.Objects[i]).ModelServiceInts.Cmd(PChar(aClassName));
end;

procedure TMainForm.CreateMenu(Dataset: TDataSet; Menu: TMainMenu);

var
  p, m: TMenuItem;
begin
  if not Dataset.Active then Exit;
  if Dataset.IsEmpty then Exit;
  if Menu = nil then Exit;
  Menu.Items.Clear;
  p := nil;
  Dataset.First;
  while not Dataset.Eof do                      // 此算法要求MODULEID必须可以排序
  begin
    m := TMenuItem.Create(self);
    m.Hint := Dataset.FieldByName('ModuleId').AsString;
    m.Caption := Dataset.FieldByName('ModuleName').AsString;
    if (Dataset.FieldByName('ParentId').AsString = '') or               // one level's root node
      (Dataset.FieldByName('ParentId').AsString = Dataset.FieldByName('ModuleId').AsString) then begin
      p := m;
      Menu.Items.Add(m);
    end else if (Dataset.FieldByName('ParentId').AsString <> '') and   // second level's root node
      (Dataset.FieldByName('ClassName').AsString = '') then begin
      p.Add(m);
      p := m;
    end else begin                                                    // son node
      p.Add(m);
      m.OnClick := MenuItemClick;
    end;
    Dataset.Next;
  end;
end;

procedure TMainForm.FormCreate(Sender: TObject);

var
  i: Integer;
begin
  cdsLibrary.IndexFieldNames := 'DLL';
  if cdsLibrary.IsEmpty then raise Exception.Create('没有注册任何插件');
  cdsMenu.IndexFieldNames := 'ModuleId';
  if cdsMenu.IsEmpty then raise Exception.Create('没有注册任何菜单项');

  FDllsPath := ExtractFilePath(Application.ExeName);       // load plugins

  FDllList := TStringList.Create;
  FLoadersContainer := TStringList.Create;
  SetLength(FLoaders, cdsLibrary.RecordCount);
  i := 0;
  cdsLibrary.First;
  while not cdsLibrary.Eof do begin
    FLoaders[i] := TLoader.Create(FDllsPath + cdsLibrary.FieldByName('DLL').AsString);
    FLoadersContainer.AddObject(ExtractFileName(FDllsPath + cdsLibrary.FieldByName('DLL').AsString), FLoaders[i]);
    cdsLibrary.Next;
    i := i + 1;
  end;

  CreateMenu(cdsMenu, mainmenu1);                        // load menu items

end;

procedure TMainForm.FormDestroy(Sender: TObject);

var
  i: Integer;
begin
  for I := Low(FLoaders) to High(FLoaders) do
  begin
    if Assigned(FLoaders[i]) then
      FLoaders[i].Free;
  end;
  FreeAndNil(FDllList);
  FreeAndNil(FLoadersContainer);
end;

end.

转载地址:http://bebxl.baihongyu.com/

你可能感兴趣的文章
火币网程显峰:区块链技术风险到底是些什么鬼?
查看>>
已知bug列表——Solidity中文文档(12)
查看>>
Java面向对象(二)
查看>>
Mybatis——构造方法
查看>>
Amino——范围层
查看>>
使用 QuickBI 搭建酷炫可视化分析
查看>>
SpringCloud 微服务 (六) 服务通信 RestTemplate
查看>>
PageOfficeV4.0 隐藏Excel的行号列标
查看>>
从MySQL到HBase:数据存储方案转型的演进
查看>>
Qt5开发及实例学习之不规则窗体:没看懂
查看>>
为什么不推荐用JWT保护你的Web应用
查看>>
带你了解MySQL数据库小技巧
查看>>
Java代码自动部署
查看>>
cmake 自动add_subdirectory
查看>>
凑个热闹,分析下Padavan的代码,一
查看>>
RabbitMQ 高可用之镜像队列
查看>>
你真的懂redis的数据结构了吗?
查看>>
人工智能的下一步是什么?我们应如何定义生命?
查看>>
Chrome 开发者控制台中,你可能意想不到的功能
查看>>
设计模式的学习(12)责任链模式
查看>>