Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants VCL Delphi Discussion :

Problème d'identification d'un composant dans le Sender


Sujet :

Composants VCL Delphi

  1. #1
    Membre habitué
    Problème d'identification d'un composant dans le Sender
    Bonjour à tous,

    J'ai une série de boutons radio dans un RadioGroup nommé "RGChiffres" que je dois identifier dans une procédure. Les boutons sont identifiés par la valeur de l'index de RGChiffres afin de mettre à jour la Police d'affichage dans une série de "TPanel".
    Le code me paraissait assez simple mais ça plante. Voici le source de la procédure. J'ai laissé les deux lignes du showmessage qui m'a permit de localiser l'erreur mais je ne la comprends pas.
    Voici le code de la détection d'un changement de clic sur le RadioGroup:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    procedure TForm2.RGChiffresClick(Sender: TObject);
     var i,j : integer;
    begin
      for i := 0 to ComponentCount - 1 do
      begin
        showmessage(Components[i].Name+' = '+inttostr(I+1)+' eme composant'); // 1er test => OK donne Panel1 
        if Components[i] is TPanel then
        begin
          showmessage(TPanel(Sender).Name+' => index choix = '+inttostr(RGChiffres.ItemIndex+1));//2ème test => TPanel(Sender).Name donne TGChiffres ce qui ne devrait pas
          if TPanel(Sender).Name
             =
             TPanel(FindComponent('Panel'+inttostr(RGChiffres.ItemIndex+1))).Name  then
          begin
            With TPanel(Sender).Font do
            begin
              Color := clYellow;
              Style := [fsBold];
            end;
          end else
          begin
            For j := 0 to Maxchiffres - 1 do
            begin
              With TPanel(FindComponent('Panel'+inttostr(j))).Font do // ça plante ici (violation...)
              begin
                Color := clGray;
                Style := [];
              end;
            end;
          end;
        end;
      end;


    Est-ce que vous y voyez plus clair que moi?

    merci

  2. #2
    Rédacteur/Modérateur

    Citation Envoyé par Jlmat Voir le message
    TPanel(Sender).Name donne TGChiffres ce qui ne devrait pas
    Ben si, Sender est le RadioGroup ...

    Citation Envoyé par Jlmat Voir le message
    if TPanel(Sender).Name = TPanel(FindComponent('Panel'+inttostr(RGChiffres.ItemIndex+1))).Name then
    ... ce qui entraîne que ce test échouera toujours.

    Citation Envoyé par Jlmat Voir le message
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    For j := 0 to Maxchiffres - 1 do
    begin
      With TPanel(FindComponent('Panel'+inttostr(j))).Font do //ça plante ici (violation...)
    Le panel recherché n'existe pas, FindComponent renvoie nil. TPanel(nil).Font égal VA.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var Panel :TPanel;
     
    Panel := TPanel(FindComponent('Panel'+inttostr(j)));
     
    if Assigned(Panel) then
      With Panel.Font do ...



    Après, il y a certainement plus simple comme approche. FindComponent est rarement la meilleure solution.

  3. #3
    Expert éminent sénior
    alors en effet le Sender c'est le Radiogroup, mais ce code est affreux

    si je comprend bien, quand on clique sur le premier Radio bouton Panel1 doit change de font, sur le second, c'est Panel2, etc...

    pour ce genre de chose, j'initialise un tableau dans le OnCreate de la fiche

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
     
    type
      TForm2 = class(Form)
      ...
      private
        fPanels: array[0..1] of TPanel;
      end;
    ...
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      FPanels[0] := Panel1;
      FPanels[1] := Panel2;
    end;
     
    procedure TForm2.RGChiffresClick(Sender: TObject);
    var
      index: Integer;
    begin
    // EDIT: je viens de comprend le code <img src="images/smilies/icon_smile.gif" border="0" alt="" title=":)" class="inlineimg" />
      for Index := Low(FPanels) to High(FPanels) do 
      with FPanels[Index].Font do
      begin
         if Index = RGChiffres.ItemIndex then
        begin
           Color := clYellow;
           Style := [fsBold];  
        end else begin
           Color := clGray;
           Style := [];  
        end;
      end;
    end;


    c'est à la fois plus rapide, plus lisible, plus facile à comprendre, plus facile à maintenir...enfin je ne vois que des aventages
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre habitué
    Merci Andnotor pour ta réponse!
    En effet, le test if TPanel(Sender).Name = TPanel(FindComponent('Panel'+inttostr(RGChiffres.ItemIndex+1))).Name then n'est pas valable, je le remplace par

    Merci Paul, ton code fonctionne bien. C'est effectivement plus rationnel.
    Dans le Oncreate, j'ai essayé le code suivant qui ne fonctionne pas...
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
          for i := 0 to High(fPanels) do
            fPanels[i] := TPanel(FindComponent('Panel'+inttostr(i+1)).Name);


    c'était pour éviter 12 affectations individueles mais qui ne plante pas...
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      FPanels[0] := Panel1;
      FPanels[1] := Panel2;
      FPanels[2] := Panel3;
     ...
      FPanels[10] := Panel11;
      FPanels[11] := Panel12;



  5. #5
    Rédacteur/Modérateur

    Citation Envoyé par Jlmat Voir le message
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    fPanels[i] := TPanel(FindComponent('Panel'+inttostr(i+1)).Name);
    FPanels est un tableau de TPanel mais tu essayes d'y inscrire une string (Name). fPanels[i] := TPanel(FindComponent('Panel'+inttostr(i+1)));.

    Mais ne pourrais-tu pas réorganiser ton interface et poser ces panels sur un autre panel (ou TGroupBox, TScrollBox, peu importe) qui servirait de conteneur ?
    Tu n'aurais dès lors plus à maintenir une liste séparée puisque le contrôle "conteneur" connaît ses enfants.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //Les panels sont posés sur PanelGroup
    for Index := 0 to PanelGroup.ControlCount -1 do
      with TPanel(PanelGroup.Controls[Index]).Font do
        if Index = RGChiffres.ItemIndex then
        begin
          Color := clYellow;
          Style := [fsBold];
        end
        else
        begin
          Color := clGray;
          Style := [];
        end;

  6. #6
    Membre habitué
    Oui, c'est une bonne idée Andnotor!
    Merci