IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Langage Delphi Discussion :

Vider des Objets 'multi'


Sujet :

Langage Delphi

  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut Vider des Objets 'multi'
    Bonjour à tous, j'espère être au bonne endroit.

    Je créer des TPanel dynamiquement dont leur name peut être :
    M0JPanel200
    M1JPanel200
    M2JPanel200
    ou
    M0XJPanel200
    M1XJPanel200
    M2XJPanel200

    Sachant que mes TPanels sont créer dans une form et que leur parent est un StringGrid
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Panel.Parent := Self.StringGrid;
    Ma question comment arriver a rendre invisible l'ensemble des TPanels dont leur name se termine par 200 ?

    J'ai vue sur ce forum ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      For i:=1 To 10 Do
      Begin
        Edit:=TEdit(Form1.FindComponent('Edit'+IntToStr(i)));
        If Edit<>Nil
          Then Edit.Text:='';
      End;
    Mais le problème c'est qu'il faudrait un genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Form1.FindComponent( * + '200');


    MErci de vos lumières

  2. #2
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Salut,

    Essaie avec ce code :

    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i:integer;
    begin
      // Pour tous les composants de la Form1
      for i:=0 to Form1.ComponentCount -1 do
      begin
        // Si le composant est un TPanel
        if(Form1.Components[i] is TPanel)then
        begin
          // Si son Name contient 200 alors on désactive la visibilité du panel.
         // AnsiConstainsText ne fait pas attention à la casse. Si tu veux tenir compte de ça, utilise AnsiContainsStr.
          if (AnsiContainsText(TPanel(Form1.Components[i]).Name,'200'))then
          begin
            TPanel(Form1.Components[i]).Visible:=false;
          end;
        end;
      end;
    end;
    Tiens nous au courant!
    A+

  3. #3
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bonsoir

    Ta proposition fonctionne trés bien.

    La problématique c'est que je peux avoir :
    - 2000 composants TPanel
    - et maxi 5 aillant la même terminaison (donc 400 groupe de Panel aillant la même terminaison)

    Il y a-t-il un moyen d'accélerer ta proposition ?


    Sinon chapeau bas, j'aurais jamais pensé à cela.

  4. #4
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Admettons que j'ajoute cela à un TPAnel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    property Caption1 : String read fCaption1 write fCaption1;
    et que lors de la création dynamique je laisse le name comme si-dessous et que j'ecris

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MonPanel := TMonPanel.Create(Self);
    MonPanel.Parent := Self.StringGrid;
    ..
    MonPanel.Caption1 := 'A'   (dans la réalité ce sera un chiffre)
    Est ceque dans ce cas on peut, trouver le nombre de composant aillant A en Caption1 ?

    Si oui je pourrais réduire ta boucle ?

    Je délire ou pas ?

  5. #5
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Tout d'abord, merci pour le chapeau bas

    Ensuite, en ce qui concerne ta proposition avec le Caption1, c'est toujours pareil, il faudra bien faire le test sur le panel pour savoir si Caption1 possède ou non ce A.

    On pourrait limiter la durée de traitement en créant un nouveau composant (qui en réalité serait un Panel)... En fait, c'est uniquement le nom du compo qui changerait ... Ainsi, on se limiterait sur la recherche du compo ce qui supprimerait le test avec AnsiContainsText ...
    Sinon, je vois pas comment raccourcir le temps d'exécution (si ce n'est regroupé des Panels dans d'autres Panels ...)
    Désolé

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 812
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 812
    Points : 13 527
    Points
    13 527
    Par défaut
    AnsiContainsStr test la chaîne complète alors que seuls le 3 derniers caractères t'intéressent. Utilise plutôt RightStr dans StrUtils qui sera certainement plus efficace. En plus, si tu as une fois un M200XJPanel400, ton test sera erroné! (Autant prévoir l'évolution future )

    Tu pourrais aussi utiliser la propriété Tag pour le numéro du groupe ce qui éviterait les tests sur une chaîne.

    Mais pour une boucle vraiment efficace, crée un TList par groupe et ajoutes-y les Panels directement lors de leur création. Le temps de chargement sera un peu plus long, mais les traitements ultra rapide!

    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
    33
    34
    35
    36
    37
    var
      Groups :array [0..999] of TList;
     
    function TForm1.CreatePanel(aPrefix: string; aGroup: integer) :TPanel;
    begin
      //Crée le TList uniquement s'il est nécessaire
      if not Assigned(Groups[aGroup]) then
        Groups[aGroup] := TList.Create;
     
      Result        := TPanel.Create(Self);
      Result.Parent := StringGrid;
      Result.Name   := Format('%s%d', [aPrefix, aGroup]);
      Result.Tag    := aGroup;
      //etc.
     
      Groups[aGroup].Add(Result);
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    var
      i: Integer;
    begin
      //FreeAndNil test d'abord que le pointer soit assigné 
      //et si oui, libère l'objet
      for i := 0 to High(Groups) do
        FreeAndNil(Groups[i]);
    end;
     
    procedure TForm1.SetVisibility(aGroup: integer; aVisible: boolean);
    var
      i: Integer;
    begin
      //S'assure que le groupe existe avant de boucler dessus
      if Assigned(Groups[aGroup]) then
        for i := 0 to Groups[aGroup].Count -1 do
          TPanel(Groups[aGroup][i]).Visible := aVisible;
    end;

  7. #7
    Rédacteur/Modérateur
    Avatar de ero-sennin
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    2 965
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 2 965
    Points : 4 935
    Points
    4 935
    Par défaut
    Salut,

    J'approuve l'idée de Andnotor!
    D'ailleurs, elle m'est venue hier soir, juste avant le dodo (mais mon PC était déjà éteint ).

    Donc oui, faire un TList qui contiendra tous les panels nécessaires à ce que tu souhaites faire est une très bonne idée!

  8. #8
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 933
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 933
    Points : 15 380
    Points
    15 380
    Par défaut
    Salut.

    C'est quoi, des objets 'Muli' ?
    Je voudrais pas me coucher idiot...

  9. #9
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    L'idéal serait de modifer le code de la procédure SetName du composant TPanel voir
    d'en faire une classe dérivée et faire un override de cette procédure dans
    laquelle une fonction AnsiContainsText pourrait faire l'identification et l'intégrer
    dans une liste en utilisant le Design Pattern Observer comme Canevas.
    Compte tenu du nombre de composants TPanel (4000) mis en jeu, c'est dans la colonne
    vertebrale de la classe du composant que le code s'insère le mieux.

    En agissant directement sur la propriété Name de Tpanel et donc sur sa procédure SetName,
    il est possible de combiner à la fois l'analyse de texte qui serait gourmande en
    resource s'il fallait parcourir systématiquement tous les composants d'une fiche de cette façon,
    içi il est fait une seule fois à chaque modification de la propriété name autrement dit à la source, et
    d'utiliser les listes contenant les objets panels qui seraient les Observers.
    Il est question de 5 groupes de panel, donc 5 observers.

    Ca demande de la réflexion, mais le résultat sera non seulement efficace mais aussi élégant
    et découplé d'un point de objet des Tforms, tout au moins faudrat il parcourir les objets(listes)
    observers pour modifier la propriété visible de chacun des panels (Items).

    C'est une suggestion, chacun est libre de faire son choix.

  10. #10
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bonjour,

    Je vais mettre en place la proposition de Andhotor. J'avais penser au Tag mais pas du tout au notin de list (enfin de tableau) qui sans contest doit être vachement plus rapide.

    Ceci dit mes (left, top width, heigt) de mes panel son issu d'une base de donnée donc je vais mettre un peu de temps à mettre en place.

    Je reviens vers vous pour vous dire le résultat.

    PS : Chaplin ta remarque attire mon attention et pour tout dire j'ai pas tout compris. Mais on en reparle apres.
    PS : Jipété déolé je voulais ecrire Multi et pas Muli. oups...

    PS Général : Mes Panel comporte déjà des procedure override sur le canevas enfin procedure PAINT (je vous mettrais tout cela ici)

    Merci à vous. à bientôt.

  11. #11
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bon j'ai des difficultés pour mettre la function CReatepanel en place

    Voici le procedure actuel qui me créer mes panels

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    Procedure TFormPrincipal.MiseEnPlaceDesTPanelJourDejaExistant;
    Var
     xCaption2, xCaption1: String;
     Panel: TRuPanel;
     CalculDuLeft, CalculDuWidth, CalculDuTop, CalculDuHeight: Integer;
     oldTop, i : Integer;
    Begin
      With ModuleDeDonneeSecondaire do
      Begin
        ADOCalendrier.Open;
        ADOCalendrier.Filter := 'NumeroSemaine = '+ QuotedStr(NumeroDeSemaine) + 'And NumeroAnnee = '+ QuotedStr(Annee);
        ADOCalendrier.Filtered := true;
        NbRecord := ADOCalendrier.Recordset.RecordCount;
      end;
      if (NbRecord <> 0) then
      Begin
        StatusBar1.Panels[3].Text := 'Chargement des tâches';
        Application.ProcessMessages;
        with ProgressBarPrincipal do
        Begin
          Visible := True;
          Min:= 0;
          Max:= NbRecord;
          Position :=0;
          Parent := StatusBar1;
          SetBounds((StatusBar1.Panels[0].Width+StatusBar1.Panels[1].Width)
          ,4,StatusBar1.Panels[2].Width-2,StatusBar1.Height-10);
        end;
        With ModuleDeDonneeSecondaire do
        Begin
          while not ADOCalendrier.Eof do
          Begin
            CalculDuLeft := 0;
            CalculDutop := 0;
            CalculDuHeight := 0;
            CalculDuWidth :=0;
            xCaption1 := '';
            xCaption2 := '';
            if ADOCalendrier.Fields.Fields[1].AsString = ComboBoxSalarie.Text then // Uniquement le salarie concerné (choix effectue dans un Combobox)
            Begin
    
           xCaption1 = 'EXEMPLE FORUM'
           xCaption2 := 'EXEMPLE FORUM'
    
         // Cas semaine entière
              if ADOCalendrier.Fields.Fields[30].AsInteger = 9900 then
              Begin
    // Plus traité inutile à éprurer plus tard
              end
              Else
              Begin
    
    // Cas tâches au milieu entre 2 ou x jours ou semaine entière
    // Le dénominateur commun LE GROUPE serait ADOCalendrier.Fields.Fields[31].AsString;
                if ADOCalendrier.Fields.Fields[11].AsInteger <> ADOCalendrier.Fields.Fields[12].AsInteger then  // si date debut et date de fin est différent
                Begin
    
                  oldTop := ADOCalendrier.Fields.Fields[8].AsInteger; // On mémorise l'heure de debut
                  For i:= ADOCalendrier.Fields.Fields[11].AsInteger to ADOCalendrier.Fields.Fields[12].AsInteger do  // De date début à date de fin
                  Begin
                    CalculDuLeft := 0;
                    CalculDutop := 0;
                    CalculDuHeight := 0;
                    CalculDuWidth :=0;
    
                    CalculDuLeft := StringGridJour.ColWidths[0]
                                    + (i * StringGridJour.DefaultColWidth);
    
                    CalculDuTop := StringGridJour.RowHeights[0]
                                    + (oldTop * StringGridJour.DefaultRowHeight);
                    if i <> ADOCalendrier.Fields.Fields[12].AsInteger then  // si on est sur le dernier For i
                    Begin
                      CalculDuHeight := StringGridJour.DefaultRowHeight * (22 - oldtop);
                    end
                    else
                    Begin
                      CalculDuHeight := ADOCalendrier.Fields.Fields[9].AsInteger
                                        * StringGridJour.DefaultRowHeight;
                    end;
                    CalculDuWidth := StringGridJour.DefaultColWidth;
    //
    // Création du TPanel spécifique ici le panel est découper en morceau
    // le dénominateur commun le (groupe) est ADOCalendrier.Fields.Fields[31].AsString
    //
    
                    Panel := TRuPanel.Create(Self);
                    With Panel do
                    Begin
                      Parent := Self.StringGridJour;
                      Font.Size := 8;
                      Font.Name := 'Tahoma';
                      Name := 'M' + IntToStr(i) + 'JPANEL' + ADOCalendrier.Fields.Fields[31].AsString;
                      Caption := '';
                      Left := CalculDuLeft;
                      Top := CalculDuTop;
                      Width := CalculDuWidth-1;
                      Height := CalculDuHeight;
                      Color := clBtnFace;
                      ParentBackground := False;
                      Hint := ADOCalendrier.Fields.Fields[23].AsString;
                      ShowHint := True;
                      StartColor := clCream;
                      EndColor := ADOCalendrier.Fields.Fields[20].AsInteger;
                      Caption1 := xCaption1;
                      Caption2 := xCaption2;
                      OnDblClick := PanelJourDblClick;
                    end;
                    oldTop := 0; // Astuce qui tue. Permet de revenir à 0 dans le découpage du Panel pour continuer sur un autre panel
                  end;
                end
                else
                Begin
    //
    // Ici le TPAnel n'a pas besoin d'être d"écoupé
    // La notion de groupe n'ai pas forcément utile
    //
                  CalculDuLeft := StringGridJour.ColWidths[0]
                                  + (StringGridJour.ColWidths[1]
                                    * (ADOCalendrier.Fields.Fields[2].AsInteger - 1));
                  CalculDuTop := (StrToInt(ADOCalendrier.Fields.Fields[8].AsString)
                                  * StringGridJour.DefaultRowHeight)
                                    + StringGridJour.RowHeights[0];
                  CalculDuHeight := (StrToInt(ADOCalendrier.Fields.Fields[9].AsString)
                                    - StrToInt(ADOCalendrier.Fields.Fields[8].AsString))
                                      * StringGridJour.DefaultRowHeight;
                  CalculDuWidth := StringGridJour.DefaultColWidth;
                  Panel := TRuPanel.Create(Self);
                  With Panel do
                  Begin
                    Parent := Self.StringGridJour;
                    Font.Size := 8;
                    Font.Name := 'Tahoma';
                    Name := 'JPANEL' + ADOCalendrier.Fields.Fields[31].AsString;
                    Caption := '';
                    Left := CalculDuLeft;
                    Top := CalculDuTop;
                    Width := CalculDuWidth-1;
                    Height := CalculDuHeight;
                    Color := clBtnFace;
                    ParentBackground := False;
                    Hint := ADOCalendrier.Fields.Fields[23].AsString;
                    ShowHint := True;
                    StartColor := clCream;
                    EndColor := ADOCalendrier.Fields.Fields[20].AsInteger;
                    Caption1 := xCaption1;
                    Caption2 := xCaption2;
                    OnDblClick := PanelJourDblClick;
                  end;
                end;
              end;
            end;
            ProgressBarPrincipal.Position := ProgressBarPrincipal.Position + 1;
            ADOCalendrier.Next;
          end;
        end;
        ProgressBarPrincipal.Visible := False;
        StatusBar1.Panels[3].Text := '';
      end;
      ModuleDeDonneeSecondaire.ADOCalendrier.Filtered := false;
      ModuleDeDonneeSecondaire.ADOCalendrier.Close;
    
    end;
    Comment mettre la proposition de Andnotor ?
    Ne serait-il pas justicieux de mettre la function à l'interieur de ma procédure ?
    Si oui comment l'intégrer ?

    Je vous mets également le RuPanl déscendent de TPanel pour l'idée de Chaplin
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    type
    
      TRuPanel = class(TPanel)
        Private
          FStartColor:Tcolor;
          FEndColor:Tcolor ;
          fCaption1:String;
          fCaption2:String;
        Protected
          Procedure Paint;override;
        Published
          property StartColor : Tcolor read fStartColor write fStartColor ;
          property EndColor : Tcolor read FEndColor write FEndColor ;
          property Caption1 : String read fCaption1 write fCaption1;
          property Caption2 : String read fCaption2 write fCaption2;
      end;
    ....
    
    procedure TRuPanel.Paint;
      Procedure Degrader;
      Var
        aBand : TRect;    { Bande rectangulaire de couleur courante        }
        i    : Integer;  { Compteur pour parcourir la hauteur de la fiche }
        FStartRGB  : Array[0..2] of Byte;    { RGB de la couleur de départ }
        FCurrentRGB : Array[0..2] of Byte;    { RGB de la couleur courante  }
        FDeltaRGB  : Array[0..2] of Integer; { RGB à ajouter à la couleur de départ pour atteindre la couleur de fin }
        nbtranches: integer;
        Canevas:TControlCanvas;
        Rect:TRect;
      Begin
    //
    // Calcul du Degrader que tout le monde connaite
    //
          Font.Name := self.Font.Name;
          Font.Size := self.Font.Size;
          Brush.Style := bsClear;
          if Self.Caption1 = '' then DrawText(Canevas.Handle, PChar(Self.Caption) , -1, Rect, DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE)
          else
          Begin
            DrawText(Canevas.Handle, PChar(Self.Caption1) , -1, Rect, DT_CENTER or DT_NOPREFIX or DT_SINGLELINE);
            Rect.Top := Rect.Top + Self.Font.Size + 6;
    
            Pen.Color := clBlack;
            MoveTo(Rect.Left+2,Rect.Top);
            LineTo(Rect.Right-2,Rect.top);
    
            Rect.Top := Rect.Top + 2;
            DrawText(Canevas.Handle, PChar(Self.Caption2) , -1, Rect, DT_NOPREFIX or DT_WORDBREAK);
          end;
        End;
       Canevas.Free; // Libérer le canevas après usage !
      End;
    
    begin
     inherited Paint;
     Degrader;
    end;
    Je vous remercie de vos remarques.

  12. #12
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    Je pense que ton approche n'est pas du tout la bonne, bien que la proposition de Andhotor soit une bonne réponse au problème posé.

    Je suis allé trop loin dans mon raisonnement, je n'avais pas bien lu énoncé
    bien que cela serait possible.

    En voyant le code source, il faut traité le problème autrement.

    Quand tu créés autant d'objets sur une forme, le bon usage c'est de ne pas
    créé X milles objets de même type mais d'en simulé le comportement
    avec un objet. Un exemple concret est le tstringGrid, où le passage d'une
    cellule à une autre ne revient qu'a changer la position d'un TEdit au lieu
    d'avoir N X M TEdit.

    Me trompes-je ?

  13. #13
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Non pas exactement. Je ne puex pas traité mon stringgrid de la même manière.

    Chaque Panel crée représente une tâche précise, qui correspond à une durée par la 'colonne' , et une horraire par les 'lignes'.

    Comme un calendrier si tu veux, comme outlook en visu hebdomadaire.

  14. #14
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    C'est à dire que les panels sont de différentes tailles. Je reste pour le moins
    sceptique, car c'est du dessin même si je n'est pas donné le bon exemple, je
    persiste sur mon point de vue.

    Je peux toujours changé d'avis pour l'instant non.

  15. #15
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 812
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 812
    Points : 13 527
    Points
    13 527
    Par défaut
    Il est clair que de toute façon, créer 4000 objets n'est pas optimal.

    Pour en revenir au code:
    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
    //La fonction renvoi un type TRuPanel.
    //L'assignation du parent à été supprimée et reste
    //définie dans ta procédure d'appel
    function TForm1.CreatePanel(aPrefix: string; aGroup: integer) :TRuPanel;
    begin
      //Crée le TList uniquement s'il est nécessaire
      if not Assigned(Groups[aGroup]) then
        Groups[aGroup] := TList.Create;
     
      //Création du type TRuPanel
      Result        := TRuPanel.Create(Self);
      Result.Name   := Format('%s%d', [aPrefix, aGroup]);
      Result.Tag    := aGroup;
     
      Groups[aGroup].Add(Result);
    end;
    Il n'y a en faite que ton TPanel.Create à remplacer par CreatePanel et l'assignation du nom à supprimer. (Elle devient obsolète puisque le nom est défini dans CreatePanel.)
    Le numéro de groupe est également lu en entier à la place d'une chaîne depuis la BD.

    Les lignes supprimées en été commentées pour que tu vois la différence.

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    Procedure TFormPrincipal.MiseEnPlaceDesTPanelJourDejaExistant;
    Var
     xCaption2, xCaption1: String;
     Panel: TRuPanel;
     CalculDuLeft, CalculDuWidth, CalculDuTop, CalculDuHeight: Integer;
     oldTop, i : Integer;
    Begin
      With ModuleDeDonneeSecondaire do
      Begin
        ADOCalendrier.Open;
        ADOCalendrier.Filter := 'NumeroSemaine = '+ QuotedStr(NumeroDeSemaine) + 'And NumeroAnnee = '+ QuotedStr(Annee);
        ADOCalendrier.Filtered := true;
        NbRecord := ADOCalendrier.Recordset.RecordCount;
      end;
      if (NbRecord <> 0) then
      Begin
        StatusBar1.Panels[3].Text := 'Chargement des tâches';
        Application.ProcessMessages;
        with ProgressBarPrincipal do
        Begin
          Visible := True;
          Min:= 0;
          Max:= NbRecord;
          Position :=0;
          Parent := StatusBar1;
          SetBounds((StatusBar1.Panels[0].Width+StatusBar1.Panels[1].Width)
          ,4,StatusBar1.Panels[2].Width-2,StatusBar1.Height-10);
        end;
        With ModuleDeDonneeSecondaire do
        Begin
          while not ADOCalendrier.Eof do
          Begin
            CalculDuLeft := 0;
            CalculDutop := 0;
            CalculDuHeight := 0;
            CalculDuWidth :=0;
            xCaption1 := '';
            xCaption2 := '';
            if ADOCalendrier.Fields.Fields[1].AsString = ComboBoxSalarie.Text then // Uniquement le salarie concerné (choix effectue dans un Combobox)
            Begin
    
           xCaption1 = 'EXEMPLE FORUM'
           xCaption2 := 'EXEMPLE FORUM'
    
         // Cas semaine entière
              if ADOCalendrier.Fields.Fields[30].AsInteger = 9900 then
              Begin
    // Plus traité inutile à éprurer plus tard
              end
              Else
              Begin
    
    // Cas tâches au milieu entre 2 ou x jours ou semaine entière
    // Le dénominateur commun LE GROUPE serait ADOCalendrier.Fields.Fields[31].AsString;
                if ADOCalendrier.Fields.Fields[11].AsInteger <> ADOCalendrier.Fields.Fields[12].AsInteger then  // si date debut et date de fin est différent
                Begin
    
                  oldTop := ADOCalendrier.Fields.Fields[8].AsInteger; // On mémorise l'heure de debut
                  For i:= ADOCalendrier.Fields.Fields[11].AsInteger to ADOCalendrier.Fields.Fields[12].AsInteger do  // De date début à date de fin
                  Begin
                    CalculDuLeft := 0;
                    CalculDutop := 0;
                    CalculDuHeight := 0;
                    CalculDuWidth :=0;
    
                    CalculDuLeft := StringGridJour.ColWidths[0]
                                    + (i * StringGridJour.DefaultColWidth);
    
                    CalculDuTop := StringGridJour.RowHeights[0]
                                    + (oldTop * StringGridJour.DefaultRowHeight);
                    if i <> ADOCalendrier.Fields.Fields[12].AsInteger then  // si on est sur le dernier For i
                    Begin
                      CalculDuHeight := StringGridJour.DefaultRowHeight * (22 - oldtop);
                    end
                    else
                    Begin
                      CalculDuHeight := ADOCalendrier.Fields.Fields[9].AsInteger
                                        * StringGridJour.DefaultRowHeight;
                    end;
                    CalculDuWidth := StringGridJour.DefaultColWidth;
    //
    // Création du TPanel spécifique ici le panel est découper en morceau
    // le dénominateur commun le (groupe) est ADOCalendrier.Fields.Fields[31].AsString
    //
    
                    //Panel := TRuPanel.Create(Self);  <-- Supprimé!!!
    
                    //Le numéro de groupe est lu en entier (AsInteger)
                    Panel := CreatePanel('M' + IntToStr(i) + 'JPANEL', ADOCalendrier.Fields.Fields[31].AsInteger);
                    With Panel do
                    Begin
                      Parent := Self.StringGridJour;
                      Font.Size := 8;
                      Font.Name := 'Tahoma';
                      //Name := 'M' + IntToStr(i) + 'JPANEL' + ADOCalendrier.Fields.Fields[31].AsString;  <-- Supprimé!!! (Obsolète)
                      Caption := '';
                      Left := CalculDuLeft;
                      Top := CalculDuTop;
                      Width := CalculDuWidth-1;
                      Height := CalculDuHeight;
                      Color := clBtnFace;
                      ParentBackground := False;
                      Hint := ADOCalendrier.Fields.Fields[23].AsString;
                      ShowHint := True;
                      StartColor := clCream;
                      EndColor := ADOCalendrier.Fields.Fields[20].AsInteger;
                      Caption1 := xCaption1;
                      Caption2 := xCaption2;
                      OnDblClick := PanelJourDblClick;
                    end;
                    oldTop := 0; // Astuce qui tue. Permet de revenir à 0 dans le découpage du Panel pour continuer sur un autre panel
                  end;
                end
                else
                Begin
    //
    // Ici le TPAnel n'a pas besoin d'être d"écoupé
    // La notion de groupe n'ai pas forcément utile
    //
                  CalculDuLeft := StringGridJour.ColWidths[0]
                                  + (StringGridJour.ColWidths[1]
                                    * (ADOCalendrier.Fields.Fields[2].AsInteger - 1));
                  CalculDuTop := (StrToInt(ADOCalendrier.Fields.Fields[8].AsString)
                                  * StringGridJour.DefaultRowHeight)
                                    + StringGridJour.RowHeights[0];
                  CalculDuHeight := (StrToInt(ADOCalendrier.Fields.Fields[9].AsString)
                                    - StrToInt(ADOCalendrier.Fields.Fields[8].AsString))
                                      * StringGridJour.DefaultRowHeight;
                  CalculDuWidth := StringGridJour.DefaultColWidth;
                  Panel := TRuPanel.Create(Self);
                  With Panel do
                  Begin
                    Parent := Self.StringGridJour;
                    Font.Size := 8;
                    Font.Name := 'Tahoma';
                    Name := 'JPANEL' + ADOCalendrier.Fields.Fields[31].AsString;
                    Caption := '';
                    Left := CalculDuLeft;
                    Top := CalculDuTop;
                    Width := CalculDuWidth-1;
                    Height := CalculDuHeight;
                    Color := clBtnFace;
                    ParentBackground := False;
                    Hint := ADOCalendrier.Fields.Fields[23].AsString;
                    ShowHint := True;
                    StartColor := clCream;
                    EndColor := ADOCalendrier.Fields.Fields[20].AsInteger;
                    Caption1 := xCaption1;
                    Caption2 := xCaption2;
                    OnDblClick := PanelJourDblClick;
                  end;
                end;
              end;
            end;
            ProgressBarPrincipal.Position := ProgressBarPrincipal.Position + 1;
            ADOCalendrier.Next;
          end;
        end;
        ProgressBarPrincipal.Visible := False;
        StatusBar1.Panels[3].Text := '';
      end;
      ModuleDeDonneeSecondaire.ADOCalendrier.Filtered := false;
      ModuleDeDonneeSecondaire.ADOCalendrier.Close;
    
    end;
    Et cessé d'estropier mon nom Andnotor (En référence à un bon vieux disque de Steve Hillage qui sied parfaitement à l'informatique )

  16. #16
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bonsoir à tous,

    J'ai donc tenter de mettre ta proposition Andnotor.

    mais je ton sur une erreur à l'execution du genre EaccessViolation ... à l'adresse xxxx
    et il s'arrete sur la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                    Panel := CreatePanel('M' + IntToStr(i) + 'JPANEL', ADOCalendrier.Fields.Fields[31].AsInteger);
    Ensuite
    J'ai essayer dans la function d'ajouter plus de paramètre mais rien y change.
    (j'ai ajouter Result.Parent / Result.Caption etc...)

    Une idée ?

  17. #17
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 812
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 812
    Points : 13 527
    Points
    13 527
    Par défaut
    C'est alors que le AsInteger n'est pas supporté!
    AsInteger élève une exception s'il n'est pas surchargé dans une classe dérivée. Ce qui (après contrôle ) ne semble pas être le cas dans les composants ADO.

    Pour simplifier le code, tu peux aussi supprimer le 2ème Fields. Fields est la propriété par défaut de TFields et peut donc être omis.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Panel := CreatePanel('M' + IntToStr(i) + 'JPANEL', StrToInt(ADOCalendrier.Fields[31].AsString));

  18. #18
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Re.

    Je suis chiant mais cela ne fonctionne pas mieux
    StrtoInt ou pas

    j'ai même essayer de passé par une variable

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                    xGroupe := StrToint(ADOCalendrier.Fields[31].AsString);
                    Panel := CreatePanel('M' + IntToStr(i) + 'JPANEL', xGroupe);
    avec ou sans AsString, field en plus ou pas.

    Si j'écris cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Panel := CreatePanel('M' + IntToStr(i) + 'JPANEL', 100);
    sa fonctionne !!!

    Là je vois pas la raison.

  19. #19
    Membre chevronné

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 292
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2002
    Messages : 1 292
    Points : 1 944
    Points
    1 944
    Par défaut
    Dans le cas de la variable, il plante à quelle ligne, celle du xGroupe ou celle de la création de Panel?

  20. #20
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 812
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 812
    Points : 13 527
    Points
    13 527
    Par défaut
    Si cela fonctionne avec une variabe en dure, c'est que tu as un problème au niveau de ta BD. Ton champ n'a pas de valeur par défaut et renvoi pafois Null.

    Remplace StrToInt par StrToIntDef qui renverra une valeur par défaut en cas d'erreur. (0 dans l'exemple ci-dessous)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Panel := CreatePanel('M' + IntToStr(i) + 'JPANEL', StrToIntDef(ADOCalendrier.Fields[31].AsString, 0));
    Difficile de t'aider plus
    Comme le dit Linkin, mets des points d'arrêt et regarde où ça bloque (En particulier le contenu de ADOCalendrier.Fields[31].AsString).

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 6
    Dernier message: 12/02/2004, 21h55
  2. [MFC] libération des objets GDI's
    Par Kevgeii dans le forum MFC
    Réponses: 5
    Dernier message: 01/02/2004, 10h37
  3. Créer des objets sur la pile ?
    Par Cornell dans le forum Langage
    Réponses: 8
    Dernier message: 03/03/2003, 11h47
  4. Importer des objets de 3dsMax
    Par Anonymous dans le forum OpenGL
    Réponses: 3
    Dernier message: 06/05/2002, 13h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo