Ajout d' une unité dans les "Uses" lorsque le programmeur ajoute du code dans l'

Résolu
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 - 19 nov. 2009 à 14:50
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 - 24 nov. 2009 à 12:09
Bonjour à tous,

merci de m' aider sur ce point:
j' aimerai automatiquement ajouter une unité dans les "Uses" lorsque le programmeur ajoute du code dans l' événement de mon compo: c' est à dire lorqu' il double clique sur l' événement de mon compo ...

Merci d' avance,
Mauricio

15 réponses

Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
19 nov. 2009 à 18:39
Salut,

je pense que cette page est une bonne piste .. y a pas de solution directe mais tu devrais y trouver les bonnes clefs.


[hr]@+Cirec
[hr]
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
20 nov. 2009 à 14:22
[quote=Mauricio]C' est très interessant mais malheureusement je n' ai pas trouvé mon bonheur ...
[quote=Cirec]y a pas de solution directe mais tu devrais y trouver les bonnes clefs./quote/quote

peut importe le scénario. Si tu veux, par code, pouvoir ajouter/modifier le code source directement dans l'IDE, il te faut passer par les IOTA ... c'est même la seule solution.

Tous les outils y sont .. mais c'est à toi d'écrire le code (il n'y a rien de fait "prévu" pour ton problème)

Bonne courage
[hr]@+Cirec
[hr]
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
20 nov. 2009 à 23:20
Bonsoir

Je ne sais pas si je poste trop tard mais tant pis. Voilà un exemple trivial juste écrit pour te montrer la voie.

unit AddUnitComponent;

interface

uses
  SysUtils, Classes, Controls;

type
  TAddUnitComponent = class(TControl)
  public
    constructor Create(AOwner: TComponent); override ;
  end;

procedure Register;

implementation

uses ToolsAPI ;

procedure Register;
begin
  RegisterComponents('WhiteHippo', [TAddUnitComponent]);
end;

{ TAddUnitComponent }

constructor TAddUnitComponent.Create(AOwner: TComponent);
const
  BUFFER_SIZE = 4096 ;
var
  ModuleServices: IOTAModuleServices;
  Module: IOTAModule;
  Editor: IOTAEditor;
  SourceEditor: IOTASourceEditor;
  Reader: IOTAEditReader ;
  Writer: IOTAEditWriter ;
  Buffer:Array[0..BUFFER_SIZE-1] of char ;
  i : integer ;
begin
  inherited ;
  ModuleServices := BorlandIDEServices as IOTAModuleServices;
  for i:=0 to ModuleServices.ModuleCount-1 do
  begin
    Module := ModuleServices.Modules[i] ;
    if Assigned(Module) then
    begin
      Editor := Module.ModuleFileEditors[i];
      if Assigned(Editor) then
      begin
        if Editor.QueryInterface(IOTASourceEditor, SourceEditor)=S_OK then break ;
      end ;
    end ;
  end ;
  // Récupération du fichier
  Reader := SourceEditor.CreateReader ;
  if Assigned(Reader) then
  begin
    FillChar( Buffer, BUFFER_SIZE, 0 ) ;
    Reader.GetText(0, @Buffer, BUFFER_SIZE );
  end ;

  Writer := SourceEditor.CreateWriter ;
  if Assigned(Writer) then
  begin
    Writer.Insert( '// Insertion d''un commentaire'#13#10 );
    Writer.CopyTo(0); //Au début de l'unité
  end ;
end;

end.


P.S. Bien sur, dans ton cas il faudra faire un parser pour retrouver la clause "uses" ( aux Maj/Min du genre "UseS" ), rechercher le premier point virgule suivant. Puis analyser les unités à l'intérieur pour voir si ton unité n'est pas déjà présente. L'insertion la plus simple serait de l'ajouter à la position du point virgule précedemment trouvée.

Cordialement.
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
19 nov. 2009 à 18:47
Merci Cirec.

C' est très interessant mais malheureusement je n' ai pas trouvé mon bonheur ...

Maurício

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
19 nov. 2009 à 19:50
Salut Mauricio,

Sincèrement je pense que cela va être difficile car cela revient à interagir directement au niveau de l'IDE.

Puis je pense à un problème : Si la solution existe, elle ne pourra exister quand designtime. En runtime c'est voué à l'échec.

Pourrais tu nous dire ce que tu souhaites faire concrètement ? Peut être qu'une autre alternative existe .
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 33
19 nov. 2009 à 21:10
Mauricio est bien mystérieux...

"c' est à dire lorsqu'il double clique sur l' événement de mon compo ..."
S'il double clique, c'est donc un composant visuel et, dans ce cas, Delphi ajoute automatiquement l'unité appropriée dans la clause Uses de l'interface de l'unité.
Comme Francky l'a écrit, pourrais-tu nous en dire plus ?
A+

8000 Lévriers 'galgos' par an sont torturés et massacrés en Espagne
May Delphi be with you

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
20 nov. 2009 à 10:02
Bonjour à tous,

je me cite: "double clique sur l' événement de mon compo ... "

je pensais que c' était clair mais je vais vous expliquer avec mon cas précis:
1. Je mets mon compo TcyIniForm sur une Form.
2. Je vais dans ses events, et je rajoute le code suivant dans l' événement CustomLoadFromFile:

procedure TFrmPrint.cyIniForm1CustomLoadFromFile(Sender: TObject;
IniFile: TIniFile);
begin
Caption := IniFile.ReadString('DEFINFITIONS', 'TITRE', 'Valeur par défaut');
end;

Si je compile, Delphi me dit qu' il ne connait pas "Inifile"!
Ce que je voudrais faire donc, c' est lorsque l' on ouvre l' événement cyIniForm1CustomLoadFromFile, l' IDE ajoute automatiquement dans les Uses l' unité "Inifiles" ...

Merci d' avance!
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
20 nov. 2009 à 14:36
Merci Cirec,

je vais reessayer sur cette voie ...

A+
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
21 nov. 2009 à 10:24
Bonjour

J'ai oublié de préciser, testé sous Delphi 7 Pro. A adapter pour les autres versions.

Cordialement.
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
23 nov. 2009 à 17:45
Salut à tous!

D' abord, je tiens à remercier tous les intervenants de ce thread.
Je tiens à remercier plus particulièrement WhiteIppo car c' est son post qui m' a le plus aider.
Voici la solution que j' ai développé basé sur le code de WhiteIppo et que j' ai mis dans l' unité de mon compo (cyIniForm.pas):

procedure TcyIniForm.AddIniFilesUnitToUses;



function GetSourceEditor: IOTASourceEditor;
var
ModuleServices: IOTAModuleServices;
Module: IOTAModule;
Editor: IOTAEditor;
i: Integer;
begin
RESULT := Nil;
ModuleServices := BorlandIDEServices as IOTAModuleServices;
for i := 0 to ModuleServices.ModuleCount-1 do
begin
Module := ModuleServices.Modules[i];
if Assigned(Module)
then begin
Editor := Module.ModuleFileEditors[i];
if Assigned(Editor)
then
if Editor.QueryInterface(IOTASourceEditor, RESULT) = S_OK
then Break;
end;
end;
end;

const
BufferSize = 254; // Number of chars for Buffer ...
var
SourceEditor: IOTASourceEditor;
Reader: IOTAEditReader;
Writer: IOTAEditWriter;
Buffer: AnsiString;
Position, ReadedChars, UsesPos: Integer;
UsesStr: AnsiString;
SourceCode: String;
begin
SourceEditor := GetSourceEditor;

if SourceEditor = Nil
then EXIT;

SourceCode := '';
Reader := SourceEditor.CreateReader;

// Retrieve code source :
if Assigned(Reader)
then begin
Position := 0;
SetLength(Buffer, BufferSize);

repeat
ReadedChars := Reader.GetText(Position, PAnsiChar(Buffer), BufferSize);
Inc(Position, ReadedChars);
SourceCode := SourceCode + Copy(Buffer, 1, ReadedChars);
until ReadedChars < BufferSize;
end;

// Write into code source :
if SourceCode <> ''
then Writer := SourceEditor.CreateWriter
else Writer := Nil;

if Assigned(Writer)
then begin
UsesPos := Pos('USES', Uppercase(SourceCode));

if UsesPos <> 0
then begin
UsesStr := '';
Position := UsesPos;
while SourceCode[Position] <> ';' do
begin
UsesStr := UsesStr + SourceCode[Position];
Inc(Position, 1);
end;
end;

if Pos('INIFILES', UpperCase(UsesStr)) = 0
then begin
Writer.CopyTo(UsesPos + Length(UsesStr) - 1);
Writer.Insert(', Inifiles');
end;
end;
end;

Ça marche très bien en tout cas : l' unité Inifiles est bien ajoutée en Design-time!
Par contre, je n' arrive plus à compiler mon projet: il me donne l' erreur suivante: "file not found: ToolsAPI.dcu" tout en pointant sur l' unité cyIniForm.pas qui est l' unité de mon compo ...
Avez-vous une idée pour que ça compile à nouveau?

A+
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
23 nov. 2009 à 17:46
Je résume: mon pack de compo compile mais plus mes projets qui utilisent le compo TcyIniform ...

Merci de votre aide!
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
23 nov. 2009 à 18:05
Testé sous Delphi 2009 seulement pour l' instant ...

PS pour WhiteIppo:
L' ordre correct est CopyTo puis Insert:
Writer.CopyTo(UsesPos + Length(UsesStr) - 1);
Writer.Insert(', Inifiles');

PS pour Cirec:
Tu avais raison, il fallait passer par les OTA que je ne conaissais pas du tout il y a une semaine!

Entre nous, dommage qu' en même qu' il n' y ai pas de fonctions qui simplifient la manipulation genre :
IOTAEditWriter.AddItem(Object: TObject; SourceElement: TSourceElement; Identifier: String; Item: String);

IOTAEditWriter.AddItem(Nil, ceUses0, 'Inifiles', 'Inifiles');
IOTAEditWriter.RemoveItem(Nil, ceUses0, 'Inifiles');
IOTAEditWriter.AddItem(Nil, ceUses1, 'unit1', 'unit1');
IOTAEditWriter.RemoveItem(Nil, ceUses1, 'unit1');
IOTAEditWriter.AddItem(Nil, ceConst0, 'x', 'x = 3');
IOTAEditWriter.RemoveItem(Nil, ceConst0, 'x');
IOTAEditWriter.AddItem(TForm1, cePublicVar, 'y', 'y: String');
IOTAEditWriter.RemoveItem(TForm, cePublicVar, 'y');
IOTAEditWriter.AddItem(TForm1, cePrivate, 'FFAutoSave', 'FFAutoSave: Boolean');
IOTAEditWriter.RemoveItem(TForm1, cePrivate, 'FFAutoSave');

A+
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
23 nov. 2009 à 18:58
Il me semble que la solution serait de créer un design time package que je déclarerai dans les requires de mon pack ...

Avez vous une idée?
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
23 nov. 2009 à 21:13
Bonsoir

Désolé pour la réponse tardive. Je suis super occupé en ce moment.
Pourquoi l'ajout de l'unité "ToolsAPI" conduit à l'erreur du compilateur "Fichier non trouvé: ToolsAPI.dcu"?
Faut juste comprendre que cette unité est incluse dans "designide.bpl" qui fait partie intégrale de Delphi. Il faut donc ajouter "DesignIDE" pour la liste des paquets nécessaires à ton paquet.
N.B. Penser également à cocher "Construire avec les paquets d'execution" et avoir au minimum : vcl;rtl;vclx;designide

Va voir ici : http://edn.embarcadero.com/en/print/39007

Cordialement.
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
24 nov. 2009 à 12:09
Bonjour WhiteHippo et merci de ta réponse.

J' avais déjà ajouté "DesignIDE" dans mes requires.
Malheureusement, l' erreur survient, sauf si pour mon projet (qui utilise mon compo, pas mon pack de compo car de toute façon le checkbox est disabled) je précise "Construire avec les paquets d'execution" mais je ne peux obliger mes utilisateurs de compos à compiler leurs projets en Run-time package.

Je pense que la solution est de créer un design-time package car on aurait plus l' erreur.

Je vais essayer et je vous tiens au courant!

Mauricio
Rejoignez-nous