Inspecteur d'objet

Résolu
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 - 3 août 2010 à 14:17
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 - 10 août 2010 à 19:24
Bonjour,

Dans un composant, je souhaite utiliser un type séparateur qui comprend par exemple :
('.',';',#13,'/','|',',','-',' ','_',':');
Je souhaite que ces séparteurs apparaissent tels quels dans l'inspecteur d'objet du composant.

Qu'elle est la bonne méthode?

Je peux bien sûr à l'exécution transtyper
Par exemple :

Type
TTypeSeparator =(tsPoint,tsComma...);
Var 
Separator : TTypeSeparator;
SeparChar : Char; 

Puis faire un Case Separator of
                tsPoint : SeparChar := '.';
                tsComma : Separator
                ...
              End;


Mais ça n'apparaitra pas dans l'inspecteur de propriétés du composant.
Peut-être un type persistant?

Qu'en pensez-vous?
Merci

Jean_Jean

16 réponses

Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
3 août 2010 à 16:26
Salut,

c'est un peu plus complexe que ça
regarde ce lien ... il me semble contenir l'essentiel pour arriver au résultat attendu
pour reprendre les termes du lien:
1°) créer un type compatile "Integer"
  // Définition du type 'Touche' permettant ensuite l'ajout d'un éditeur de propriétés.
  // TTouche est compatible avec le type Integer.
  TTouche = 0..255;


2°) la propriété de type "TTouche"

3°) un tableau, de type "TIdentMapEntry ", de correspondance "valeur touche" >> "Texte touche"
const
  Touches: array[0..137] of TIdentMapEntry = (
  ( Value:Ord('.')    ; Name:'.'),
  ( Value:Ord(',')    ; Name:','),
   ...

4°) créer les fonctions de conversions
Function ToucheToIdent(Touche: Longint; var Ident: string): Boolean;
begin
  Result := IntToIdent(Touche, Ident, Touches);
end;

Function IdentToTouche(const Ident: string; var Touche: Longint): Boolean;
begin
  Result := IdentToInt(Ident, Touche, Touches);
end;

5°) et enfin définir un éditeur de propriétés pour ce nouveau type
  //Définition de l'éditeur de propriété pour les TTouche.
  //
  //Ce n'est pas indispensable, mais ça évite de connaître les codes de
   //touches par coeur. Il sera utilisé automatiquement par Delphi si vous
   //créez une propriété de type TTouche dans vos composants.
  TToucheProperty = class(TIntegerProperty)
  public
    {GetAttributes : }
    function GetAttributes: TPropertyAttributes; override;
    {GetValue : }
    function GetValue: string; override;
    {GetValues : }
    procedure GetValues(Proc: TGetStrProc); override;
    {SetValue : }
    procedure SetValue(const Value: string); override;
  end;

6°) enregistrer le tout (le nouveau type l'éditeur de propriété et ton composant )
// Enregistrement des classes créées
procedure Register;
begin
  RegisterPropertyEditor(TypeInfo(TTouche), Nil, '', TToucheProperty);
  RegisterComponents('Exemples', [TonComposant]);
end;
initialization
  RegisterIntegerConsts(TypeInfo(TTouche), IdentToTouche, ToucheToIdent);


voilà ça devrait le faire


[hr]@+Cirec
[hr]
3
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
3 août 2010 à 20:33
oui je sais !!

mais n'essayes pas de compiler "DsgnIntf" tu n'y arriveras pas ... par contre si tu respectes scrupuleusement l'exemple du lien que tu donnes sur Phidels.com, le code compile, le paquet s'installe et tout fonctionne bien ... et ensuite seulement l'unité "DesignIntf" est reconnue par l'éditeur (en passant la souris dessus)

donc en conclusion tu ne peux pas compiler un tel code avec F9 si le projet en cours n'est pas un paquet (*.dpk)

ah oui aussi .. il n'y a pas de "DesignIntf.dcu" mais c'est normal .. delphi fait le lien en interne à condition de l'utiliser correctement


[hr]@+Cirec
[hr]
3
cs_yanb Messages postés 271 Date d'inscription lundi 27 octobre 2003 Statut Membre Dernière intervention 7 juillet 2022 14
8 août 2010 à 16:52
Salut jean_jean, mais je crois que c'est plus comme ça :
Dans ton package du rajoute {$DESIGNONLY} et dans requires : designide

unit CEdProprieteSeparators;

interface

uses
    SysUtils, Classes, DesignEditors, DesignIntf;

type
  TDataSeparator = 0..255;

const
  MaxSeparators  = 10;
  Separators : array[0..(MaxSeparators - 1)] of TIdentMapEntry = (
              (Value : Ord('.') ; Name : ' .'),
              (Value : Ord(',') ; Name : ' ,'),
              (Value : Ord(';') ; Name : ' ;'),
              (Value : Ord(#13) ; Name : 'CR'),
              (Value : Ord('/') ; Name : ' /'),
              (Value : Ord('|') ; Name : ' |'),
              (Value : Ord('-') ; Name : ' -'),
              (Value : Ord(' ') ; Name : 'SP'),
              (Value : Ord('_') ; Name : ' _'),
              (Value : Ord(':') ; Name : ' :'));

type
   TSeparatorProperty  = class(TIntegerProperty)
   public
     function GetAttributes : TPropertyAttributes; override;
     function GetValue: string; override;
     procedure GetValues(Proc: TGetStrProc); override;
     procedure SetValue(const Value:String); override;
   end;

    procedure register;
    function SeparatorToIdent(Separator : Longint; var Ident : string):Boolean;
    function IdentToSeparator(const Ident : string; var Separator : Longint):Boolean;
    function DataDecToString(DataDec : TDataSeparator): string;
    function StringToDataDec(const Str: string): TDataSeparator;

implementation

function SeparatorToIdent(Separator : Longint; var Ident : string):Boolean;
begin
    Result := IntToIdent(Separator, Ident, Separators);
end;

function IdentToSeparator(const Ident : string; var Separator : Longint):Boolean;
begin
    Result := IdentToInt(Ident, Separator, Separators);
end;

function TSeparatorProperty.GetAttributes : TPropertyAttributes;
begin
    Result := [paAutoUpdate, paValueList, paRevertable];
end;

procedure TSeparatorProperty.GetValues(Proc: TGetStrProc);
var
    I   : Integer;
begin
    for I := Low(Separators) to High(Separators) do
        Proc(Separators[I].Name);
end;

function TSeparatorProperty.GetValue : string;
begin
    if not SeparatorToIdent(TDataSeparator(GetOrdValue), Result) then
        Result := IntToStr(GetOrdValue);
end;

procedure TSeparatorProperty.SetValue(const Value: string);
var
    NewValue    : Longint;
begin
    if IdentToSeparator(Value, NewValue) then
        SetOrdValue(NewValue)
    else
        inherited SetValue(Value);
end;

function DataDecToString(DataDec : TDataSeparator): string;
begin
    if not SeparatorToIdent(DataDec, Result) then
        FmtStr(Result, '%d', [DataDec]);
end;

function StringToDataDec(const Str: string): TDataSeparator;
var
    Lg  : Longint;
begin
    if not IdentToSeparator(Str, Lg) then
        Lg := StrToInt(Str);
    Result := Lg;
end;

procedure register;
begin
    RegisterPropertyEditor(TypeInfo(TDataSeparator), nil, '', TSeparatorProperty);
end;

initialization
    RegisterIntegerConsts(TypeInfo(TDataSeparator), IdentToSeparator, SeparatorToIdent);

end.

Pour l'exemple je prend un TEdit pour composant avec la propriété DataDec
unit QEdit;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, CEdProprieteSeparators, DesignEditors, DesignIntf;

type
  QEdit = class(TEdit)
    private
        FDataDec: TDataSeparator;
    protected
    public
        constructor Create (Aowner: TComponent); override;
        destructor  Destroy; override;
    published
        property DataDec : TDataSeparator read FDataDec write FDataDec;
    end;

procedure Register;

implementation

constructor QEdit.Create(Aowner: TComponent);
begin
    inherited Create(AOwner);
        FDataDec:=StringToDataDec(' .');
end;

destructor QEdit.Destroy;
begin
    inherited Destroy;
end;

procedure Register;
begin
    RegisterComponents('Exemples', [QEdit]);
    RegisterPropertyEditor(TypeInfo(TDataSeparator), nil, '', TSeparatorProperty);//utile ?
end;

initialization
    RegisterIntegerConsts(TypeInfo(TDataSeparator), IdentToSeparator, SeparatorToIdent);//utile ?

end.

Normalement c'est ok
@+yanb
3
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
10 août 2010 à 15:17
[quote=yanb]de plus si des problèmes subsistent avec designintf, tu peux ajouter dans le projet -> options -> chemin de recherche -> {$DELPHI}/ToolsApi/Source/ (je croix de souvenir ). /quote
je déconseille quand même fortement cette option:

la plupart de ces unités ne sont pas compilables par l'IDE ... c'est comme vouloir recompiler l'unité "System.pas" ... c'est impossible !!!

si vous avez des problèmes avec ces unités, il y a de fortes chances que ce soit une erreur de votre part, une mauvaise utilisation et/où méthode de compilation.


[hr]@+Cirec
[hr]
3

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

Posez votre question
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
10 août 2010 à 15:21
C' est exact Cirec,
ces unités ne sont pas faites pour être recompilées!!!
On ajoute le package dans les requires des nos packages en design only: impossible de les utiliser en run-time (elles sont faites pour modifier l' IDE de toute façon) ...

A+
3
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
3 août 2010 à 16:40
Ouha! du grand Cirec!
Bon, je vais essayer d'exploiter la chose!
Bien à toi
Jean_Jean
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
3 août 2010 à 19:17
1. La class class(TIntegerProperty) est dans l'unité
DsgnIntf qui se trouve dans mon répertoire Toolsapi de D7 perso. Mais lorsque je compile, il me trouve 40 erreurs. Bizarre, il ne reconnait pas les identificateurs de sa propre unité?!?!?
Dommage, la démarche que tu me proposai était en bonne voie!
2. En plus du lien que tu m'a donné, j'en ai trouvé un autre ici
3. Bon, sinon, l'éditeur fera apparaître les noms symboliques de séparateurs
@+
Jean_Jean
0
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
4 août 2010 à 10:16
Salut vous 2!

c' est très interessant... J' ai bien ajouté un Item dans le popUpMenu de mes compos mais je n' ai pas encore exploité le fait que je puisse créer mon propre éditeur de compo!

Ça me donne des idées tout ça :)

A+
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
4 août 2010 à 19:23
Bienvenue Mauricio!
Je vais essayé ce we!
Chaque auteur a sa méthode qui sont toutes intéressantes et la doc Borland est peau de chagrin sur le sujet.
Bon, Pour éviter de compiler DsgnIntf, j'ai un peu peur, on va voir par le concepteur de composant!...
@+
Jean_Jean
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
8 août 2010 à 10:18
Ben, c'est pas gagné!
1. J'ai essayé d'installer selon la procédure traditionnelle (indiqué par "Phidels" dans son ) pour tester un nouvel éditeur de propriété.J'ai toujours les erreurs d'identifiant dans la propre unité Designintf.
2. Je ne possède pas apparemment L'autre unité DesignEditors incluse dans le uses de l'exemple. C'est probablement pour cette raison que je n'arrive pas à installer le dpk de l'éditeur.
D7 perso ne permet peut-être pas de faire cela!
3. Bon en attendant de trouver une méthode plus élégante, je vais donc faire saisir le séparateur par l'utilisateur de mon futur composant.
4. Je donne ci-dessous, le code en cours d'écriture à laconception de l'unité du nouvel éditeur:

unit CEdProprieteSeparators;
{NOUVEAU EDITEUR DE PROPRIETE : TSeparatorProperty
}

interface
uses
  SysUtils,DsgnIntf,DesignEditors,Dialogs;

Const
  TDataSeparator = 0..255;
  MaxSeparators  = 10;

  Separators : array[0..MaxSeparators-1] of TIdentMapEntry = (
              (Value : Ord('.') ; Name : ' .'),
              (Value : Ord(',') ; Name : ' ,'),
              (Value : Ord(';') ; Name : ' ;'),
              (Value : Ord(#13) ; Name : 'CR'),
              (Value : Ord('/') ; Name : ' /'),
              (Value : Ord('|') ; Name : ' |'),
              (Value : Ord('-') ; Name : ' -'),
              (Value : Ord(' ') ; Name : 'SP'),
              (Value : Ord('_') ; Name : ' _'),
              (Value : Ord(':') ; Name : ':'));

Type

   {L'editeur descend de l'éditeur d'entiers. On bénéficiera donc des
   méthodes GetOrdValue et SetOrdvalue pour récupérer et mettre une valeur
   depuis l'inspecteur d'objets}
   TSeparatorProperty  = class(TIntegerProperty)
   public

     {GetAttributes:}
     function GetAttributes : TPropertyAttributes; override;
     {GetValue:}
//     function GetValue:string;override;
     {GetValues:}
     procedure GetValues(Proc:TGetStrProc);override;
     {SetValue}
//     procedure SetValue(const Value:String);
     procedure SeparatorEdit; override;
   end;


implementation

{---------------------------------------------------
 Fonction de conversion de l'ordre de l'Ascii séparteur de données en son nom
 symbolique qui apparaitra tel quel dans l'inspecteur de propriété du composant
 Ord('.') => '.' visuel dans l'inspecteur
 utilise pour cela un nouveau type de propriété qui n'est pas hérité naturellement
 et qu'il faut définir
---------------------------------------------------}
Function TBTreeGraph.SeparatorToIdent(Separator : Integer; Var Ident : String):Boolean;
begin
  result := IntToIdent(Separator,Ident,Separators);
end;
Function TBTreeGraph.IdentToSeparator(const Ident : string; Var Separator : Integer):Boolean;
begin
  result := IdentToInt(Ident,Separator,Separators);
end;

{-------------------------------------------------
définition du type d'éditeur de propriétés par GetAttributes:  (de l'Aide Delphi)
 paAutoUpdate => La méthode SetValue est appelée à chaque modification effectuée
 dans l'éditeur au lieu d'être appelée après l'approbation de la modification.
 PaValueList  => L'éditeur de propriété peut renvoyer une liste énumérée de
 valeurs pour la propriété. Quand paValueList est définie, la méthode GetValues
 doit être surchargée pour fournir les valeurs énumérées. Quand paValueList est
 définie, l'inspecteur d'objets affiche un bouton de déroulement à droite de la
 propriété.
---------------------------------------------------}
function TSeparatorProperty.GetAttributes : TPropertyAttributes;
begin
  result := paAutoUpdate; // ou PaValueList à voir?
end;

{---------------------------------------------------
GetValues: (Aide Delphi)
L'inspecteur d'objet appelle GetValues quand l'utilisateur clique sur le bouton
de déroulement pour afficher les valeurs énumérées. La méthode GetValues de
TPropertyEditor n'a aucun effet. Les éditeurs de propriétés qui renvoient
paValueList avec la méthode GetAttributes doivent surcharger GetValues pour
appeler le paramètre Proc pour chaque chaîne susceptible de représenter une
valeur énumérée correcte. Même si la méthode GetAttributes ne renvoie pas
paValueList, les éditeurs de propriétés pour les types énumérés doivent toujours
surcharger GetValues pour énumérer toutes les valeurs possibles.
---------------------------------------------------}
function TSeparatorProperty.GetValues(Proc:TGetStrProc);
var
  i: integer;
begin
  for i := 0 to MaxSeparators - 1 do Proc(Separators[i]);
end;

{---------------------------------------------------
 Procédure qui est appelée par l'inscpecteur d'objet lorsque l'utilisateur clique
 sur le bouton '...'
---------------------------------------------------}
procedure SeparatorEdit; override;
var i : interger;
begin
  i := GetOrdvalue;
  showmessage('GetOrdValue contient la valeur actuelle de la propriété'+#13#10+
              'dans l''inspecteur d''objet ici : '+inttostr(i)+#13+
              'SetOrdValue permet d''indiquer la valeur que doit prendre la'+#13+
              'propriété en sortant de l''éditeur');
  setOrdValue(100);
end;

{---------------------------------------------------
GetValue: (Aide Delphi)
GetValue formate la valeur de la propriété sous la forme d'une chaîne. Si la
valeur n'est pas disponible, GetValue déclenche une exception.
---------------------------------------------------}
//procedure TSeparatorProperty.GetValue:string;
//begin
//end;

{SetValue}
//procedure TSeparatorProperty.SetValue(const Value:String);
//begin
//end;

procedure register;
begin
  RegisterPropertyEditor(TypeInfo(Integer),Nil,TSeparatorProperty);
end;

end.

Bien à vous
Jean_Jean
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
8 août 2010 à 19:09
Merci Yanb pour ton commentaire.
1. voilà qui relance le débat!
2. j'essaye ça et je te tiens au courant.

Jean_Jean
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
8 août 2010 à 19:12
Au fait, s'il y a un admin qui
passe par là, le titre de mon tropic est trompeur. il vaudrait mieux mettre "Inspecteur de propriété" plutot "qu'inspecteur d'objet".
si ça n'est pas trop compliqué à changer, ça serait mieux pour le recencement dans le moteur de recherche pour les internautes...
Jean_Jean
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
8 août 2010 à 20:35
Bravo yanb, tu es mon sauveur!
1. Comme me l'avait dit Cirec et je le répète pour les internautes qui passeraient par là, il ne faut pas compiler le composant comme on le fait habituellement, il faut directement l'installer.
2. Je pense que ton petit exemple mériterait d'être posté en tant que code, qu'en penses-tu? Je ne voudrais pas t'en voler la paternité...Sinon je publierai un autre petit exemple en te citant
3. Car mon composant graphique sur les B-arbres est encore en chantier, cela peut prendre encore un certain temps avant que je publie!

Jean_Jean
0
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
9 août 2010 à 10:07
Salut Jean-Jean,

j' aurai pû t' aider car j' ai eu le même problème que toi!
J' ai dû créer un "design package" pour pouvoir ajouter un menuItem au Popmenu de mes compos.

A+
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
9 août 2010 à 10:50
Salut Mauricio,
Oui, quel dommage que le temps me manque!
Je prends mon temps maintenant pour développer. Et sans ce site, je ne pourrai pas y arriver.
Les B-Arbres me torturent les neurones en ce moment. Quand je pense que j'étais maître en la matière il y a 30 ans!
Je pense que je soumettrai mon compo à votre critique (toi ou les amis du site) avant la publication.
Bien à toi et merci pour ton intérêt.
Jean_Jean
0
cs_Jean_Jean Messages postés 615 Date d'inscription dimanche 13 août 2006 Statut Membre Dernière intervention 13 décembre 2018 3
10 août 2010 à 19:24
Merci à tous les trois pour vos commentaires pertinents.
Yanb, je regarderai tes liens un peu plus tard, merci...
Que ferait-on sans Delphi?
Jean_Jean
0
Rejoignez-nous