Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Примеры использования Пакетов (Package)


Автор: Admin 29.12.2004, 23:31
Приведу примеры испоьзования Pack-ей. 

Статическое подключение пакетов. 

Создаешь новую форму(размещаешь на ней нужные компоненты и пишешь код), после чего сохраняешь ее например в C:\Borland\Delphi7\Projects\Plugins\.
Создаешь свой пакет(не закрывая созданной формы) - Components>Instal Component. Там выбираешь вкладку Into New Package. Указываешь путь к своей форме и прописываешь название нового пакета(в эту же директорию). В окне созданного пакета открываешь Options>Directories/Conditionals: в Output directory пишешь путь до текущего местонахождения пакета, что бы пакет результирующие файлы сохранялись не в Project\Bpl а в твоем каталоге. Так же указываешь этот путь в DCP Outpu directory (В данном примере C:\Borland\Delphi7\Projects\Plugins). После чего сохраняешь и компилишь пакет. Инсталить его нет необходимости. Закрываешь окно с твоим пакетом. Создаешь новый проект в этом же каталоге и в его uses добавляешь название юнита твоей формы в этом пакете, т.е. если ты не изменил его названи это Unit1, тогда код будет выглядеть примерно так:

Код
unit TestUnit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Unit1{Добавленный юнит из пакета};

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
//Твоя форма в пакете
PackForm:TForm1;
begin
  PackForm:= TForm1.Create(Self);
  try
    PackForm.ShowModal;
  finally
    FreeAndNil(PackForm);
  end;
end;

end.


В действительности код формы в пакете будет включен в результирующий exe файл, для того чтобы этого не было необходимо использовать пакеты времени исполнения и свой пакет включить к списку пакетов времени исполнения(смотри Project>Options>Packages Runtime packages тут установи галочку Build with runtime packages, если в списке пакетов нету твоего пакета, то добавь его кнопкой Add).

Загрузка пакетов во время исполнения программы 

Наиболее интересный на мой взгляд способ, но тут я стокнулся с одной проблемой, которую уже как 2 часа не могу решить(может кто поимет в чем дело).
Открываешь созданный тобою уже пакет и добавляешь такой код.

Код
initialization
  RegisterClass(TForm1){или твое название формы}


Данный код нужен для того чтобы получить доступ к этому классу функцией GetClass.
Сохраняешь свой пакет и компилишь его.

Создаешь тестирующее приложение:
Код
unit ULoaderPlugin;

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, Buttons, TypInfo;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
PackForm:TForm;
FormClass:TFormClass;
hPack:HMODULE;
begin
  hPack:= LoadPackage(ExtractFilePath(ParamStr(0))+'PluginPack.bpl');
  if hPack > 0 then
  begin
    FormClass:= TFormClass(GetClass('TPackForm'));
    if Assigned(FormClass) then
    begin
      PackForm:= FormClass.Create(Self);
      try
        PackForm.ShowModal;
      finally
        FreeAndNil(PackForm);
      end;   
    end
    else
      Showmessage('Class not found');
    UnLoadPackage(hPack);
  end
  else
    ShowMessage('Error load package');
end;

end.


Если тебе нужно получить доступ к полям свойствам твоей формы(не стандартным), то этого можно добиться при помощи SetPropValue  (необходимо подключить модуль TypInfo), например:

Код
//Устанавливаешь значения свойств
SetPropValue(PackForm, 'Caption', 'New Caption');
//Получаешь значения свойств
GetPropValue(PackForm, 'Caption');


Но эти свойства должны быть обязательно обьявлены в секции published.

Проблема, о которой я уже писал, заключается в том, что когда я вызываю GetClass он всегда возвращает nil. Хотя похожий пример из книги "Delphi 6" Марко Кенту работает нормально. Может у кого есть идей на этот счет?

Таким образом, если разобраться с этой проблемой, то можно написать класс для юзания плагинов, например в своей программе можно отвести соответствующую директорию и при каждом запуске проги получать из нее все все файлы и загружать их. Чем я и займусь, если эта проблема решится.

Если тебе нужно разместить в пакете кнопку с реакцией на нажатие, то можно, например, сделать так:
Создаешь наследника от нужного тебе компонента(в данном случае от TButton), причем он должен быть в свою очередь наследником TPersistent, если ты будешь подключать пакет динамически, для генерироавния соответствующей RTTI инфы. Вот пример для TButton:

Код
unit UMyButton;

interface
  uses StdCtrls, Dialogs;

type
  TMyButton = class(TButton)
     public
       procedure Click; override;
   end;

implementation

{ TMyButton }

procedure TMyButton.Click;
begin
  inherited;
  ShowMessage('Hello from my click');
end;

end.

 Запихиваешь кнопку в пакет приведенным выше способом.

Твоя прога(Подключение с помощью LoadPackage пока не могу показать, так как не разобрался почему GetClass возвращает nil):

Код
unit UMyButtonTest;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, UMyButton;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
 Button:TMyButton;
begin
  Button:=TMyButton.Create(Self);
  try
    Button.Parent:=Self;
    Button.Left:=10;
    Button.Top:=10;
    Button.Caption:='MyButton';
  except
    FreeAndNil(Button);
  end;
end;

end.

Файл UMyButton.pas можешь удалть из этого каталога, чтобы увидеть что исползуется юнит в bpl.

Ну вот пока и все. Надеюсь кто нить знает причину моей ошибки при динамическом подключении, так как мне самому это интересно.

Автор: <Spawn>

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)