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

Composants VCL Delphi Discussion :

Déplacement de Composant


Sujet :

Composants VCL 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 Déplacement de Composant
    Bonsoir tout le monde.

    J'essai de faire déplacer des panels qui sont enfant d'un strinGgrid selon le scroll horizontale.
    Voilà mon 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
    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, ExtCtrls, ComCtrls, StdCtrls;
     
    type
      TForm1 = class(TForm)
        PageControl1: TPageControl;
        TabSheet1: TTabSheet;
        Panel1: TPanel;
        Panel2: TPanel;
        StringGrid1: TStringGrid;
        Edit1: TEdit;
        Edit2: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure StringGrid1TopLeftChanged(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
     
    var
      Form1: TForm1;
      Panel : Tpanel;
      MemoRow : Integer;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    Var
    i: Integer;
    begin
      StringGrid1.colCount := 63;
      StringGrid1.RowCount := 63;
      StringGrid1.DefaultColWidth := 20;
      StringGrid1.DefaultRowHeight := 20;
      For i:=1 to 62 do
      Begin
        StringGrid1.Cells[i,0] := IntToStr(i);
        StringGrid1.Cells[0,i] := IntToStr(i);
      end;
     
    Panel := TPanel.Create(Self);
    Panel.Parent := Self.StringGrid1;
    Panel.Name := 'ici1';
    Panel.Caption := 'ici1';
    Panel.Height := 20;
    Panel.Width := 30;
    Panel.Left := StringGrid1.ColWidths[1]*2;
    Panel.Top := StringGrid1.DefaultRowHeight;
     
    Panel := TPanel.Create(Self);
    Panel.Parent := Self.StringGrid1;
    Panel.Name := 'ici2';
    Panel.Caption := 'ici2';
    Panel.Height := 20;
    Panel.Width := 30;
    Panel.Left := StringGrid1.ColWidths[1]*10;
    Panel.Top := StringGrid1.DefaultRowHeight*2;
     
    Panel := TPanel.Create(Self);
    Panel.Parent := Self.StringGrid1;
    Panel.Name := 'ici3';
    Panel.Caption := 'ici3';
    Panel.Height := 20;
    Panel.Width := 30;
    Panel.Left := StringGrid1.ColWidths[1]*5;
    Panel.Top := StringGrid1.DefaultRowHeight*5;
     
     
    MemoRow := StringGrid1.LeftCol;
     
    end;
     
    procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject);
    Var
    OldRow : Integer;
    begin
     
      oldRow := StringGrid1.TopRow;
      if oldRow > MemoRow then
        Panel.Top := Panel.Top - StringGrid1.DefaultRowHeight
      else
        Panel.Top := Panel.Top + StringGrid1.DefaultRowHeight;
     
     
      MemoRow := oldRow;
      StringGrid1.Refresh;
    end;
     
    end.
    J'ai fais simple pour la création dynamique des panels. (En réalité je fais cela dans une boucle et je renseigne plus de paramètre).

    Le but de l'opération est que si je descend ou monte à l'aide de l'ascenseur, il faut que les objets enfant du StringGrid suivent proportionnellement.
    Donc à un moment ils disparaissent vers le haut ou vers le bas et réapparaissent etc...


    J'ai 2 problèmes :
    Le premier : Si vous utiliser les petits fleches noires du bas ou du haut Horizontale, seul le dernier Panel bouge et pas les 2 autres. Si j'essai de détecter les composants par components count, alors la le TOP des Panels est multiplié par 3.
    Est-il possible de faire ce que je cherche ? Déplacer les 3 Panels en même temps sachant qu'ils ont un TOP différent ?

    Le deuxième : Lorsque l'on clique sur les petits fleches noires du StrinGrid le déplacement est normale (hors Problemes 1) mais si on clique au milieu de la bar le déplacement le top des composants devient incohérent. Je n'arrive pas a trouver la bonne formule qui me garantirais le placement correcte des composants Enfants.

    Peut-être je fais une enorme erreur, n'hésiter pas de me dire si c'est idiot de ma part de faire cela !!!

    Merci de votre aide.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Je ne suis pas sûr que l'utilisation d'un StringGrid soit le plus adapté.

    Cepandant tu devrait essayer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Panel.BoundsRect := StringGrid.CellRect[aCol, aRow];

  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
    Bonjour AndNotOr

    J'ai mis ta proposition sous cette forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Panel := TPanel.Create(Self);
    Panel.Parent := Self.StringGrid1;
    Panel.Name := 'ici3';
    Panel.Caption := 'ici3';
    Panel.Height := 20;
    Panel.Width := 120;
    //Panel.Left := StringGrid1.ColWidths[1]*5;
    //Panel.Top := StringGrid1.DefaultRowHeight*5;
    Panel.BoundsRect := StringGrid1.CellRect(5,5);
    Juste pour esseayer.

    Le problème cest que le Panel.Width n'ai pas respecté, la taille du panel est égale à la taille de la cellule. Tu le mettrais où le Panel.BoundsRect ?


    Tu dis que ce n'ai pas justicieux de prendre le StringGrid pour faire cela, a quoi pensez tu ?

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Le BoundsRect va setter la position et les dimensions du panel à la taille et positionnement de la cellule en une seule opération.

    Maintenant, il est clair que la cellule devrait avoir la taille finale souhaitée. Sinon tu dois t'amuser avec des modulos pour déterminer le TopLeft de la bonne cellule en fonction du facteur d'échelle (Panel/Cellule).

    Si le StringGrid sert uniquement à positionner les panels, tu devrais plutôt utiliser un TPanelGrid (en D2007) ou un TScrollBox (en D7). Les scrollings seraient ainsi gérés automatiquement.

    Dans le cas du TScrollBox, tu gères toi-même des lignes et des colonnes "virtuelles".

    Voici un exemple complet. Crée un nouveau projet, pose un TScrollBox et remplace le contenu de l'unité par 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
    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls;
     
    type
      TForm1 = class(TForm)
        ScrollBox1: TScrollBox;
        procedure FormCreate(Sender: TObject);
      public
        function CreatePanel(aCol, aRow :integer) :TPanel;
      end;
     
    var
      Form1: TForm1;
     
    const
      PanelSize :TPoint = (x:120; y:20);  //Taille des Panels
     
    implementation
     
    {$R *.dfm}
     
    { TForm1 }
     
    function TForm1.CreatePanel(aCol, aRow: integer): TPanel;
    begin
      Result := TPanel.Create(ScrollBox1);
      Result.Parent := ScrollBox1;
      Result.Left   := aCol *PanelSize.X;
      Result.Top    := aRow *PanelSize.Y;
      Result.Width  := PanelSize.X;
      Result.Height := PanelSize.Y;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Col :Integer;
      Row :Integer;
    begin
      for Col := 0 to 61 do
        for Row := 0 to 61 do
          CreatePanel(Col, Row);
    end;
     
    end.

  5. #5
    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
    Merci pour tes réponses et proposition.

    Alors j'ai bien compris avc ton exemple l'avantage ici de placer les panels dans un scroolbox parent.

    Mais si tu veux je me sert du StringGrid pour plusieur raison
    - avoir des ligne et colonne fixed dans lequel je mets de titre
    - pour gere la position exxct de la souris pour permettre une saisie de tache, qui genere un Panel dont la principal utilisation est l'apparence d'une tache.

    regarde cela :


    Là tu as le StringGrid avec colonne et ligne, et par dessus des taches (colorées) qui sont en fait des PAnels (c'est beaucoup plus beau avec la verison acuelle hihihi).
    Mais je limite le nombre de ligne à 22 car si je laisse à l'infini je ne peut pas faire remonter mes panels ou l'inverse avec le scrollVert.

    Qu'est-ce que je peux faire ?

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Ok, je comprend mieux

    La première chose, remplace tes TPanel par des TShape. Tu y gagneras en rapidité. Seul le Caption devra être géré manuellement (avec DrawText pour un centrage).

    Ensuite, ne gère que la cellule 1 (lundi). Rien ne t'empêche de dessiner toute la ligne sur l'événement d'une seule cellule.

    Ne t'occupe pas des scrollbars. A la repeinture de la cellule 1 (OnDrawCell) Rect devrait te donner le positionnement correct (Top/Left).

    Il y aura tout de même une petite boucle à faire pour savoir si la cellule est visible ou non et le cas échéant, masquer le Panel (Shape).

    La taille du Shape (Panel) à un rapport Pixel/heure connu. Profites-en et ne t'occupe pas des cellules.

    Mais personnellement, je n'utiliserais pas du tout d'objet et ne gérerais que la peinture des cellules dans la couleur que je veux et le OnSelect ou un MouseDown pour déterminer si je suis sur une zone définie (occupée) et pour quelle personne

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Voilà un exemple.

    Crée un nouveau projet et remplace le contenu de l'unité par ceci (Le grid est créé dynamiquement):
    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids;
     
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        Grid :TStringGrid;
        procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
        procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
        procedure DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    const
      ActivityColor : array [1..3] of TColor = (clGreen, clYellow, clRed);
     
    //Simulation base de données
    type
      TTimeTable = record
        Name      :string;
        StartDay  :integer;  //1 à 6  (Lundi à samedi)
        StartTime :integer;  //0 à 23 (24 heures)
        EndDay    :integer;  //1 à 6  (Lundi à samedi)
        EndTime   :integer;  //0 à 23 (24 heures)
        Activity  :integer;  //Vacances, absence, etc.
      end;
     
    const
      //Ajoute plus de ligne pour le test d'un scroll vertical
      TimeTable : array [0..2] of TTimeTable = (
        (Name :'User 1'; StartDay :2; StartTime :0; EndDay :5; EndTime :23; Activity:1),
        (Name :'User 2'; StartDay :3; StartTime :10; EndDay :3; EndTime :12; Activity:2),
        (Name :'User 3'; StartDay :2; StartTime :8; EndDay :2; EndTime :19; Activity:3)
        );
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i: Integer;
    begin
      //Création dynamique du grid
      Grid := TStringGrid.Create(Self);
      with Grid do
      begin
        Parent           := Self;
        Align            := alClient;
        ColCount         := 6 *24 +FixedCols; //6 jours * 24h +1 titre
        RowCount         := High(TimeTable) +FixedRows +1;
        DefaultColWidth  := 3;
        DefaultRowHeight := 20;
        ColWidths[0]     := 60;
        Options          := Options -[goVertLine];
        OnDrawCell       := DrawCell;
        OnMouseMove      := MouseMove;
        OnMouseUp        := MouseUp;
     
        //Entête de ligne
        for i := 0 to High(TimeTable) do
          Cells[0, i +FixedRows] := TimeTable[i].Name;
      end;
    end;
     
    //Dessin de la cellule *********************************************************
    procedure TForm1.DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    var
      Index    :integer;
      StartCol :integer;
      EndCol   :integer;
    begin
      if aRow > Grid.FixedRows -1 then
      begin
        Index := aRow -Grid.FixedRows;
     
        if aCol > Grid.FixedCols-1 then
          with TimeTable[Index] do
          begin
            //Colonne jour/heure de début
            StartCol := (StartDay-1) *24 +StartTime;
            //Colonne jour/heure de fin
            EndCol   := (EndDay-1) *24 +EndTime;
     
            if aCol in [StartCol..EndCol] then
            begin
              Grid.Canvas.Brush.Color := ActivityColor[Activity];
              Grid.Canvas.Pen.Color   := Grid.Canvas.Brush.Color;
              Inc(Rect.Right);
              Grid.Canvas.Rectangle(Rect);
            end;
          end;
      end;
    end;
     
    //Mise à jour du Caption (pour info) *******************************************
    procedure TForm1.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    var
      aCol  :integer;
      aRow  :integer;
      Index :integer;
    begin
      Grid.MouseToCell(X, Y, aCol, aRow);
      Index := aRow -Grid.FixedRows;
     
      if aRow > Grid.FixedRows -1
      then Caption := Format('[%s] %d/%d', [TimeTable[Index].Name, aCol, aRow])
      else Caption := 'Pas de sélection';
    end;
     
    //Sélection ********************************************************************
    procedure TForm1.MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      aCol  :integer;
      aRow  :integer;
      Index :integer;
    begin
      //Sélection Jour/heure
      Grid.MouseToCell(X, Y, aCol, aRow);
      Index := aRow -Grid.FixedRows;
     
      if aRow > Grid.FixedRows -1 then
        ShowMessage(format('Utilisateur : %s'#13'Jour : %d'#13'Heure : %dh', [TimeTable[Index].Name, aCol div 24 +1, aCol mod 24]));
    end;
     
    end.

  8. #8
    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
    Je viens de tester ton exemple. C'est claire que dans ce cas précis aucun problème de mouvement de scroll.

    J'avais hésiter de faire tout dessiner par DrawCell et apres vue les evenements que j'avais besoin, j'avais préférer le TPanel.

    Maintenant en vue de ton avant dernier poste, j'ai essayer le TShape j'arrive effectivement au même rendu et c'est plus rapide sans contest. D'ailleur je te remercie de ta lumière car j'avais un à endroit précis (une autre form) une lenteur du à la lecture des enregistrement et à la création dynamique sur 2 STringGrid des TPanels.
    PAr contre sur la page ecran que je t'es mis mes TPAnel utilise cela :
    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
     
            Panel.ParentFont := False;
            Panel.Font.Size := 7;
            Panel.Font.Name := 'Tahoma';
            Panel.Name := 'PANEL' + ADOCalendrier.Fields.Fields[31].AsString;
            Panel.Caption := ADOCalendrier.Fields.Fields[45].AsString;
            Panel.Top := StrToInt(ADOCalendrier.Fields.Fields[28].AsString);
            Panel.left := StrToInt(ADOCalendrier.Fields.Fields[25].AsString);
            Panel.Height := StrToInt(ADOCalendrier.Fields.Fields[22].AsString);
            Panel.Color := clBtnFace;// ADOCalendrier.Fields.Fields[20].AsInteger;
            Panel.Width := StrToInt(ADOCalendrier.Fields.Fields[30].AsString);
            Panel.Parent := Self.StringGridSemaine;
            Panel.PopupMenu := Self.PopupMenu1;
            Panel.OnDblClick := Self.PanelDblClick;
            Panel.OnMouseDown := Self.PanelMouseDown;
            Panel.OnMouseMove := Self.PanelMouseMove;
            Panel.OnMouseUp := Self.PanelMouseUp;
            Panel.ParentBackground := False;
            Panel.Hint := ADOCalendrier.Fields.Fields[23].AsString;
            Panel.ShowHint := True;
            Panel.StartColor := clCream;
            Panel.EndColor := ADOCalendrier.Fields.Fields[20].AsInteger;
    Sur le TShape on a pas Le OnDblClick et le popupMenu par exemple (evidement on pourrais le gere dans les evenements Down, up) mais c'est pas si simple. Donc j'ai pris le TSHape sur un autre apperçu où je ne donne pas accès à ces actions. (merci encore)

    Maintenant revenons à cela :
    Ne t'occupe pas des scrollbars. A la repeinture de la cellule 1 (OnDrawCell) Rect devrait te donner le positionnement correct (Top/Left).

    J'ai pas tout capter sur à vrai dire. Et je n'arrive toujours pas à synthétiser correctement le mouvement du ScrollVert pour que mes (Shape ou panel) suivent le mouvement.


    PS : J'ai mieux compris grace à ton code la notion de rapport Pixel/heure. Merci

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Citation Envoyé par BuzzLeclaire Voir le message
    Sur le TShape on a pas Le OnDblClick et le popupMenu par exemple
    Si on les a Mais ces événements ne sont pas publiés. Il suffit de rédéclarer une classe et de transtyper pour y accéder.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //Les événements Protected seront accessible avec cette subtilité.
    type
      TShapeEx = class(TShape);
     
    //Ensuite où tu crée tes TShape:
      Shape1 := TShape.Create(Self);
      TShapeEx(Shape1).OnDblClick := DBLClick;
      TShapeEx(Shape1).PopupMenu  := PopupMenu;
    Je vais faire quelques essais pour le positionnement et te redonne des nouvelles.

  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
    Re Bonjour,

    en fait comme au départ j'avais fais cela
    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
    type
     
      TRuShape = class(TShape)
        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;
    J'ai ajouté cela sur ma form:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure ShapeDblClick(Sender: TObject);
    Ensuite j'ai fais comme cela (dont un eprocedure que tu connais deja le PAINT

    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
    Procedure TFormVisuJour.ShapeDblClick(Sender: TObject);
    Begin
         showmessage('double Clique');
    end;
     
    procedure TRuShape.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
        Rect.Left := 2;
        Rect.Top := 2;
        Rect.Right := Self.Width-2;
        Rect.Bottom := Self.Height-2;
        self.ParentColor := false;
        Canevas:= TControlCanvas.Create;
        Canevas.Control:= self;
        { Calcul des valeurs RGB pour la couleur courante }
        FStartRGB[0] := GetRValue( ColorToRGB( StartColor ) );
        FStartRGB[1] := GetGValue( ColorToRGB( StartColor ) );
        FStartRGB[2] := GetBValue( ColorToRGB( StartColor ) );
        { Calcul des valeurs à ajouter pour atteindre la couleur de fin }
        FDeltaRGB[0] := GetRValue( ColorToRGB( EndColor )) - FStartRGB[0] ;
        FDeltaRGB[1] := GetgValue( ColorToRGB( EndColor )) - FStartRGB[1] ;
        FDeltaRGB[2] := GetbValue( ColorToRGB( EndColor )) - FStartRGB[2] ;
     
        { Initialisation des dimensions de la bande de couleur }
        aBand.Left :=Rect.Left;
        aBand.Right:=Rect.Right;
        nbtranches:=min(256, Rect.Bottom-Rect.Top);
        { Boucle pour remplir la fiche courante en dégradé }
        With Canevas Do
        Begin
            Pen.Style:=psSolid;
            Pen.Mode:=pmCopy;
            For i:= 0 To nbtranches-1 Do
            Begin
                { Dimensions verticales de la bande }
                aBand.Left :=Rect.Left;
                aBand.Right:=Rect.Right;
                aBand.Top := Rect.Top+Round((Rect.Bottom-Rect.Top)/nbtranches*i);
                aBand.Bottom := Rect.Top+Round((Rect.Bottom-Rect.Top)/nbtranches*(i+1));
     
                { Calcul de la couleur courante }
                FCurrentRGB[0] := (FStartRGB[0] + MulDiv( i , FDeltaRGB[0] , nbtranches )) mod 256;
                FCurrentRGB[1] := (FStartRGB[1] + MulDiv( i , FDeltaRGB[1] , nbtranches )) mod 256;
                FCurrentRGB[2] := (FStartRGB[2] + MulDiv( i , FDeltaRGB[2] , nbtranches )) mod 256;
                { Affichage sur la fiche }
                Brush.color:=RGB(FCurrentRGB[0],FCurrentRGB[1],FCurrentRGB[2]);
                FillRect(aBand);
            End;
          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_WORDBREAK);
            Rect.Top := Rect.Top + Self.Font.Size + 7;
     
            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;
    Et à la création

    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
                    
    ...
                    Shape := TRuShape.Create(StringGridVisuJourBas);
                    Shape.Parent := StringGridVisuJourBas;
                  end;   <= pas d'inquiétude c'est normal
                  With Shape do //Panel do
                  Begin
                    Font.Size := 7;
                    Font.Name := 'Tahoma';
                    Name := 'M' + IntToStr(i) + 'JPANEL' + Fields.Fields[31].AsString;
                    Caption := '';//ADOCalendrier.Fields.Fields[45].AsString;
                    Left := CalculDuLeft+1;
                    Top := CalculDuTop+1;
                    Width := CalculDuWidth-2;
                    Height := CalculDuHeight-2;
                    Color := clBtnFace;// ADOCalendrier.Fields.Fields[20].AsInteger;
                    Hint := Fields.Fields[23].AsString;
                    ShowHint := True;
                    StartColor := clCream;
                    EndColor := Fields.Fields[20].AsInteger;
                    if not xCaptionEcrit then
                    Begin
                      Caption1 := xCaption1;
                      Caption2 := xCaption2;
                      xCaptionEcrit := True;
                    end
                    Else
                    Begin
                      Caption1 := '';
                      Caption2 := '';
                    end;
                  Shape := stRoundRect;
                  OnDblClick := Self.ShapeDblClick;
                  end;
    cela fonctionne tres Bien. Décidement tu as réponse à tout lolol

    Merci je vais voir pour déployer sur mes autres StringGrid.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Merci pour les commentaires

    Alors j'ai fait quelques essais de scroll.

    OnDrawCell permet bien de déplacer le Shape en fonction du Rect.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    begin
      Shape.Left := Rect.Left;
      Shape.Top  := Rect.Top;
    end;
    Le problème est qu'il y a une rémanance de l'image du Shape sur les cellules adjacentes qui étaient partiellement hors écran. (Le DrawCell survient avant le déplacement du Shape et le ClipRect de la cellule est plus petit que sa taille d'où repeinture partielle)

    Il ne reste plus qu'à créer un nouveau composant Grid et gérer le message WM_VSCROLL:
    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, ExtCtrls;
     
    type
      TStringGridEx = class(TStringGrid)
      protected
        procedure WMVSCROLL(var Message :TMessage); message WM_VSCROLL;
      public
        procedure CheckInBounds;
      end;
     
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        Grid :TStringGridEx;
        Shape :TShape;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Grid := TStringGridEx.Create(Self);
      Grid.Parent   := Self;
      Grid.ColCount := 6;
      Grid.RowCount := 20;
      Grid.Align    := alClient;
      Grid.Options  := Grid.Options -[goVertLine];
     
      Shape := TShape.Create(Grid);
      Shape.Parent := Grid;
      Shape.Brush.Color := clRed;
      Shape.Height := Grid.DefaultRowHeight;
      Shape.Width  := Grid.DefaultColWidth *2;
      //Utilisation du Tag pour retrouver la ligne et colonne facilement.
      //Puisque tu as déjà surchargé le TShape, tu peux rajouter 2 propriétés Col Row
      Shape.Tag    := MakeLong(6, 2); //Ligne 6, colonne 2
     
      //Première initialisation
      Grid.CheckInBounds;
    end;
     
    { TStringGridEx }
     
    //Contrôle les lignes visibles
    procedure TStringGridEx.CheckInBounds;
    var
      i   :Integer;
      Col :integer;
      Row :integer;
    begin
      //Liste des Shapes
      for i := 0 to ControlCount -1 do
      begin
        Col := HiWord(Controls[i].Tag);
        Row := LoWord(Controls[i].Tag);
     
        //Cache le Shape si la ligne est masquée ou le positionne
        Controls[i].Visible := CellRect(Col,Row).Top > 0;
        Controls[i].Left    := CellRect(Col,Row).Left;
        Controls[i].Top     := CellRect(Col,Row).Top;
      end;
    end;
     
    //Détection du Scroll
    procedure TStringGridEx.WMVSCROLL(var Message: TMessage);
    begin
      //Exécute le scroll
      inherited;
      //Contrôle les lignes visibles
      CheckInBounds;
      //Force une repeinture pour éliminer la rémanance
      Invalidate;
    end;
    end.
    Mais encore une fois, beaucoup de jonglerie. Penses à te passer d'objet

  12. #12
    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
    Encore Merci,

    Je viens d'essayer ta proposition. C'est encore mieux qu'avant !!!

    Mais (oarcqu'il y à un mais lol) si tu te place dans la cellule audessus du shape et que tu scroll vers le bas puis vers le haut, il redessine que la moitié du shape, c'est comme si il était couper en deux

    pour répondre à ton commentaire
    Mais encore une fois, beaucoup de jonglerie. Penses à te passer d'objet

    Il y a 2 problème :
    Le premier c'est que mon TPanel ou Tshape est retaillable disont que lorsque tu approche la souris sur le bords droite du composant tu clique et tu peux l'étirer, je vois vraiment pas comment avec un dessin Drawcell comment donner cette poossibilité il me faut absolument un Objet.

    La deuxieme raison c'est que mon programme est proche de la fin (enfin il me reste l'impression et la saisie de tâche sur multi salarié et si je refais en pertant d'aucun composant t'imagine le travail de reconstruction à refaire. Enfin cela ne m'arreterais pas si il le fallais !! lol

    PS : Si tu veux je pourrais te monter le prog ? mais je sais pas si j'ai le droit ici de passer juste le prog sans les sources, je voudrais pas être mis à la porte du forum.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Je ne remarque rien avec ma démo

    Essaye avec ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TStringGridEx.WMVSCROLL(var Message: TMessage);
    var
      i   :Integer;
    begin
      inherited;
      CheckInBounds;
      Invalidate;
     
      for i := 0 to ControlCount -1 do
        Controls[i].Invalidate;
    end;

  14. #14
    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
    Il faut utiliser la molette de la souris pour voir le phénomène.


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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    La molette ne génère pas de WM_VSCROLL. Alors traite aussi sont message.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Type
      TStringGridEx = class(TStringGrid)
        ...
        procedure WMMOUSEWHEEL(var Message :TMessage); message WM_MOUSEWHEEL;
        ...
     
    procedure TStringGridEx.WMMOUSEWHEEL(var Message: TMessage);
    begin
      inherited;
      CheckInBounds;
      Invalidate;
    end;

  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
    Purée t'es vraiment excellent !! Purée comment je me prend la tête et toi en 4 ligne tu gere... Pfff sa gonfle....


    Trop bien tes propositions.


    Est-il possible d'éviter le scintillement ? doublebuffer ?

  17. #17
    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 mis cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Grid.DoubleBuffered := True;
    Et encore un grand merci à AndNotOr.

    Je vais essayer maintenant de l'implémenter dans mon programme, je c'est pas par ou commencer mais j'y vais

    Merci de ton implication.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 764
    Points : 13 386
    Points
    13 386
    Par défaut
    Tout le plaisir est pour moi

  19. #19
    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
    Je reviens vers toi AndNotOr sur ta proposition.

    Comment faire si Left n'ai pas une colonne pleine.

    Dison que le left peut trés bien etre en plein milieu de la colonne. Si j'utilise ta proposition tel quel le left est toujours également au début de la colonne.

    j'ai essayer cela mais rien ne fonctionne.
    En Rouge les changements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Shape.Tag    := MakeLong(6, 250); //Ligne 6, colonne 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        //Cache le Shape si la ligne est masquée ou le positionne
        Controls[i].Visible := CellRect(Col,Row).Top > 0;
        Controls[i].Left    := Col;
        Controls[i].Top     := CellRect(Col,Row).Top;
    Donc si je souhaite mettre la shape à 250 du bord je n'y arrive pas.

    Encore un de tes lumières ?

  20. #20
    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
    J'ai fais cela et cela à l'aire de fonctionné

    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
    procedure TStringGridEx.CheckInBounds;
    var
      i   :Integer;
      Col :integer;
      Row :integer;
      xLeft: Integer;
    begin
      //Liste des Shapes
      for i := 0 to ControlCount -1 do
      begin
        Col := HiWord(Controls[i].Tag);
        Row := LoWord(Controls[i].Tag);
        xLeft := Controls[i].Left;
     
        //Cache le Shape si la ligne est masquée ou le positionne
        Controls[i].Visible := CellRect(Col,Row).Top > 0;
        Controls[i].Left    := xLeft;
        Controls[i].Top     := CellRect(Col,Row).Top;
      end;
    end;
    Dans ce cas à quoi sert le Col, faut-il vraiment le garder ou le forcer à 0 ou 1?

    quand pense tu ?

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

Discussions similaires

  1. NetBeans Visual Design: Modifier le pas de déplacement des composants
    Par JerryMouse dans le forum NetBeans Platform
    Réponses: 0
    Dernier message: 20/02/2011, 13h10
  2. Problème de déplacement de composants après updateUI()
    Par phoenix420 dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 28/06/2010, 11h09
  3. Déplacement de composant hérité
    Par gudul dans le forum Delphi
    Réponses: 5
    Dernier message: 19/04/2007, 10h42
  4. [Image] scintillement lors déplacement sur autre composant
    Par lilou77 dans le forum Interfaces Graphiques en Java
    Réponses: 21
    Dernier message: 07/12/2005, 09h27
  5. Déplacement dynamique de composants à l'exécution
    Par tekilx dans le forum Composants VCL
    Réponses: 8
    Dernier message: 05/07/2005, 10h46

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