• 主控程序之主窗体


    使用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.

  • 相关阅读:
    5.JavaSE之数据类型详解
    4.JavaSE之标识符
    2.Java程序运行机制
    1.HelloWorld 仪式感
    10.安装开发环境
    【模板】后缀数组
    Luogu P3808 【模板】AC自动机(简单版)
    Luogu P3375 【模板】KMP字符串匹配
    LNSY集训
    Luogu P2580 于是他错误的点名开始了 (Trie树模板)
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2358370.html
Copyright © 2020-2023  润新知