zoukankan      html  css  js  c++  java
  • BPL插件框架的二种实现方法

    BPL插件框架的二种实现方法
    1)非RTTI方式适用于所有的DELPHI版本
    unit untMain;
    
    interface
    
    uses
      Windows, Messages, SysUtils,
      Classes, Graphics,
      Controls, Forms, Dialogs,
      ExtCtrls, Buttons;
    
    type
      TFrmMain = class(TForm)
        Panel1: TPanel;
        SpeedButton1: TSpeedButton;
        procedure btnClick(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        procedure LoadPlugin(const formClass: string);
      public
        { Public declarations }
      end;
    
    var
      FrmMain: TFrmMain;
    
    implementation
    
    {$R *.dfm}
    
    procedure TFrmMain.btnClick(Sender: TObject);
    var
      h: Integer;
      formClass, bplFile: string;
    begin
      if SameText(TSpeedButton(Sender).Caption, '系统一') then
      begin
        bplFile := 'bplTest1.bpl';
        formClass := 'TfrmTest1';
      end;
    
      if TSpeedButton(Sender).Tag = 0 then
      begin
        if FileExists(bplFile) then
        begin
          h := LoadPackage(bplFile);
          if h = 0 then
          ShowMessage(bplFile + ' 包加载失败')
        else
        begin
          TSpeedButton(Sender).Tag := h;
        end;
      end
      else
        ShowMessage(bplFile + ' 没有找到');
      end;
    
      LoadPlugin(formClass);
    end;
    
    procedure TFrmMain.FormDestroy(Sender: TObject);
    var
      i: integer;
    begin
      for i := 0 to Panel1.ComponentCount - 1 do
      begin
        if TSpeedButton(Panel1.Components[i]).Tag <> 0 then
          UnloadPackage(TSpeedButton(Panel1.Components[i]).Tag);
      end;
    end;
    
    procedure TFrmMain.LoadPlugin(const formClass: string);
    var
      aForm: TForm;
    begin
      aForm := TFormClass(FindClass(formClass)).Create(Self);
      aForm.Position := poScreenCenter;
      aForm.Show;
    end;
    
    end.
    
    2)RTTI方式,适用于2009以上版本
    unit untMain;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Generics.Collections,
      System.Rtti, Vcl.ExtCtrls, Vcl.Buttons;
    
    type
      TFrmMain = class(TForm)
        Panel1: TPanel;
        SpeedButton1: TSpeedButton;
        procedure FormDestroy(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure btnClick(Sender: TObject);
      private
        { Private declarations }
        bplList: TDictionary<string, Integer>;
        procedure LoadPlugin(const bplFile, unitClass: string);
      public
        { Public declarations }
      end;
    
    var
      FrmMain: TFrmMain;
    
    implementation
    
    {$R *.dfm}
    
    procedure TFrmMain.btnClick(Sender: TObject);
    var
      h: Integer;
      bplFile: string;
      unitClass: string;
    begin
      if SameText(TSpeedButton(Sender).Caption, '系统一') then
      begin
        bplFile := 'bplTest1.bpl';
        unitClass := 'untTest1.TfrmTest1';
      end;
    
      if TSpeedButton(Sender).Tag = 0 then
      begin
        if FileExists(bplFile) then
        begin
          h := LoadPackage(bplFile);
          if h = 0 then
            ShowMessage(bplFile + ' 包加载失败')
          else
          begin
            bplList.Add(bplFile, h);
            TSpeedButton(Sender).Tag := h;
          end;
        end;
      end;
      LoadPlugin(bplFile, unitClass);
    end;
    
    procedure TFrmMain.FormCreate(Sender: TObject);
    begin
      bplList := TDictionary<string, Integer>.Create;
    end;
    
    procedure TFrmMain.FormDestroy(Sender: TObject);
    var
      i: Integer;
    begin
      if Assigned(bplList) then
      begin
        for i in bplList.Values do
          UnloadPackage(i);
        FreeAndNil(bplList);
      end;
    end;
    
    procedure TFrmMain.LoadPlugin(const bplFile, unitClass: string);
    var
      LContext: TRttiContext;
      LPackage: TRttiPackage;
      LClass: TRttiInstanceType;
      aForm: TForm;
    begin
      if (bplFile = '') or (unitClass = '') then
        Exit;
    
      LContext := TRttiContext.Create;
      try
        try
          for LPackage in LContext.GetPackages() do
          begin
            if SameText(ExtractFileName(LPackage.Name), bplFile) then
            begin
              LClass := LPackage.FindType(unitClass) as TRttiInstanceType;
              aForm := LClass.MetaclassType.Create as TForm;
              aForm.Create(nil);
              aForm.WindowState := wsNormal;
              aForm.Position := poScreenCenter;
              aForm.Show;
            end;
          end;
        except
          ShowMessage('单元名和类名是大小写敏感的');
        end;
      finally
        LContext.Free;
      end;
    end;
    
    end.


  • 相关阅读:
    【BZOJ2879】【NOI2012】美食节(费用流)
    HN2018省队集训
    【HDU5421】Victor and String(回文树)
    【BZOJ2878】【NOI2012】迷失游乐园(动态规划)
    【BZOJ5338】[TJOI2018]异或(主席树)
    【BZOJ2432】【NOI2011】兔农(数论,矩阵快速幂)
    【BZOJ2436】【NOI2011】NOI嘉年华(动态规划)
    【BZOJ2437】【NOI2011】兔兔与蛋蛋(博弈论,二分图匹配)
    【BZOJ2109/2535】【NOI2010】航空管制(贪心)
    【BZOJ1565】【NOI2009】植物大战僵尸(网络流)
  • 原文地址:https://www.cnblogs.com/xieyunc/p/9126529.html
Copyright © 2011-2022 走看看