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

Delphi Discussion :

pour spécialiste du Glisser_Déposer, OnDragOver, OnDragDrop


Sujet :

Delphi

  1. #1
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut pour spécialiste du Glisser_Déposer, OnDragOver, OnDragDrop
    Bonjour à tous, j'essaie d'utiliser vos conseils pour avancer peu à peu.
    je désire créer un quizz qui se présente sous la forme d'un panel, appelé "surface_images, sur lequel j'ai disposé 4 cases de type recept, classe directement héritée des Tlabel, de 150x150.
    Je dépose ensuite à la création de la fiche, 4 images de 150x150, que je dois déposer sur les 4 cases.
    (Un énoncé suivra et un dépot ordonné sur les cases permettra de valider ou pas la réponse ainsi réalisée)
    .
    Il faut donc pouvoir glisser_déposer les images UNIQUEMENT sur les cases. Si le dépôt se fait ailleurs sur le panel, l'image réintègre sa position initiale.Nom : interface.jpg
Affichages : 846
Taille : 70,5 Ko

    Comme la gestion du curseur de la souris se fait par rapport à la fiche, et que sur le panel, les coordonnées sont relalives au panel, je tiens compte du décalage en faisant intervenir les coordonnées du panel (8,208) pour positionner l'image quand je la fais glisser, afin qu'elle suive le curseur de la souris.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm8.surface_imagesDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);  // OnDragOver
    begin
    if source is Timage then Accept := true; // Si on fait glisser une image
     
    if sender = surface_images then // On déplace l'image uniquement si on est sur le panel
       begin
       Timage (source).Left := mouse.CursorPos.X - decalage_x ;
       Timage (source).Top := mouse.CursorPos.Y - decalage_y  ;
           end;
    end;
    Le curseur est alors centré sur l'image, ce que je souhaite!!
    Nom : dragover_centré.jpg
Affichages : 803
Taille : 14,8 Ko

    Hélas un problème important demeure car, quand je fait glisser, le "ondragover", appliqué sur le panel, ne s'applique que lorsque le curseur touche ce dernier et donc, l'image reste immobile tant que le curseur se déplace sur l'image elle-même, puis quand il en sort, touchant le panel, le "ondragover s’exécute, et l'image se centre immédiatement sur le curseur, puis s'immobilise à nouveau, jusqu'au prochain contact direct sur le panel. Le fonctionnement est donc saccadé et désagréable, donc pas satisfaisant...
    (Si j'affecte le "ondragover" sur l'image également, le déplacement est à nouveau fluide mais le lâcher sur les cases est bien sur inopérant...)



    J'ai donc créé un décalage en plus, pour que le curseur reste en contact sur le panel sans toucher l'image :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm8.surface_imagesDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);  // OnDragOver
    begin
    if source is Timage then Accept := true; // Si on fait glisser une image
     
    if sender = surface_images then // On déplace l'image uniquement si on est sur le panel
       begin
       Timage (source).Left := mouse.CursorPos.X - decalage_x ;
       Timage (source).Top := mouse.CursorPos.Y - decalage_y +90  ;
           end;
    end;
    le décalage de 90 place le curseur au-dessus de l'image et cela fonctionne.

    Nom : dragover_décalé.jpg
Affichages : 811
Taille : 20,5 Ko

    Deux problèmes subsistent cependant :
    1/ la solution est peu élégante car l'image reste au-dessous du curseur et le résultat n'est finalement que partiellement atteint.
    2/ Même si le déplacement de l'image est stoppé quand le curseur sort du panel, en position basse, l'image a donc déjà disparu quand le curseur est trop bas, et on ne peut pas la récupérer car elle est alors invisible....


    Voici donc ma question :

    Pendant le déplacement souhaité, le curseur est en contact uniquement au dessus de l'image, car elle doit rester centrée sur ce dernier et suivre son déplacement.
    Comment donc, rendre possible la gestion du "OnDragOver" de mon panel, puisque l'image "fait écran" entre le curseur et le panel??

    Merci pour vos idées si vous gérez facilement cela??? Désolé pour la longueur mais j'essaie d'être précis..

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

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 507
    Points : 2 779
    Points
    2 779
    Billets dans le blog
    10
    Par défaut
    Le traitement ne passe pas par les fonctions de DRAG/Drop. Voici un exemple qui déplace un TShape dont tu peux t'inspirer
    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
     
    unit ex25a;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls;
     
    type
      TForm1 = class(TForm)
        procedure Shape1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure Shape1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormActivate(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
      TTextShape = class (TShape)
      protected
        procedure paint ; override ;
        procedure CMTextChanged ( var Msg:TMessage ) ; message  CM_TextChanged ;
      published
        property Caption ;
      end ;
     
    var
      Form1: TForm1;
      B1 : boolean = false ;
      X1, Y1 : integer ;
      Shape1 : TTextShape ;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Shape1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    var
      x2,Y2 : integer ;
    begin
      x2 := Mouse.CursorPos.X ;
      y2 := Mouse.CursorPos.Y ;
      if b1 and ((x2<>x1) or (y2<>y1)) then
      begin
        Shape1.Top := Shape1.Top + (Y2 - Y1) ;
        Shape1.Left :=Shape1.Left + (X2 - X1) ;
        x1 := X2 ;
        y1 := Y2 ;
      end ;
    end;
     
    procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      B1 := true ;
      X1 := Mouse.CursorPos.X ;
      Y1 := Mouse.CursorPos.Y ;
    end;
     
    procedure TForm1.Shape1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      B1 := false  ;
    end;
     
    { TTextShape }
     
    procedure TTextShape.CMTextChanged(var Msg: TMessage);
    begin
      invalidate ;
    end;
     
    procedure TTextShape.paint;
    begin
      inherited Paint ;
      with canvas do
      begin
        TextOut ((Width - TextWidth (Caption)) div 2 , (height div 2)-10, Caption) ;
      end ;
     
    end;
     
    procedure TForm1.FormActivate(Sender: TObject);
    begin
      Shape1 := TTextShape.Create(form1) ;
      with Shape1 do
      begin
        Left := 64;
        Top := 24 ;
        Width := 113;
        Height := 105;
        Brush.Color := clwhite;
        Pen.Color := clRed;
     
        Pen.Style := psClear;
        OnMouseDown := Shape1MouseDown;
        OnMouseMove := Shape1MouseMove;
        OnMouseUp := Shape1MouseUp;
        Caption := 'Essai' ;
      end ;
      Shape1.Parent := form1 ;
     
     
     
    end;
     
    end.

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 264
    Points : 41 665
    Points
    41 665
    Billets dans le blog
    64
    Par défaut
    Bonjour,

    Pour moi, il y a presque trop d'informations sauf peut-être l'essentiel la version de Delphi 10.3* et sa "saveur" VCL* ou FMX. *retrouvés via l'autre discussion sur le sujet

    Autant avec FMX je sais faire une "image" de l'élément à déplacer autant en VCL j'ai eu beau essayé en lisant et relisant cet article je n'ai pas réussi à le faire.

    Autre chose qui me perturbe, l'image doit "bouger" avec le curseur ou non ?

  4. #4
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Autre chose qui me perturbe, l'image doit "bouger" avec le curseur ou non ?
    Il me semble bien que c'est ce qu'il avait codé dans un autre post.

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 264
    Points : 41 665
    Points
    41 665
    Billets dans le blog
    64
    Par défaut
    Re,
    En tout cas, voilà ce que cela pourrait donner en FMX
    Nom : Capture.PNG
Affichages : 807
Taille : 64,4 Ko
    L'image ne rendant pas justice au déplacement
    quant au code il est joint dans le zip, une centaine de lignes en comptant les déclarations
    Fichiers attachés Fichiers attachés

  6. #6
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut Merci pour vos pistes!
    Un grand merci aux différents intervenants qui m'ont proposé des conseils pour résoudre ma problématique. Je vais étudier tout ça et je reviendrai peut-être vers vous pour des interrogations qui naitront à ce moment là.

  7. #7
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut problème de Glisser_déposer suite
    bonsoir et tout d'abord, merci pour votre aide.

    J'ai étudié votre code d'assistance qui fonctionne plutôt bien pour le glisser_déplacer.

    Quand j'utilisais dans mon premier code le OnDragDrop, cela permettait de tester, au moment du lâcher, si j'étais au dessus d'une aire de réception, et dans ce cas, de bien aligner mon image dans cette case de dépôt quand je là lachais.

    Avec votre code plus léger et modulable ce qui est mieux, je perds cependant ce bénéfice car au lâcher sur le OnMouseDown, je ne peux pas détecter si je suis sur une aire de réception ou pas...

    1/ Est-il possible de tester de manière "toute faite", si deux objets sont en contact, ou en superposition, même partielle ou dois-je me lancer dans une procédure qui sur le OnMouseDown, testerait la position X et Y de la souris, puis par un balayage lourd des coordonnées des différentes aires de réception, permettrait de détecter si ce lâcher était sur l'une d'elle, et enfin dans ce cas, bien aligner l'image sur la case. Ouf!! Très lourde et mauvaise idée, non?

  8. #8
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par patdu26 Voir le message
    1/ Est-il possible de tester de manière "toute faite", si deux objets sont en contact, ou en superposition, même partielle ou dois-je me lancer dans une procédure qui sur le OnMouseDown, testerait la position X et Y de la souris, puis par un balayage lourd des coordonnées des différentes aires de réception, permettrait de détecter si ce lâcher était sur l'une d'elle, et enfin dans ce cas, bien aligner l'image sur la case. Ouf!! Très lourde et mauvaise idée, non?
    Je pense que tu peux trouver quelque chose de sympa du côté des TRect.
    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       function IntersectsWith(const R: TRect): Boolean;
    N'oublie pas que tu as aussi les fonctions MouseToScreen, ScreenToClient, .. pour convertir les coordonnées de la position de ton curseur par exemple, dans un autre référentiel (celui d'un objet).
    Quand je fais des choses comme ça, j'utilise un papier et un crayon

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 264
    Points : 41 665
    Points
    41 665
    Billets dans le blog
    64
    Par défaut
    Bonjour,

    Quand j'utilisais dans mon premier code le OnDragDrop, cela permettait de tester, au moment du lâcher, si j'étais au dessus d'une aire de réception, et dans ce cas, de bien aligner mon image dans cette case de dépôt quand je la lâchais.
    C'est toujours le cas dans mon code

    Citation Envoyé par patdu26 Voir le message
    je perds cependant ce bénéfice car au lâcher sur le OnMouseDown,
    Ce n'est pas le onMousedown qui le fait, le OnMouseDown permet de déclencher l'opération de drag et créer l'image "fantôme".

    Je ne peux pas détecter si je suis sur une aire de réception ou pas...
    En fait c'est l'évènement onDragOver des zones de réceptions qui suffit, en plus cet évènement est partagé par toutes les zones de réceptions (donc : un seul code en utilisant sender pour savoir duquel il s'agit)

    Est-il possible de tester de manière "toute faite", si deux objets sont en contact
    dans mon code c'est impossible puisque le drag n'est accepté que si la zone de réception est vide TRectangle(Sender).Fill.Kind=TBrushKind.SolidAprès s'il s'agit de remplacer une image par une autre dans une même zone, sans avoir à effacer la zone au préalable (ce que fait le onDblClick) c'est légèrement plus compliqué mais guère

    Il faut modifier l'évènement onDragOver
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm106.Rectangle1DragOver(Sender: TObject; const Data: TDragObject;
      const Point: TPointF; var Operation: TDragOperation);
    begin
    <s>// if TRectangle(Sender).Fill.Kind=TBrushKind.Solid then 
    </s>  Operation:=TDragOperation.Move;
    end;
    Si le OnDblClick est "gênant" rien n'empêche de mettre un bouton dans les rectangles de réception
    Nom : Capture.PNG
Affichages : 757
Taille : 25,2 Ko
    les boutons (des TSpeedbuttons, stylelookup= stoptoolbutton) ont l'évènement onclick=le onDblClick déjà cité mais rectifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TForm106.Rectangle1DblClick(Sender: TObject);
    var aRectangle : TRectangle;
    begin
    if Sender is TRectangle
       then aRectangle:=Sender as TRectangle
       else aRectangle:=TFMXObject(Sender).Parent as TRectangle;
      aRectangle.Fill.Bitmap.Bitmap.Clear(TAlphaColors.White);
      aRectangle.Fill.Kind:=TBrushKind.Solid;
    end;
    Bien aligner l'image sur la case.
    En fait, dans le code présenté, l'image sera toujours centrée, c'est pour cela qu'il y a un code de "retaillage"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     aRectangle.Fill.Bitmap.Bitmap:=TImage(Data.Source).Bitmap; // image taille réelle, celle du fichier 
     aRectangle.Fill.Bitmap.Bitmap.Resize(Round(aRectangle.Width),Round(aRectangle.Height)); // image de la taille du rectangle
    Quelques "contorsions" supplémentaires pour respecter l'image de début (les numéros de cases)
    Nom : Capture.PNG
Affichages : 735
Taille : 2,7 Ko Nom : Capture.PNG
Affichages : 739
Taille : 9,7 Ko
    ajout de 2 TText, on peut jouer sur l'opacité ou la couleur de fonte, l'important un Hittest:=false;

    En débordant du drag drop :
    Dans l'optique d'un quizz il faudra bien sûr stocké l'information de contenu mais les propriétés tag, tagstring, tagobject peuvent répondre à ce problème à peu de frais.
    Plus compliqué, si une image ne peut être sélectionnée qu'une seule fois c'est néanmoins possible en utilisant une collection ou liste quelconque

  10. #10
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut merci pour l'aide... suite..
    Mon message d'hier à 20h26 commentait l'aide de ALWEBER du 08 mars à 8h34.

    Pour Blonde et SergioMaster, qui vous êtes intercalés depuis, je commence à éplucher votre aide et vos idées.

    Je reviendrais vers vous également si j'ai des difficultés à vous suivre, car vous avez beaucoup plus de recul que moi dans le domaine

    Un grand merci à tous à nouveau, car c'est motivant de découvrir des approches nouvelles, souvent plus fluides et cohérentes!

  11. #11
    Membre confirmé Avatar de blonde
    Femme Profil pro
    Développeur Delphi
    Inscrit en
    Septembre 2003
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Delphi

    Informations forums :
    Inscription : Septembre 2003
    Messages : 278
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par patdu26 Voir le message
    Un grand merci à tous à nouveau, car c'est motivant de découvrir des approches nouvelles, souvent plus fluides et cohérentes!
    Et c'est plaisant de lire des personnes qui sont motivées avec des projets sympas !

  12. #12
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 264
    Points : 41 665
    Points
    41 665
    Billets dans le blog
    64
    Par défaut
    Citation Envoyé par blonde Voir le message
    Et c'est plaisant de lire des personnes qui sont motivées avec des projets sympas !
    C'est sûr, des projets de ce type, ça permet de me détendre entre deux prises de tête
    Des petits challenges j'en veux bien 1 ou 2 par semaine histoire de montrer l'étendue de FMX
    En plus cela me permet d'aller hors des sentiers de l'informatique de gestion. Cela dit, je reste encore hermétique à la 3D

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

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 507
    Points : 2 779
    Points
    2 779
    Billets dans le blog
    10
    Par défaut
    SI tu veux j'ai a peu près terminé l'exemple que tu proposais

  14. #14
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut pour SergioMaster
    Merci pour ce code qui apporte beaucoup d'éléments et qui fonctionne très bien!
    Voici quelques interrogations au niveau d'un débutant:

    1/ Votre code est en FMX plutôt que VCL, vous avez déjà soulevé cette nuance dans mes précédents messages. J'ai vu un article de comparaison mais je n'ai pas assez de hauteur pour vraiment "sentir" la portée de ce choix de départ. FMX est une orientation nouvelle qui permet une compilation vers différents OS, c'est ça?
    En tant que débutant, ai-je intérêt à partir directement vers le FMX, avec peu d'expérience à mon niveau, cela est-il d’important?

    J'en reviens à votre code en ZIP.

    2/ Quand je neutralise le redimensionnement par "//", comme un commentaire, je suis étonné car une petite partie de l'image seulement, apparait sur le rectangle de réception et elle semble être 4xplus grande que le rectangle d'accueil, alors que dans le code, les dimensions sont pratiquement identiques.
    Pourquoi une telle différence sans "retaillage" à l'exécution?

    3/ Quand l'image en déplacement est détectée au-dessus du rectangle de réception, les bords de celui-ci changent de couleurs (et tant mieux). Je ne vois pas cette démarche dans le code, est-elle automatique dans l'utilisation du "DragDrop"?

    4/ Quand je regarde les arguments du "DragOver", (none, link, copy, move), je vois qu'il n'entraine pas un comportement mais, semble-t-il, sont informatifs, en inscrivant juste un mot à l'usage de l'utilisateur (toucheF1)
    Or, je vois bien que cela a une incidence puisque le comportement du "DragOver" change si une image est déjà présente sur le rectangle, et que le dépôt d'une autre est impossible... De plus, pas de mot affiché, ni "none", ni "move".... Comment interpréter cela?

    5/ Si je neutralise la ligne 49 "AND TPlatformServices.Current.SupportsPlatformService(IFMXDragDropService, Svc)", il y a une interruption à l'exécution.
    Dois-je comprendre que cette ligne "vérifie" que le service "DragDrop" est susceptible de fonctionner et l'affecte à SVC de la ligne 55?
    Que représente SVC? "BeginDragDrop" est-il une propriété de SVC?

    Voila quelques questions de plus. Désolé si cela vous semble puéril

  15. #15
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut A l'intention d'ALWEBER
    Bonsoir, merci d'avoir travailler sur mon cahier des charges.
    Je serais bien sur intéressé de voir votre interprétation de problème pour pouvoir le décortiquer et le digérer peu à peu.
    Merci à vous et bonne soirée!

  16. #16
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 264
    Points : 41 665
    Points
    41 665
    Billets dans le blog
    64
    Par défaut
    Bonjour,

    Citation Envoyé par patdu26 Voir le message
    Voilà quelques questions de plus. Désolé si cela vous semble puéril
    Ce sont des bonnes questions

    Citation Envoyé par patdu26 Voir le message
    Votre code est en FMX plutôt que VCL, vous avez déjà soulevé cette nuance dans mes précédents messages. FMX est une orientation nouvelle qui permet une compilation vers différents OS, c'est ça?
    FMX pour faire court est effectivement la "version" multi OS de Delphi ou plus exactement permet d'obtenir des exécutables pour chaque OS (Windows,Mac OSX, IOS, Android et même Linux)
    Citation Envoyé par patdu26 Voir le message
    En tant que débutant, ai-je intérêt à partir directement vers le FMX, avec peu d'expérience à mon niveau, cela est-il d’important?
    De mon point de vue de "vieux" développeur pro, je tendrai à dire oui, j'étaye :
    • tout d'abord il y a la possibilité des autres OS que Windows (notez bien le "possibilité")
    • La différence du "mode de pensée" entre VCL et FMX par exemple en FMX un composant, quelqu' il soit (ou presque) peut être parent d'un ou plusieurs autres composants, les propriétés du parent (i.e couleurs, mouvements, échelle etc.. seront appliquées aux enfants). À noter que cette différence rebute beaucoup d'anciens Delphiistes ou programmeurs Pascal "pur"
    • FMX offre des possibilités d'ajout d'effets et d'animations
    • FMX permet la 3D (cela étant je suis un noob dans ce domaine @gbgreg)

    Ce sont ces arguments (et d'autres qui ne me viennent pas à l'esprit) qui me poussent à dire oui à un débutant autodidacte. S'il vous faut d'autres arguments sachez que développeur Delphi depuis le siècle dernier toutes mes applications (en gros un énorme ERP) seront migrées au cours de ces prochaines années (choix perso et multi-os oblige)

    Le Code
    Merci pour ce code qui apporte beaucoup d'éléments et qui fonctionne très bien!
    Il a été fait "à la va-vite" avec un gros avantage, je travaille de plus en plus avec FMX (à tel point que je commence à trouver VCL freinant) et j'avais déjà connaissance des opérations de Gillser déposer en ce domaine. Je n'ai lu que les grandes lignes du "cahier des charges" pour ne m'intéresser qu'à cette fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Quand je neutralise le redimensionnement par "//", comme un commentaire, je suis étonné car une petite partie de l'image seulement, apparait sur le rectangle de réception et elle semble être 4xplus grande que le rectangle d'accueil, alors que dans le code, les dimensions sont pratiquement identiques. Pourquoi une telle différence sans "retaillage" à l'exécution?
    En fait elles semblent identiques, mais ce n'est pas le cas, les images de gauche sont des images prises un peu au hasard sur mon disque, des fichiers png de tailles diverses. Si vous regardez dans les propriétés de ces images vous y verrez une propriété wrapmode = fit (j'aurais pu mettre Stretch mais les résultats auraient été moins bon), jouez avec cette propriété (original vous montrera la taille exacte)

    Quand l'image en déplacement est détectée au-dessus du rectangle de réception, les bords de celui-ci changent de couleurs (et tant mieux). Je ne vois pas cette démarche dans le code, est-elle automatique dans l'utilisation du "DragDrop"?
    Il s'agit d'une propriété (true par défaut) EnableDragHightLight, qui existe pour les composants acceptant le drop

    Quand je regarde les arguments du "DragOver", (none, link, copy, move), je vois qu'il n'entraine pas un comportement mais, semble-t-il, sont informatifs, en inscrivant juste un mot à l'usage de l'utilisateur (toucheF1)
    En fait c'est les "équivalents" FMX de ce que l'on est obligé de faire en VCL (begindrag, enddrag) oui c'est informatif mais peu se révéler utile dans le traitement. J'avoue que je n'ai pas encore eu l'occasion d'utiliser link ou copy, juste move pour accepter et none pour refuser. [NOTE] Après contrôle cela a une incidence sur l'image du curseur au sein de l'image "fantôme". Toutefois none empêche aussi le Drop.

    Or, je vois bien que cela a une incidence puisque le comportement du "DragOver" change si une image est déjà présente sur le rectangle, et que le dépôt d'une autre est impossible... De plus, pas de mot affiché, ni "none", ni "move".... Comment interpréter cela?
    Cela a une incidence sur le comportement du glisser déposer et si vous faites attention, sur l'icône du curseur dans l'image "fantôme"

    Si je neutralise la ligne 49 "AND TPlatformServices.Current.SupportsPlatformService(IFMXDragDropService, Svc)", il y a une interruption à l'exécution.
    Dois-je comprendre que cette ligne "vérifie" que le service "DragDrop" est susceptible de fonctionner et l'affecte à SVC de la ligne 55?
    Oui c'est ça. Qui dit FMX dit possibilité de multiples OS, et les OS ne fonctionnent pas tous de la même manière (l'exemple le plus flagrant les messages). D'où la notion de plateformes. TPlatFormServices.Current permet d'activer le "bon service" en fonction de la plateforme (OS) en cours.
    Beaucoup de chose passent par les services en FMX (une raison de plus d'être "déstabilisé" ?)
    Que représente SVC? "BeginDragDrop" est-il une propriété de SVC?
    SVC c'est ce fameux service, BeginDragDrop une fonction de ce service, celui qui affecte la source (dragdata) et l'image fantôme (DragImage) à l'opération. Si vous avez lu cet article vous avez vu qu'il existe un DragObject en VCL (truc que je n'ai pas réussi à faire fonctionner) ce serait son équivalent FMX.

    En pj. Une autre version du programme (plus de contrôle pour savoir si la zone de réception est remplie, possibilité d'effacer la zone de réception, numérotation des zones de réception), test Quizz
    Fichiers attachés Fichiers attachés

  17. #17
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut Super boulot!
    Merci SergioMaster, pour votre réactivité et vos précisions.

    Des réponses font naitre de nouvelles question bien sur...

    1/ Les objets sont référencés par la lettre majuscule "T" : Tbutton, Tedit, Timage.... Que représente le A des paramètres AFrom, ABitmap?...

    2/ Le type DragObject, doit descendre la classe mère "Object", non? Pour la procedure BeginDragDrop a-t-elle besoin d'un paramètre Data de type DragObject et non simplement Object. Les objets ne sont pas tous "dragables" par défaut?

    3/ j'ai un peu de mal avec les paramètres de "BeginDragDrop".
    Le premier "Self" représente quoi??
    Le second représente L'objet de type TDragObject, réellement déplacé.
    Le troisième représente l'image affichée pendant le déplacement.

    A la ligne 98 on a "DragData.Source := Sender";
    Cela veut dire que l'objet qui sera déplacé contient une copie de Sender et non Sender lui-même? C'est pour cela qu'il apparait toujours à son emplacement pendant qu'une copie se déplace?

    Peut-on le déplacer lui-même afin que chaque image n'apparaisse qu'en un seul exemplaire à l'écran?...

  18. #18
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 264
    Points : 41 665
    Points
    41 665
    Billets dans le blog
    64
    Par défaut
    Bonjour,
    Citation Envoyé par patdu26 Voir le message
    1/ Les objets sont référencés par la lettre majuscule "T" : Tbutton, Tedit, Timage.... Que représente le A des paramètres AFrom, ABitmap?...
    axxxxx c'est en quelque sorte ma signature pour les objets que je crée, c'aurait pu être un wxxxx (pour working), unxxxx (mais un c'est trop long à écrire)

    2
    Là c'est du décorticage de première classe et je ne suis pas sûr d'avoir toutes les réponses.
    Les objets ne sont pas tous "dragables" par défaut?[/QUOTE]
    Le type DragObject, doit descendre la classe mère "Object", non?
    Pour moi, le DragObject, est un objet créé lors du début de l'opération de drag et détruit à la fin, je ne sais pas si cela répond à ce que vous appelez classe mère.
    Pourquoi la procedure BeginDragDrop a-t-elle besoin d'un paramètre Data de type DragObject et non simplement Object.
    un DragObject est un record pas une classe. Regardez dans les sources(un clic droit sur TDragObject devrait vous y conduire).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     TDragObject = record
        Source: TObject;
        Files: array of string;
        Data: TValue;
      end;
    3/ j'ai un peu de mal avec les paramètres de "BeginDragDrop".
    moi aussi, mais encore une fois les sources sont plus claires
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure BeginDragDrop(AForm: TCommonCustomForm; const Data: TDragObject; ABitmap: TBitmap);
    Le premier "Self" représente quoi??
    Donc, la forme.
    Le second représente L'objet de type TDragObject, réellement déplacé.
    Réponse de normand, oui et non, ce n'est pas un objet où pour être plus explicite ce n'est pas l'image posée sur la forme
    Le troisième représente l'image affichée pendant le déplacement.
    Ce que je nomme l'image "fantôme", oui
    A la ligne 98 on a "DragData.Source := Sender";
    Cela veut dire que l'objet qui sera déplacé contient une copie de Sender et non Sender lui-même?
    Un pointeur sur Sender

    C'est pour cela qu'il apparait toujours à son emplacement pendant qu'une copie se déplace?
    En fait l'image ne bouge pas

    Peut-on le déplacer lui-même afin que chaque image n'apparaisse qu'en un seul exemplaire à l'écran?...
    Dans le fil de la discussion, j'avais posé cette question
    Citation Envoyé par SergioMaster Voir le message
    Autre chose qui me perturbe, l'image doit "bouger" avec le curseur ou non ?
    Cela me perturbait car dans ce cas il ne s'agissait de glisser-déposer (sujet du post), mais un "simple" déplacement d'objet comme le fait Alain.
    Avec FMX on pourrait même gérer cela avec des Animations si j'en crois


    Enfin, pour essayer d'en finir, j'ai essayé le programme sur Androïd. Problème il n'y a pas de souris ma question d'adresse aux personnes qui accrocherait ce wagon, comment faire avec les gestes (gestures ) ?
    J'avoue que c'est un domaine que je n'ai jamais abordé voilà pourquoi j'aime me confronter à ce genre de challenge, pour apprendre de nouvelles choses.

  19. #19
    Membre habitué

    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2020
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2020
    Messages : 167
    Points : 162
    Points
    162
    Par défaut une question de plus..
    bonjour à tous,

    je reste pour le moment avec mon code ou le curseur est un peu décalé sur mes images, mais ça marche..

    Je veux instaurer une limite basse de déplacement dans le panel "surface_images.
    Cependant, je le dessine en conception sur le morceau minuscule visible de la fiche, et donc, il prend ses pleines dimensions uniquement quand la fiche est créé, en wsMaximized.
    J'ai bien coché cela dans l'inspecteur d'objet pour Form8 et elle s'affiche directement en grand. J'évalue le niveau bas limite à la ligne 67, à la création de la fiche, et j'ai même répété en code "wsMaximized" jusque avant à la ligne 65.
    J'espèrais donc que le paramètre "surface_image.height" pris en compte serait la taille redimensionnée, et bien non??....

    A quel moment les objets redimensionnés à la taille de form8 acquièrent-ils ces nouvelles valeurs dans la création?

    Peut-on évaluer, simplement à partir d'un dessin en conception, les dimensions réelles des objets redimensionnés en plein écran??

    Il semble impossible de disposer en conception des éléments vers bas et droit, quasiment inutilisable non??

    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
    166
    167
    168
    169
    170
    171
    unit jeudi_05_05;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
      jpeg, vcl.imaging.pngimage, vcl.extctrls, vcl.stdctrls;
     
    type
      TForm8 = class(TForm)
        panneau_bas: TPanel;
        bp_valider: TButton;
        bp_avancer: TButton;
        panneau_haut: TPanel;
        habilitation: TLabel;
        lp_catalins: TLabel;
        surface_images: TPanel;
        Memo1: TMemo;
        Q1: TButton;
        Edit1: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure Q1Click(Sender: TObject);
        procedure surface_imagesDragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
          procedure lacher_sur_recept (sender, source : Tobject ; x, y : integer) ;
     
             private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
      Trecept = class (Tlabel)
      public
        var libre : boolean ;
      end;
    var
      Form8: TForm8;
      recept : array[1..4] of Trecept;
      image : array [1..4] of Timage ;
      largeur_image : integer = 150 ;
      hauteur_image : integer = 150 ;
      decalage_x, decalage_y : integer;
      limite_basse : integer;
     
     
    implementation
     
    {$R *.dfm}
     
     
     
     
     
     
     
     
    {CREATION DE LA FICHE} procedure TForm8.FormCreate(Sender: TObject);
     
    var
    i : integer ;
     
    begin                  // CREATION DES 4 CASES RECEPT
      WindowState := wsMaximized ;
      memo1.Lines[10] :=  inttostr(surface_images.height) ;
       limite_basse := surface_images.Top + surface_images.Height - hauteur_image;
       for   i := 1 to 4 do
             begin
                 recept[i] := Trecept.Create(self) ;
                 with recept[i] do
                              begin
                                 parent := surface_images ;
                                 height := hauteur_image ;
                                 width := largeur_image ;
                                 Transparent := false ;
                                 AutoSize := false ;
                                 color := clWhite;
                                 caption := inttostr (i) ;
                                 font.Height := 130 ;
                                 font.Color := clGrayText;
                                 layout := tlcenter;
                                 alignment := TaCenter;
                                 top := 20 ;
                                 left := 100+50*i+ largeur_image*(i-1);
                                 ondragover := surface_imagesdragover ;
                                 ondragdrop := lacher_sur_recept;
                                 libre := true;
                              end;
             end;
                 decalage_x := surface_images.left + hauteur_image div 2 ;
                 decalage_y := surface_images.top + largeur_image div 2 ;
    end;
     
    {CHARGEMENT DE LA QUESTION ACTUELLE}   procedure TForm8.Q1Click(Sender: TObject);
    var
      i: Integer;
      question :textfile;
      stg : string ;
    begin                       // CHARGEMENT DU TEXTE
     
    AssignFile(question, 'd:\quizz\q1\q1.txt') ;
    reset(question)   ;
    read(question , stg);
    edit1.text := stg ;
           for i := 1 to 4 do
               begin             // CHARGEMENT DES 4 IMAGES
                     image[i] := Timage.Create(self) ;
                     with image[i] do
                          begin
                              Parent := surface_images ;
                               height := 150 ;
                               width := 150 ;
                               top := surface_images.Height - 200 ;
                               left := 100+50 *i + 150*(i-1) ;
                               picture.LoadFromFile('d:\quizz\q1\image'+inttostr(i)+'.png');
                               dragmode := dmAutomatic ;
     
     
     
     
                          end;
               end;
     
    end;
     
    {ON DRAG DRAGOVER générique} procedure TForm8.surface_imagesDragOver(Sender, Source: TObject; X, Y: Integer;State: TDragState; var Accept: Boolean);
    begin
    if (mouse.CursorPos.y) < limite_basse then
      begin
        if (sender = surface_images) or (sender is trecept) then accept:= true; // on peut "drager"
        memo1.Lines[0] := (' mouse_pos_y =  ' + (inttostr(mouse.CursorPos.Y)));
        memo1.Lines[2] := (' limite_basse =  ' + inttostr (limite_basse));
        memo1.Lines[4] := booltostr (accept);
        memo1.Lines[6] :=   inttostr(surface_images.Top)    ;
        memo1.Lines[7] :=    inttostr(surface_images.Height)   ;
        memo1.Lines[8] :=  inttostr(hauteur_image) ;
       Timage (source).Left := mouse.CursorPos.X - decalage_x ;
       Timage (source).Top := mouse.CursorPos.Y - decalage_y +80  ;
           end;
    end;
     
    {ON DRAG DROP générique} procedure Tform8.lacher_sur_recept (sender, source : Tobject ; x, y : integer) ;
    var i : integer ;
     
    begin     // l'image se dépose sur la case
    //showmessage ('je lache une image');
      if trecept (sender).libre = true then
      begin
       // showmessage ('le sender est bien une case, je depose.');
        Timage (source).left := Trecept (sender).left ;
        Timage (source).Top  := Trecept (sender).top ;
        trecept (sender).libre := false;
      end
     
      else     // ou bien l'image retoune sur l'aire de départ
      begin
        // showmessage ('l''image n''est pas au dessus d''une case donc retour sur aire de départ');
        for i := 1 to 4 do
          begin
     
            if source = image[i] then
            begin
              image[i].Left :=  100+50*i + 150*(i-1) ;
              image[i].Top := surface_images.Height - 200 ;
               //showmessage (' break ');
              break;
            end;
          end;
      end;
    end;

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

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 507
    Points : 2 779
    Points
    2 779
    Billets dans le blog
    10
    Par défaut
    Voici l'exemple dont je t'avais parlé
    Nom : Annotation 2020-03-16 174056.png
Affichages : 667
Taille : 18,8 Ko
    Fichiers attachés Fichiers attachés

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

Discussions similaires

  1. Question pour spécialiste oracle
    Par plawde dans le forum Oracle
    Réponses: 2
    Dernier message: 05/08/2016, 12h24
  2. Question pour spécialiste de AcroPDFLib_TLB.pas
    Par colorid dans le forum Composants VCL
    Réponses: 7
    Dernier message: 23/05/2009, 14h41
  3. Pour les spécialistes des Cartes Mères !
    Par zakuli dans le forum Composants
    Réponses: 8
    Dernier message: 04/12/2005, 08h30

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