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.


  • 相关阅读:
    优化网站设计(十七):延迟或按需加载内容
    优化网站设计(七):避免在CSS中使用表达式
    SharePoint Server 2013发现之旅系列文章的概述和相关资源
    优化网站设计(十六):为AJAX请求使用GET方法
    优化网站设计(二十):使用多个主机来平衡负载
    优化网站设计(六):在文档底部放置脚本定义或引用
    优化网站设计(十八):预加载内容
    优化网站设计(二十八):避免使用Filters(滤镜)
    优化网站设计(三十五):避免将img的src属性设置为空白
    优化网站设计(三十四):将组件直接打包到页面
  • 原文地址:https://www.cnblogs.com/xieyunc/p/9126529.html
Copyright © 2011-2022 走看看