Възможно ли е да се включват файлове (свързване) въз основа на свойство на компонент?

Delphi 2007/2009 странен въпрос тук:

Възможно ли е, въз основа на свойство на компонент, дефинирано по време на проектиране, да включите файлове в свързването или да ги оставите?

Пример: Ако оставя SomeProperty true, при компилиране единицата SomeUnit ще бъде включена в моя проект. В противен случай няма да бъде включен.

Вторият ми подход към този проблем е да разположа втори компонент, който, когато бъде пуснат във формуляра (или не), ще включва единицата в клаузата за използване. Но ако може да се направи с имот, ще е по-добре.

Искам да избегна условната компилация чрез IFDEF, защото това принуждава компонентът да се изгражда всеки път, когато проектите се изграждат. Или не?

Опитвам се да постигна лесен начин за включване на някои единици в проекта и след това тези единици ще осигурят поддръжка за конкретни бази данни. Поставянето им в опция в компонента за свързване ще бъде идеално лесно: Проверете поддръжката и това е готово. Премахнете отметката и вземете малко по-малко KB във вашето компилирано ПРИЛОЖЕНИЕ.

редактиране: Ще остана с компонентния начин например. Знаех метода IFDEF и нещата, но това принуждава компонентът да се изгражда всеки път, когато проектите се изграждат. Или не?

Опитвах се да постигна лесен начин за включване на някои единици в проекта и след това тези единици ще предоставят поддръжка за конкретни бази данни. Поставянето им в опция в компонента за свързване ще бъде идеално лесно: Проверете поддръжката и това е готово. Премахнете отметката и вземете малко по-малко KB във вашето компилирано ПРИЛОЖЕНИЕ.


person Gustavo Ciello    schedule 13.01.2009    source източник


Отговори (6)


No.

Какво се опитваш да решиш?

Бихте могли да добавите стъпка за посткомпилиране, която по избор ще включва някакъв ресурс, базиран на свойство на компонент - но ще трябва да направите малко кодиране, за да приложите такава функция.

person gabr    schedule 13.01.2009

Можете да използвате метода с незадължителен код {$IFDEF youridentifier} {$ENDIF} за условно компилиране на данни във вашето приложение и след това, за да го активирате, просто отидете в опциите на вашия проект и въведете вашия идентификатор в съответното поле за опция. Друг метод за това е да добавите следното в горната част на вашето устройство (или във включен файл):

{$DEFINE youridentifier}

което ще принуди вашия идентификатор да бъде включен. За да деактивирате, просто поставете точка точно преди $:

{.$DEFINE youridentifier}

С помощта на тези техники е лесно да се въведе условно код или да се замени код с всяко компилиране.

person skamradt    schedule 13.01.2009
comment
+1, това изглежда като най-добрият начин за условно включване на файлове. Той има допълнителното предимство, че може да се използва за компилации от командния ред / автоматични компилации. - person mghie; 14.01.2009

Напишете IDE добавка. Обработете известието „преди компилиране“ и проверете дали някакви формуляри или модули с данни в проекта имат компоненти от типа, който ви интересува, и след това проверете техните свойства. Въз основа на това, което намерите там, можете да опитате да промените съдържанието на единица, за да използвате другата единица по ваш избор. Със сигурност не звучи лесно, но изглежда възможно.

Втората ти идея е много лесна. Точно това прави компонентът TXPManifest например. Имайте предвид, че премахването на такъв компонент от формуляр не "преустановява използването" на свързаната единица.

За да добавите условно поддръжка за различни бази данни, можете да обмислите използването на пакети за изпълнение. (В края на краищата IDE успява да поддържа толкова много различни видове компоненти.) Поставете потребителския код на всяка база данни в различен пакет. След това базите данни, които поддържате, са просто тези, които имат налични пакети по време на изпълнение. Не е необходима конфигурация по време на компилиране или по време на проектиране. Пречката за това обаче е да управлявате кои пакети са налични и да определяте кои от тях са пакетите, които осигуряват поддръжка на базата данни.

person Rob Kennedy    schedule 13.01.2009

Вашият втори подход не е задължително да работи както искате. Въпреки че Delphi услужливо ще добави необходимата единица към вашия списък с употреби, когато пуснете компонента във формуляра, той няма да премахне единицата, когато изтриете компонента. И дори ако не използвате компонента или друг експортиран обект от този модул, е възможно модулът така или иначе да бъде свързан с вашето приложение, когато има код в инициализация или финализиранена част на блока. Това за съжаление е много често случаят, дори когато би било възможно да се инициализират неща при поискване.

person mghie    schedule 14.01.2009

Няма начин да направите това, което искате, но нещо, което може да не сте наясно е, че единиците, които са включени в списъка ви с употреби, но никога не са посочени, ще имат минимално въздействие върху размера на вашия изпълним файл. Интелигентният линкер, който е в Delphi, върши много добра работа за премахване на код, който никога не се използва. Ако внимавате за вашата „незадължителна единица“, към която се препраща компонентът, и нямате никакъв код в нея, който да се изпълнява глобално (всичко е самостоятелно включено в клас или класове), тогава не би трябвало да има значение дали е в клаузата за употреби и не се използва или изобщо не е в клаузата за употреби.

Това лесно би ви позволило да направите това, което според мен искате да направите, което би било да пуснете компонент във формуляр, който включва единица, която след това може да бъде свързана с вашето приложение. Премахването на компонента ще доведе до липса на свързване в устройството. Вярвам обаче, че всички ресурси (например формуляри или други елементи, включени от директивата $R), които са в използваната единица, пак ще бъдат включени в изпълнимия файл.

person skamradt    schedule 16.01.2009

Можете да използвате DesignIntf.RegisterSelectionEditor, за да регистрирате редактор за избор (вижте коментарите в изходния код на Delphi относно ISelectionEditor), след което да използвате процедурата RequiresUnits, за да включите допълнителни единици в клаузата uses.

TMySelectionEditor = class(TSelectionEditor)
public
  procedure RequiresUnits(Proc: TGetStrProc); override;
end;

procedure Register;

implementation

procedure TMySelectionEditor.RequiresUnits(Proc: TGetStrProc);
var
  comp: TMyComponent;
  I: Integer;
begin
  inherited RequiresUnits(Proc);
  Proc('ExtraUnit');  
  // might be a better way of doing the code from here onwards?
  if (Designer=nil)or(Designer.Root=nil) then Exit;

  for I := 0 to Designer.Root.ComponentCount - 1 do
  begin
      if (Designer.Root.Components[i] is TMyComponent) then
      begin
        comp := TMyComponent(Designer.Root.Components[i]);
        if comp.SampleProperty = True then
            Proc('ExtraUnit2');
        Proc(comp.ObjProperty.UnitName);
      end;
  end;
end;

procedure Register;
begin
  RegisterSelectionEditor(TMyComponent, TMySelectionEditor);
end;
person Dan Bartlett    schedule 10.07.2010
comment
Наистина трябва да има по-лесен начин от този, лесно е да се добави единица на TComponent към клаузата uses, но щом това е TPersistent, създаден динамично по време на проектиране, или тип в събитие, което не съществува в нито един от единици в класа на компонента, тогава добавянето става много по-трудно. - person Dan Bartlett; 10.07.2010
comment
Кога ще бъде извикан редакторът за избор - само когато разработчикът пусне нов компонент във формуляра? В този случай SampleProperty все още ще има стойността по подразбиране и промяна на различна стойност няма да има ефект. - person mjn; 10.07.2010
comment
Не, изглежда се извиква само когато компилирате (веднъж на компонент), така че ще зависи от стойността на свойството в този момент. Изглежда, че няма начин да се препрати към компонента, който се обработва, така че този код преминава през всички компоненти, поставени във формуляра (може да се наложи да промените, за да позволите подсвойства) - person Dan Bartlett; 10.07.2010