Inspecteur d'objet [Résolu]

cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 3 août 2010 à 14:17 - Dernière réponse : cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 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
Afficher la suite 

Votre réponse

18 réponses

Meilleure réponse
Cirec
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 3 août 2010 à 16:26
3
Merci
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]

Merci Cirec 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de Cirec
Meilleure réponse
Cirec
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 3 août 2010 à 20:33
3
Merci
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]

Merci Cirec 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de Cirec
Meilleure réponse
cs_yanb
Messages postés
260
Date d'inscription
lundi 27 octobre 2003
Dernière intervention
4 mars 2016
- 8 août 2010 à 16:52
3
Merci
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

Merci cs_yanb 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de cs_yanb
Meilleure réponse
cs_yanb
Messages postés
260
Date d'inscription
lundi 27 octobre 2003
Dernière intervention
4 mars 2016
- 10 août 2010 à 12:42
3
Merci
Salut jean_jean,
j'ai posté des exemples très très simple pour améliorer l'inspecteur d'objet en 2005 ,
Lien1
Lien2
Lien3
bon ici c'est un peu plus complexe avec les TIntegerProperty, mais le but reste le même ...
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 ).
Dans le package sous requires si tu ajoute designide il permet d'éviter des erreurs comme proxies.dcu n'existe pas ... et le {DESIGNONLY} permet de n'utiliser le code quand conception.
voili voilou .
@+yanb

Merci cs_yanb 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de cs_yanb
Meilleure réponse
Cirec
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 10 août 2010 à 15:17
3
Merci
[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]

Merci Cirec 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de Cirec
Meilleure réponse
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Dernière intervention
15 décembre 2014
- 10 août 2010 à 15:21
3
Merci
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+

Merci cs_MAURICIO 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de cs_MAURICIO
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 3 août 2010 à 16:40
0
Merci
Ouha! du grand Cirec!
Bon, je vais essayer d'exploiter la chose!
Bien à toi
Jean_Jean
Commenter la réponse de cs_Jean_Jean
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 3 août 2010 à 19:17
0
Merci
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
Commenter la réponse de cs_Jean_Jean
Cirec
Messages postés
4229
Date d'inscription
vendredi 23 juillet 2004
Dernière intervention
3 août 2018
- 3 août 2010 à 21:12
0
Merci
tu peux aussi jeter un oeil sur l'excellent code de F0xi

tant sur le plan didactique que sur l'utile


[hr]@+Cirec
[hr]
Commenter la réponse de Cirec
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Dernière intervention
15 décembre 2014
- 4 août 2010 à 10:16
0
Merci
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+
Commenter la réponse de cs_MAURICIO
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 4 août 2010 à 19:23
0
Merci
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
Commenter la réponse de cs_Jean_Jean
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 8 août 2010 à 10:18
0
Merci
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
Commenter la réponse de cs_Jean_Jean
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 8 août 2010 à 19:09
0
Merci
Merci Yanb pour ton commentaire.
1. voilà qui relance le débat!
2. j'essaye ça et je te tiens au courant.

Jean_Jean
Commenter la réponse de cs_Jean_Jean
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 8 août 2010 à 19:12
0
Merci
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
Commenter la réponse de cs_Jean_Jean
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 8 août 2010 à 20:35
0
Merci
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
Commenter la réponse de cs_Jean_Jean
cs_MAURICIO
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Dernière intervention
15 décembre 2014
- 9 août 2010 à 10:07
0
Merci
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+
Commenter la réponse de cs_MAURICIO
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 9 août 2010 à 10:50
0
Merci
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
Commenter la réponse de cs_Jean_Jean
cs_Jean_Jean
Messages postés
639
Date d'inscription
dimanche 13 août 2006
Dernière intervention
5 mai 2016
- 10 août 2010 à 19:24
0
Merci
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
Commenter la réponse de cs_Jean_Jean

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.