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

cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 19 nov. 2009 à 14:50 - Dernière réponse : cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention
- 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
Afficher la suite 

15 réponses

Répondre au sujet
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscription 3 avril 2018 Dernière intervention - 19 nov. 2009 à 18:39
+3
Utile
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]
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Cirec
Cirec 4217 Messages postés vendredi 23 juillet 2004Date d'inscription 3 avril 2018 Dernière intervention - 20 nov. 2009 à 14:22
+3
Utile
[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]
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Cirec
WhiteHippo 1270 Messages postés samedi 14 août 2004Date d'inscription 5 avril 2012 Dernière intervention - 20 nov. 2009 à 23:20
+3
Utile
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.
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de WhiteHippo
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 19 nov. 2009 à 18:47
0
Utile
Merci Cirec.

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

Maurício
Commenter la réponse de cs_MAURICIO
Utilisateur anonyme - 19 nov. 2009 à 19:50
0
Utile
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 .
Commenter la réponse de Utilisateur anonyme
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 19 nov. 2009 à 21:10
0
Utile
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.
Commenter la réponse de cs_Delphiprog
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 20 nov. 2009 à 10:02
0
Utile
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!
Commenter la réponse de cs_MAURICIO
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 20 nov. 2009 à 14:36
0
Utile
Merci Cirec,

je vais reessayer sur cette voie ...

A+
Commenter la réponse de cs_MAURICIO
WhiteHippo 1270 Messages postés samedi 14 août 2004Date d'inscription 5 avril 2012 Dernière intervention - 21 nov. 2009 à 10:24
0
Utile
Bonjour

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

Cordialement.
Commenter la réponse de WhiteHippo
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 23 nov. 2009 à 17:45
0
Utile
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+
Commenter la réponse de cs_MAURICIO
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 23 nov. 2009 à 17:46
0
Utile
Je résume: mon pack de compo compile mais plus mes projets qui utilisent le compo TcyIniform ...

Merci de votre aide!
Commenter la réponse de cs_MAURICIO
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 23 nov. 2009 à 18:05
0
Utile
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+
Commenter la réponse de cs_MAURICIO
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 23 nov. 2009 à 18:58
0
Utile
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?
Commenter la réponse de cs_MAURICIO
WhiteHippo 1270 Messages postés samedi 14 août 2004Date d'inscription 5 avril 2012 Dernière intervention - 23 nov. 2009 à 21:13
0
Utile
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.
Commenter la réponse de WhiteHippo
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscription 15 décembre 2014 Dernière intervention - 24 nov. 2009 à 12:09
0
Utile
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
Commenter la réponse de cs_MAURICIO

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.