Переопределяющий конструктор создания компонента в отдельном пакете времени разработки - PullRequest
3 голосов
/ 10 февраля 2012

Среда программирования: Delphi 6 и выше

Мне известно о том факте, что начиная с Delphi 6, пользовательские компоненты должны иметь отдельный пакет для разработки и выполнения.Поэтому все функции времени выполнения компонента должны быть в отдельном модуле и упакованы отдельно в пакет времени разработки компонента.

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

Однако в отдельном модуле времени разработки, как мне сослаться и добавить время разработкикод, который должен быть включен в конструктор create компонента во время разработки, когда компонент помещается в форму?

Ответы [ 4 ]

4 голосов
/ 10 февраля 2012

Вы можете отделить поведение времени проектирования от поведения времени выполнения с помощью

if [not] (csDesigning in ComponentState) then

Но если вашему коду конструктора нужен пакет времени разработки DesignIDE, например из юнитов DesignEditors, DesignIntf и т. д ..., тогда я думаю, что вы застряли. Может быть, какое-то участие IOTA может помочь. Но поскольку кажется, что не существует интерфейса уведомлений для создания компонентов, для этого потребуется пользовательский IOTAFormEditor. Не так просто, если не невозможно.

2 голосов
/ 10 февраля 2012

Почему бы не использовать обратные вызовы?

Из вашего кода инициализации пакета designtime сделайте это:

unit MyDsgnUnit;

interface

  //TMyHook defined in AnImplUnit

  TMyDesignHandlerObject = class
      procedure MyMethod(Sender:TObject;ParentForm:TObject); { must match TMyHook }
  end;

implementation

uses AnImplUnit, DesignUnitNamesHere;

procedure TMyDesignHandlerObject.MyMethod(Sender:TObject);
var
  newObject:TMyComponent;
begin
   newObject := TMyComponent(Sender);
   DoSomethingThatneedsDesigntimeStuff(newObject);
end;

finalization
   ADesignHandlerObject.Free;
initialization
   ADesignHandlerObject := TMyDesignHandlerObject.Create;
   AnImplUnit.AfterConstructionHook := TDesignHandlerObject.MyMethod;

и в вашем компоненте сделайте что-то вроде этого:

unit AnImplUnit;
interface

type
   TMyHook = procedure(Sender:TObject;ParentForm:TObject) of object;
var

  AfterConstructionHook:TMyHook;

implementation

...

procedure TMyComponent.Create(AOwner:TComponent);
begin
   inherited Create(AOwner);
   DOMyStuff;
   if Assigned(AfterConstructionHook)
       AfterConstructionHook(Sender,Parent);
end;

Обновление Более подробный пример. Нет причин, по которым вы не можете добавить больше параметров в AfterConstructionHook, но поскольку ваша ссылка на Sender уже имеет тип TMyComponent, я не вижу смысла, когда вы можете получить доступ ко всему общедоступному или защищенному, в TMyComponent(Sender) изнутри ваша функция ловушки, и если вы наследуете локально (известный как класс защищенного доступа), вы также можете получить доступ к защищенному материалу.

2 голосов
/ 10 февраля 2012

Убедитесь, что ваш DPK определяет символ по вашему выбору, например DESIGNTIME. Тогда вы сможете использовать что-то подобное, чтобы включать единицы времени разработки только при необходимости:

uses Windows, Whatever, Something
  {$IFDEF DESIGNTIME}
  ,DesignIntf
  {$ENDIF}
  ;

Тогда к тому же в вашем конструкторе код:

constructor TMyClass.Create(aOwner:TComponent);override;
begin
  inherited;
  {$IFDEF DESIGNTIME}
  // I'm at design time.
  {$ENDIF}
end;

При использовании этого метода вы должны либо использовать отдельный каталог DCU для вашего pacakge и вашего обычного исполняемого файла, либо делать build каждый раз, когда вы переключаетесь с пакета времени разработки на другие проекты. Это потому, что Delphi будет перестраивать DCU, только если PAS изменился, тогда как в этом случае PAS не рассказывает всей истории, определенные символы также имеют значение. Если у вас есть DCU на диске, который был скомпилирован Delphi, когда вы строили свой проектный проект, вы можете увидеть ToolsApi.DCU not found при попытке скомпилировать обычный проект. Перестройка перекомпилирует DCU и заставляет сообщение исчезнуть. Точно так же, если вы перекомпилируете (а не пересобираете) проект во время разработки после того, как вы построили обычный проект, ваш DCU может застрять в состоянии, отличном от DESIGNTIME, оставив вас без особого поведения во время разработки.

0 голосов
/ 10 февраля 2012

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

procedure TNewEdit.Loaded;
begin
  inherited;
  if (csDesigning in ComponentState) then
    ShowMessage('Designing')
  else
    ShowMessage('Running');
end;

Однако, даже не зная, что вы пытаетесь сделать, есть несколько открытых дверей ... например, если вы хотите изменить значение свойства во время разработки и другое значение во время выполнения,тогда есть проблемы потоковой передачи, с которыми вам приходится иметь дело.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...