[Delphi] VCL/CLX Component dual install in packages list

Pagina: 1
Acties:

  • CyeZ
  • Registratie: September 2001
  • Laatst online: 23-08 22:06

CyeZ

Vroem vroem!!!

Topicstarter
Ik ben bezig als klein onderdeeltje voor mijn afstudeer stage met een component wat directories scant op veranderingen. Niet zo bijzonder, en dat deel was dan ook vrij snel klaar.

Echter, het component moet zowel voor de VCL als voor de CLX bruikbaar zijn. Normaal geen probleem, zolang je geen dingen gebruikt die specifiek voor 1 van die twee libraries is geimplementeerd. En dat is dus wel het geval.

Ik maak intern in het component gebruik van een TTimer object, die elke seconde een functie in mijn component aanroept. Dat werkt prima. Het probleem is echter dat TTimer voor de VCL in ExtCtrls zit en voor de CLX in QExtCtrls, dus in beide gevallen heb ik een andere uses clause nodig. Ik kan dit niet compile time bepalen door te kijken of het platform MSWINDOWS of LINUX is, aangezien onder windows ook gewoon van de CLX versie gebruik gemaakt moet kunnen worden.

Om dit op te lossen was mijn idee om 2 packages te maken, 1 voor de VCL en 1 voor de CLX. Hierbij zou Delphi dan zelf wel zorgen dat de juist versie op het componenten tabblad verschijnt.

Om dit een beetje fatsoenlijk voor elkaar te krijgen heb ik dus een 3 tal files aangemaakt, op de onderstaande manier:

VCL:
Delphi:
1
2
3
4
5
6
7
8
unit untDirectoryMonitor;

interface

uses 
  Classes, ExtCtrls;

{$INCLUDE 'untDirectoryMonitorShared.pas'}


CLX:
Delphi:
1
2
3
4
5
6
7
8
unit untQDirectoryMonitor;

interface

uses 
  Classes, QExtCtrls;

{$INCLUDE 'untDirectoryMonitorShared.pas'}


Globaal:
Delphi:
1
2
3
4
type
  TDirectoryMonitor = class(TComponent)
    ...
  end;


Hierbij zijn de VCL en de CLX unit dus beide opgenomen in een aparte package.
Ik kan beide packages ook prima compileren, en dan werken ze ook.
Het probleem komt echter wanneer ik beide packages wil installeren, dus gaat dus niet. Bij de 2e package die ik wil installen klaagt delphi dat er al een component met dezelfde naam aanwezig is. Opzich logisch, maar in dit geval wil ik dat dus juist wel voor elkaar krijgen omdat het om 2 verschillende versies gaat, elk afhankelijk van een andere library.

Ik ben al flink aan het zoeken geweest naar een oplossing hiervoor, o.a. in de sources van bijvoorbeeld die TTimer zelf maar daar kan ik dus nergens een Register functie van vinden. Dus ik vermoed dat ze voor de eigen grafische componenten een andere methode gebruiken om de component te registreren op het Componenten tabblad.

Iemand die enig idee heeft hoe ik dit het beste kan aanpakken of me in ieder geval de juiste richting op kan sturen?

Het gaat hier overigens om Delphi 6 waar ik gebruik van maak.

[ Voor 2% gewijzigd door CyeZ op 04-03-2003 19:43 . Reden: toevoeging delphi versie ]

[18:54] <Prammenhanger> |HunterPro|eet
[18:55] <Prammenhanger> lijkt best op
[18:55] <Prammenhanger> |HunterProFeet


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Namen van componenten, unit's, en packages moeten uniek zijn voor componenten die designtime geladen worden, dus vandaar dat je een fout krijgt. Zoals je zelf al zegt zijn er voorbeelden van componenten, zoals TTimer, waarbij beide versies (VCL/CLX) dezelfde naam hebben. Dit probleem doet zich overgens alleen voor bij niet visuele componenten. Het zou dus moeten kunnen. Na even kort zoeken vond ik een oplossing.

Alle niet visuele componenten zijn beschikbaar in zowel VCL als CLX, dit omdat ze bijna altijd zonder problemen in VCL en CLX gebruikt worden. Soms komt het voor dat er specifieke VCL en of CLX implementaties in de componenten zitten zodat het toch nodig is te vertellen of het component bij VCL of bij CLX hoort.

TControl is een visueel component en de Delphi Designer weet daarvan of het een CLX TControl of een VCL TControl is. Door je component te assosieeren met de juiste versie van TControl weet de designer bij welke groep ie hoort. Dus het werkt als een soort namespace.

De volgende code zorgt hiervoor:
Delphi:
1
2
3
4
initialization
  StartClassGroup(TControl);
  ActivateClassGroup(TControl);
  GroupDescendentsWith(TDirectoryMonitor, TControl);

We adore chaos because we like to restore order - M.C. Escher


  • CyeZ
  • Registratie: September 2001
  • Laatst online: 23-08 22:06

CyeZ

Vroem vroem!!!

Topicstarter
Heel erg bedankt LordLarry, ik heb het net kunnen uitproberen en het werkt verbazend simpel. :)

Voor de volledigheid, hier is de CLX variant van m'n register unit (de VCL variant is gelijk op de unitnaam en de uses clause na):
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
unit untQServerRegister;

interface

const
  csDIRECTORY_MONITOR_IDE_TAB = 'Server';

procedure Register;

implementation

uses
  Classes,
  QControls,
  untQDirectoryMonitor;

procedure Register;
begin
  RegisterComponents(csDIRECTORY_MONITOR_IDE_TAB,[TDirectoryMonitor]);
end;

initialization
  StartClassGroup(TControl);
  ActivateClassGroup(TControl);
  GroupDescendentsWith(TDirectoryMonitor, TControl);
end.


De register functie is dus nog wel nodig, in combinatie met het stukje initialization werkt het perfect voor zowel VCL als CLX gelijktijdig :)

[18:54] <Prammenhanger> |HunterPro|eet
[18:55] <Prammenhanger> lijkt best op
[18:55] <Prammenhanger> |HunterProFeet


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23-08 22:26

Tomatoman

Fulltime prutser

Waarom gebruik je geen conditional defines? Iets in de trant van
Delphi:
1
2
3
4
5
6
7
uses 
  Classes,
{$IFDEF VCL}
  ExtCtrls;
{$ELSE}
  QExtCtrls;
{$ENDIF}
Ik weet niet precies of de bewuste define VCL heet (ik heb hier geen Delphi 7), maar je kunt dat vast wel achterhalen via Delphi Help of misschien wel via de {$IFDEF} constructies in bijvoorbeeld SysUtils.

Een goede grap mag vrienden kosten.


  • CyeZ
  • Registratie: September 2001
  • Laatst online: 23-08 22:06

CyeZ

Vroem vroem!!!

Topicstarter
Nou heel simpel waarom ik die niet gebruik: het kan niet.
Op het moment dat ik de package waar ik het component in heb zitten compileer, heeft delphi nog geen enkele mogelijkheid om te weten welke library de hoofdapplicatie uiteindelijk zal gaan gebruiken aangezien de runtime package dan al aanwezig moet zijn.

Bovendien moet het component via een Runtime package voor zowel VCL als CLX beschikbaar moet zijn, dus ik moet wel een aparte package voor VCL en CLX maken om dit op te kunnen lossen.

[18:54] <Prammenhanger> |HunterPro|eet
[18:55] <Prammenhanger> lijkt best op
[18:55] <Prammenhanger> |HunterProFeet


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23-08 22:26

Tomatoman

Fulltime prutser

OK, weer wat geleerd :).

* Tomatoman is nogal conservatief en bouwt alleen VCL apps.

Een goede grap mag vrienden kosten.


Verwijderd

waarom zou in eigenlijk VCL/CLX component in de zelfde package doen :S

Veroorzaakt alleen maar problemen :(

[ Voor 23% gewijzigd door Verwijderd op 05-03-2003 17:09 ]


  • CyeZ
  • Registratie: September 2001
  • Laatst online: 23-08 22:06

CyeZ

Vroem vroem!!!

Topicstarter
tomatoman schreef op 05 maart 2003 @ 17:07:
OK, weer wat geleerd :).

* Tomatoman is nogal conservatief en bouwt alleen VCL apps.
Ja, ik normaal ook maar voor de huidige opdracht is een van de eisen om het geheel voor beide platformen aan het draaien te krijgen. En dan kom je dit soort dingen dus wel tegen. :) Is wel wennen trouwens, er zijn toch nog vrij veel verschillen tussen de VCL en de CLX als je er echt mee bezig gaat.
Verwijderd schreef op 05 March 2003 @ 17:09:
waarom zou in eigenlijk VCL/CLX component in de zelfde package doen :S

Veroorzaakt alleen maar problemen :(
Daarom zitten ze ook in 2 verschillende packages :)
Alleen heeft het component wel in beide packages dezelfde naam, dat veroorzaakt dus problemen als je die packages in de IDE wilt installen. Dit is dus te voorkomen door de oplossing die LordLarry hierboven heeft gegeven.

[ Voor 35% gewijzigd door CyeZ op 05-03-2003 18:48 ]

[18:54] <Prammenhanger> |HunterPro|eet
[18:55] <Prammenhanger> lijkt best op
[18:55] <Prammenhanger> |HunterProFeet

Pagina: 1