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 :

Savoir si un composant est caché par un autre


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2010
    Messages
    954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2010
    Messages : 954
    Par défaut Savoir si un composant est caché par un autre
    Bonjour à tous,

    j'ai une fiche "form1" contenant plusieurs composants (Tdbedit,Trichedit,Tlabel...ect) et j'ai programmé leur emplacement sur la fiche manuellement. De ce fait chacun peut mettre n'importe quel composant à n'importe quelle position sur la fiche, maintenant le problème est que si 2 composants se retrouvent dans le même emplacement alors l'un cache l'autre et je voudrais savoir si un composant est caché ou par un autre.

  2. #2
    Membre Expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 522
    Par défaut
    Bonjour,
    qu'entends tu par "manuellement" : tu les poses à la souris depuis l'IDE, ou tu les créés dynamiquement dans ton code ?

    Sinon, il y a la notion de premier plan et d’arrière plan qui modifie l'ordre de superposition

    A+
    Charly

  3. #3
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 540
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 540
    Par défaut
    basiquement dans l'explorateur d'objet si tu as deux TEdit qui sont disposées au même emplacement ça permet de le voir
    Sinon dans le code source également ( je n'ai pas delphi sous la main).

  4. #4
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2010
    Messages
    954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2010
    Messages : 954
    Par défaut
    Bonjour,

    les objets sont crées dynamiquement et l'utilisateur a la possibilité de les placer ou il veut on utilisant la souris, par contre je voudrais faire un contrôle qui m'avertirais si un tel ou tel objet est caché par un autre sur la fiche

  5. #5
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 543
    Billets dans le blog
    10
    Par défaut Une réponse
    Citation Envoyé par chekkal Voir le message
    Bonjour,
    les objets sont crées dynamiquement et l'utilisateur a la possibilité de les placer ou il veut on utilisant la souris, par contre je voudrais faire un contrôle qui m'avertirais si un tel ou tel objet est caché par un autre sur la fiche
    Tu peux vérifier que le conteneur peut contenir l'objet à créer dans le cas d'un TButton dans un Tpanel.
    Autrement tu peux créer un array of TRect et ajouter à chaque création d'objet le Top, Left, Top+Height, Left.Width comme nouvel élément de cet array
    Ensuite tu contrôle avant de créer que les quatre points du composant à créer ne sont pas à l'intérieur d'un des éléments TRect du tableau

  6. #6
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2010
    Messages
    954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2010
    Messages : 954
    Par défaut
    Bonjour,
    Tu peux vérifier que le conteneur peut contenir l'objet à créer dans le cas d'un TButton dans un Tpanel.
    Franchement j'ai pas compris

    Autrement tu peux créer un array of TRect et ajouter à chaque création d'objet le Top, Left, Top+Height, Left.Width comme nouvel élément de cet array
    Ensuite tu contrôle avant de créer que les quatre points du composant à créer ne sont pas à l'intérieur d'un des éléments TRect du tableau
    j'ai bien pensé à ça mais le problème il me faut un tableau "array de 500 à 1000" parce-que on peut crée dynamiquement des milliers d'objet et ensuite à chaque déplacement d'un objet il faut rechercher dans le tableau "array" si il existe les même coordonnées et c'est trés long.

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 096
    Par défaut
    Avant de placer, tu utilises ControlAtPos
    Le receveur de la méthode c'est le conteneur, la TForm un TPanel qui est fourni comme Parent aux contrôles crées dynamiquement
    Le Point c'est la position de la souris obtenu par CursorPos et converti en coordonnées du conteneur via ScreenToClient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    var
      MP: TPoint;
      MC: TControl
    begin
      MP := Form1.ScreenToClient(Mouse.CursorPos);
      MC := Form1.ControlAtPos(MP, False, True);
      if not Assigned(MC) then 
       CreerNouveauControle
      else
        ErreurControleSuperpose
    le code ci-dessus est basé sur la position de la souris
    En réalité, que cela soit au moment du poser le contrôle ou lors du déplacement, il faut utiliser les Quatre coins du control déplacé

    Tu peux aussi utiliser ControlCount \ Controls[], BoundsRect et PtInRect, c'est comme le tableau sauf que cela existe déjà, autant l'exploiter

    Comme gère tu le déplacement de te contrôles ?
    Tu as forcément déjà au besoin de savoir sur quel control tu cliques pour commencer le Drag&Drop
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 543
    Billets dans le blog
    10
    Par défaut Un exemple
    Voici un exemple que tu pourra adapter à ta convenance. Si tu veux que j'éclaircisse des points c'est possible :
    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
     
    unit ex01a;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
      Ar1: Array of TRect;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      i1: Integer;
      bPossible: boolean;
      bt1: TButton;
      aRect: TRect;
     
      function EntreBornes(X, x1, x2, Y, y1, y2: Integer): boolean;
      begin
        result := (X > x1) and (X < x2) and (Y > y1) and (Y < y2);
      end;
     
    begin
      bPossible := true;
      bt1 := TButton.Create(self);
      bt1.Top := Y;
      bt1.Left := X;
      aRect.Top := Y;
      aRect.Left := X;
      aRect.Bottom := Y + Button1.Height;
      aRect.Right := X + Button1.Width;
      if Length(Ar1) > 0 then
      begin
        for i1 := low(Ar1) to high(Ar1) do
        begin
          if EntreBornes(aRect.Left, Ar1[i1].Left, Ar1[i1].Right, aRect.Top,
            Ar1[i1].Top, Ar1[i1].Bottom) //
            or EntreBornes(aRect.Left, Ar1[i1].Left, Ar1[i1].Right, aRect.Bottom,
            Ar1[i1].Top, Ar1[i1].Bottom) //
            or EntreBornes(aRect.Right, Ar1[i1].Left, Ar1[i1].Right, aRect.Top,
            Ar1[i1].Top, Ar1[i1].Bottom) //
            or EntreBornes(aRect.Right, Ar1[i1].Left, Ar1[i1].Right, aRect.Bottom,
            Ar1[i1].Top, Ar1[i1].Bottom) then
            bPossible := false;
        end;
      end;
      if bPossible then
      begin
        bt1.Parent := Form1;
        SetLength(Ar1, Length(Ar1) + 1);
        Ar1[high(Ar1)] := aRect;
      end
      else
        bt1.Free;
    end;
     
    end.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 939
    Par défaut
    Contrôler les coins n'est pas fiable à 100% puisqu'on on pourrait ajouter un composant plus grand que le contrôle se trouvant en-dessous et utiliser IntersectsWith revient à boucler sur tous les composants

    Il n'y a qu'en passant par des régions qu'on pourrait garantir le non-chevauchement (et à la vitesse max) :
    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
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        FreeRegions :hRGN;
      public
        function CreateControl(const aClass :TControlClass; X, Y :integer; var aControl): boolean;
        function DropControl(aControl :TControl; X, Y :integer) :boolean;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Control :TControl;
    begin
      //Crée la région libre
      FreeRegions := CreateRectRgn(0, 0, ClientWidth, ClientHeight);
     
      CreateControl(TButton, 10, 10, Control);
      Control.SetTextBuf('Ok');
     
      CreateControl(TLabel, 10, 30, Control);
      Control.SetTextBuf('Pas ok');
     
      CreateControl(TPanel, 10, 40, Control);
      Control.SetTextBuf('Ok');
    end;
     
    function TForm1.CreateControl(const aClass :TControlClass; X, Y :integer; var aControl): boolean;
    begin
      TControl(aControl) := aClass.Create(Self);
      Result := DropControl(TControl(aControl), X, Y);
     
      if Result
      then TControl(aControl).Parent := Self
      else FreeAndNil(aControl);
    end;
     
    function TForm1.DropControl(aControl: TControl; X, Y: integer): boolean;
    var
      Bounds :TRect;
      RC, RF :hRgn;
     
    begin
      Bounds := aControl.BoundsRect;
      Bounds.SetLocation(X, Y);
     
      //Crée la région du contrôle
      RC := CreateRectRgn(Bounds.Left, Bounds.Top, Bounds.Right, Bounds.Bottom);
     
      //Crée l'intersection avec la région "free"...
      RF := CreateRectRgn(0, 0, 0, 0);
      CombineRgn(RF, RC, FreeRegions, RGN_AND);
     
      //...qui doit être égale à la région du contrôle
      Result := EqualRgn(RF, RC);
     
      if Result then
      begin
        aControl.BoundsRect := Bounds;
        CombineRgn(FreeRegions, RC, FreeRegions, RGN_XOR);
      end;
     
      DeleteObject(RC);
      DeleteObject(RF);
    end;

  10. #10
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 543
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Contrôler les coins n'est pas fiable à 100% puisqu'on on pourrait ajouter un composant plus grand que le contrôle se trouvant en-dessous et utiliser IntersectsWith revient à boucler sur tous les composants
    end;
    Ma réponse était effectivement une ébauche de solution. Elle peut être complétée et ce n'est pas la seule comme tu l'exprime dans ton post

  11. #11
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 938
    Billets dans le blog
    6
    Par défaut
    Pour toutes ces questions, Andnotor est en quelque sorte le régional de l'étape !
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  12. #12
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2010
    Messages
    954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2010
    Messages : 954
    Par défaut
    J'ai réussi à régler le problème avec cette méthode
    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
    procedure TForm11.P1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
            leftinitial:=Twincontrol(Sender).left;
            topinitial:=Twincontrol(Sender).top;
            heightinitial:=Twincontrol(Sender).height;
            widthinitial:=Twincontrol(Sender).width;
     
    end;
     
    procedure TForm11.P1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      I: Integer;
      OBJS,OBJC:Tcontrol;
      s:shortstring;
    begin
          objs:=Tcontrol(sender);
          for I :=0 to form11.controlcount-1 do
          begin
                 objc:=form11.Controls[i];
                 if (objs<>objc)and(objc.Visible)and
                 (((objs.left>=objc.Left)and(objs.top>=objc.top)and(objs.left+objs.width<objc.Left+objc.Width)and(objs.top+objs.height<objc.top+objc.height))or
                  ((objs.left<=objc.Left)and(objs.top<=objc.top)and(objs.left+objs.width>objc.Left+objc.Width)and(objs.top+objs.height>objc.top+objc.height)))
                  then
                  begin
                          objs.left:=leftinitial;
                          objs.top:=topinitial;
                          objs.height:=heightinitial;
                          objs.width:=widthinitial;
     
                  end;
     
          end;
     
    end;
    ainsi l'objet ne sera pas placé dans un coin ou il peut être caché par un autre objet ou lui même caché un objet. Je vous remercie beaucoup pour vos réponses.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Savoir si une fenêtre est recouverte par d'autres
    Par baloub dans le forum VB.NET
    Réponses: 5
    Dernier message: 29/05/2016, 03h02
  2. Comment savoir si un champ est compteur par req
    Par nanou9999 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 14/09/2006, 12h18
  3. Savoir si un composant est installé dans la VCL...
    Par delphi-fan dans le forum Composants VCL
    Réponses: 2
    Dernier message: 16/01/2006, 21h25
  4. [C#] Savoir si un fichier est caché
    Par Oberown dans le forum C#
    Réponses: 1
    Dernier message: 19/12/2005, 17h06
  5. Réponses: 4
    Dernier message: 15/12/2003, 17h46

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