cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 2013
-
29 juin 2005 à 23:51
florenth -
8 mai 2006 à 21:06
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
C'est sur qu'avec l'automatisation de la création et de la destruction des composants lorsqu'on les place en Design-Time, il y a de quoi douter. Mais comme l'a dit Delphiprog, c'est exactement comme cela que ça se passe.
Au moins, tu pourra supprimer une ligne ou deux dans tes codes !
NB: dans ce cas là, heureusement que la procedure Free() existe parce que si le propriétaire (à ne pas confondre avec le parent ...) essaye de libérer l'objet mais que tu l'a déjà fait toi même : aïe.
++
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 28 avril 2006 à 23:38
Le constructeur de l'objet TDragDropViewer attend un paramètre AOwner du type TComponent.
Dans le code de Florenth, le Owner est la fiche (Self). C'est donc la fiche qui sera chargée de la destruction. Il aurait pû tout autant passer Application comme paramètre.
Si tu passes Nil comme dans ton exemple, alors personne n'est chargé de détruire ton composant, sauf toi !
Il en est de même avec certains composants qui ne possèdent pas de propriétaire comme TStringList par exemple.
Tu ne le vois pas, mais quand tu déposes un composant sur une fiche, cette dernière en devient automatiquement le propriétaire. Est-ce nécessaire de coder la destruction des composants ? Eh bien non, puisque c'est la fiche qui s'en charge automatiquement.
c'est ce que je disais dans mon message : "Tu comptes sur Delphi donc pour libérer l'objet "
Mais on m'a aussi appris ceci :
"même si Delphi le fait il faudrait quand même le faire soi même non ? c'est plus propre"
Effectivement j'ai bien lu dans l'aide que Delphi s'en chargeait mais une des règles fondamentale de Delphi "pour reprendre tes propos" est de libérer les objets que l'on a crées avant de quitter l'application.
Et ce qui m'a turlupiné c'est que Florenth dit : "Dans tous les cas, sa destruction est aussi automatique"
et si l'objet est crée de cette manière :
FDragDrop := TDragDropViewer.Create(Nil);
est-il aussi libéré par l'application?
Je ne faisais que rappeler les règles que normalement Florenth respecte à la lettre. :-)
@+
Cirec
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 28 avril 2006 à 23:00
Un courageux ? Pas tant que ça pour fuir aussi vite ! Le problème est réglé.
Pour répondre à la question de Cirec : la fiche étant le propriétaire du composant créé :
FDragDrop := TDragDropViewer.Create(Self);
Elle est donc chargée de détruire les composants qu'elle possède avant d'être détruite à son tour. C'est une règle fondamentale.
Salut,
je viens de tester ta source alors ça fonctionne la n'est pas le problème.
ce qui m'a interpellé c'est le commentaire qu'il y a dans le OnCreate de la form :
... Dans tous les cas, sa destruction est aussi automatique.
Eclaire moi un peut la dessus.
Tu comptes sur Delphi donc pour libérer l'objet ?
(même si Delphi le fait il faudrait quand même le faire soi même non ? c'est plus propre)
où c'est encore un truc que je n'ai pas capté ?
Et je constate qu'il y encore un courageux qui a mis un 3/10 sans dire pourquoi
Après quelques mois d'inactivité, voici une nouvelle version de mon code.
Ici, on dessine directement sur l'écran et, à part le petit bug signalé plus haut, tout fonctionne à merveille.
Je n'ai rien contre mais je trouve ça moins propre.
De plus le TImage n'étant pas un contrôle fenetré (pas de Handle), il restera derrière les controles fenetres (Boutons, Edits, ...) de la fiche.
Alors qu'avec mon autre solution, celle qui est postée ici (en ton dans le zip) consiste à dessiner sur l'écran. Comme ça, on est sûr que cela passe au dessus de tous les controles.
Mais ta solution marche aussi.
++
Icebird
Messages postés10Date d'inscriptionlundi 14 novembre 2005StatutMembreDernière intervention27 décembre 2005 22 déc. 2005 à 16:14
Juste une petite idée comme çà: Pourquoi ne pas utiliser l'evenement OnDragOver pour afficher une image?
Tu démarre lors du BeginDrag où tu rend visible et charge l'image dans un bête TImage préalablement invisible.
Ensuite dans le OnDragOver de ta Form, tu fait TImage.top:=Y; TImage.Left:=X;
Enfin, dans le OnDragDrop de ta Form, tu rend le TImage invisible, et voilà!
Maintenant, tu peut lier l'evenement OnDragOver et OnDragDrop de ta form sur tous les composants au dessus desquels tu veut dragger quelque chose.
Ca à l'avantage de rester plutot simple à réaliser.
cs_OrsE
Messages postés44Date d'inscriptionsamedi 28 juin 2003StatutMembreDernière intervention20 octobre 2005 30 juin 2005 à 12:58
Oui en fait si je viens sur un phorum delphi c parce que c'est très proche d'un builder, et que la communauté delphi et beaucoup plus active que celle de builder
Mais bon par moment, j'ai un peu de mal, quand il s'agît de pointeur etc...
Mais ton code je vais peut être me servir des CopyMode, je connaissais pas :)
Mais c'est génial ce TDragImageList.
Il y a tous les avatages de mon code sans les inconvénients !!
" mais tous les sources que j'ai trouvé sont en delphi" : mais juste comme ça, tu es sur un forum Delphi ici ;-)
C'est pour quelle raisn que u vas te servir de mon code ? Je n'ai pas bien compris, mais bon, ce n'est pas très important.
cs_OrsE
Messages postés44Date d'inscriptionsamedi 28 juin 2003StatutMembreDernière intervention20 octobre 2005 30 juin 2005 à 12:19
Merci infiniment pour t'être donné autant de mal, je vais surement me servir de ton code à un endroit de ton projet, mais pas pour faire une image qui suit la souris pendant une sorte de drag&drop pour la raison que tu as donné juste au dessus.
En fait je fais pas réelement un drag&drop en utilisant les méthodes de borland (BeginDrag...), je sélectionne quelque cellule dans ma grille, et ensuite je les fait glisser à un autre endroit de ma grille sans utiliser les méthode de borland. Alros pour l'image qui suit la souris, j'ai trouvé une alternative (que j'aime moyennement), j'affiche tout simplement une fenêtre au mosedown que je déplace à chaque onmousemove de ma grille, cette fenêtre est transparente, j'utilise son Canvas pour afficher dessus les cellules qui sont sélectionnées et je l'efface au mouseup. 9a fonctionne bien, mais j'ai eu quelque pb dû au focus qui restait pas sur la bonne fenêtre, j'ai pu les résoudre, mais j'ai peur qu'un jour ça revienne dans un autre cas.
Sinon j'ai vu que pour afficher une image pendant un drag&drop il y avait la classe TDragImageList qui est justement faite pour ça, mais tous les sources que j'ai trouvé sont en delphi, et j'ai un peu de mal à l'adapter en C++. tu peux les trouver ici: http://www.blong.com/Conferences/BorCon2001/DragAndDrop/4114.htm
Sinon le changement du curseur peut aussi être une bonne idée, mais je pense que l'utilisateur se perdrait de voir une image à la place du curseur.
Enfin bon, j'ai du boulot, merci pour tout ;)
Bien vu Delphiprog mais cela pose un problème: les curseurs ne doivent pas dépasser 32x32 pixels.
Par contre je suis preneur d'un petit exemple qui montre comment créer son curseur car je me noie avec CreateCursor() et les ANDMaskArray, XORMaskArray...
Sinon, l'avantage de ta technique, c'est qu'elle surpasse tous les controles (là, c'est limité par le Canvas de la Form, les compos mis dessus masquent l'image).
C'est peut-être une solution à envisager.
Merci de tes remarques toujours très constructives.
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 29 juin 2005 à 23:51
Excellent et bien documenté.
As-tu exploré la voie qui consiste à créer un curseur, à l'enregistrer et à l'utiliser lors des opérations de glisser-déposer ?
Beaucoup de composants possèdent une propriété Cursor dont l'une des valeurs possibles est celle de l'image d'un drag'n drop standard (Cursor = crDrag) ? En utilisant son propre curseur, on est déchargé des problèmes de transparence, de positionnement, etc.
8 mai 2006 à 21:06
Au moins, tu pourra supprimer une ligne ou deux dans tes codes !
NB: dans ce cas là, heureusement que la procedure Free() existe parce que si le propriétaire (à ne pas confondre avec le parent ...) essaye de libérer l'objet mais que tu l'a déjà fait toi même : aïe.
++
28 avril 2006 à 23:38
Dans le code de Florenth, le Owner est la fiche (Self). C'est donc la fiche qui sera chargée de la destruction. Il aurait pû tout autant passer Application comme paramètre.
Si tu passes Nil comme dans ton exemple, alors personne n'est chargé de détruire ton composant, sauf toi !
Il en est de même avec certains composants qui ne possèdent pas de propriétaire comme TStringList par exemple.
Tu ne le vois pas, mais quand tu déposes un composant sur une fiche, cette dernière en devient automatiquement le propriétaire. Est-ce nécessaire de coder la destruction des composants ? Eh bien non, puisque c'est la fiche qui s'en charge automatiquement.
28 avril 2006 à 23:17
c'est ce que je disais dans mon message : "Tu comptes sur Delphi donc pour libérer l'objet "
Mais on m'a aussi appris ceci :
"même si Delphi le fait il faudrait quand même le faire soi même non ? c'est plus propre"
Effectivement j'ai bien lu dans l'aide que Delphi s'en chargeait mais une des règles fondamentale de Delphi "pour reprendre tes propos" est de libérer les objets que l'on a crées avant de quitter l'application.
Et ce qui m'a turlupiné c'est que Florenth dit : "Dans tous les cas, sa destruction est aussi automatique"
et si l'objet est crée de cette manière :
FDragDrop := TDragDropViewer.Create(Nil);
est-il aussi libéré par l'application?
Je ne faisais que rappeler les règles que normalement Florenth respecte à la lettre. :-)
@+
Cirec
28 avril 2006 à 23:00
Pour répondre à la question de Cirec : la fiche étant le propriétaire du composant créé :
FDragDrop := TDragDropViewer.Create(Self);
Elle est donc chargée de détruire les composants qu'elle possède avant d'être détruite à son tour. C'est une règle fondamentale.
28 avril 2006 à 15:48
je viens de tester ta source alors ça fonctionne la n'est pas le problème.
ce qui m'a interpellé c'est le commentaire qu'il y a dans le OnCreate de la form :
... Dans tous les cas, sa destruction est aussi automatique.
Eclaire moi un peut la dessus.
Tu comptes sur Delphi donc pour libérer l'objet ?
(même si Delphi le fait il faudrait quand même le faire soi même non ? c'est plus propre)
où c'est encore un truc que je n'ai pas capté ?
Et je constate qu'il y encore un courageux qui a mis un 3/10 sans dire pourquoi
Voilà c'est tout
@+
Cirec
28 avril 2006 à 15:14
Ici, on dessine directement sur l'écran et, à part le petit bug signalé plus haut, tout fonctionne à merveille.
++
22 déc. 2005 à 20:27
De plus le TImage n'étant pas un contrôle fenetré (pas de Handle), il restera derrière les controles fenetres (Boutons, Edits, ...) de la fiche.
Alors qu'avec mon autre solution, celle qui est postée ici (en ton dans le zip) consiste à dessiner sur l'écran. Comme ça, on est sûr que cela passe au dessus de tous les controles.
Mais ta solution marche aussi.
++
22 déc. 2005 à 16:14
Tu démarre lors du BeginDrag où tu rend visible et charge l'image dans un bête TImage préalablement invisible.
Ensuite dans le OnDragOver de ta Form, tu fait TImage.top:=Y; TImage.Left:=X;
Enfin, dans le OnDragDrop de ta Form, tu rend le TImage invisible, et voilà!
Maintenant, tu peut lier l'evenement OnDragOver et OnDragDrop de ta form sur tous les composants au dessus desquels tu veut dragger quelque chose.
Ca à l'avantage de rester plutot simple à réaliser.
30 juin 2005 à 12:58
Mais bon par moment, j'ai un peu de mal, quand il s'agît de pointeur etc...
Mais ton code je vais peut être me servir des CopyMode, je connaissais pas :)
30 juin 2005 à 12:48
Il y a tous les avatages de mon code sans les inconvénients !!
" mais tous les sources que j'ai trouvé sont en delphi" : mais juste comme ça, tu es sur un forum Delphi ici ;-)
C'est pour quelle raisn que u vas te servir de mon code ? Je n'ai pas bien compris, mais bon, ce n'est pas très important.
30 juin 2005 à 12:19
En fait je fais pas réelement un drag&drop en utilisant les méthodes de borland (BeginDrag...), je sélectionne quelque cellule dans ma grille, et ensuite je les fait glisser à un autre endroit de ma grille sans utiliser les méthode de borland. Alros pour l'image qui suit la souris, j'ai trouvé une alternative (que j'aime moyennement), j'affiche tout simplement une fenêtre au mosedown que je déplace à chaque onmousemove de ma grille, cette fenêtre est transparente, j'utilise son Canvas pour afficher dessus les cellules qui sont sélectionnées et je l'efface au mouseup. 9a fonctionne bien, mais j'ai eu quelque pb dû au focus qui restait pas sur la bonne fenêtre, j'ai pu les résoudre, mais j'ai peur qu'un jour ça revienne dans un autre cas.
Sinon j'ai vu que pour afficher une image pendant un drag&drop il y avait la classe TDragImageList qui est justement faite pour ça, mais tous les sources que j'ai trouvé sont en delphi, et j'ai un peu de mal à l'adapter en C++. tu peux les trouver ici: http://www.blong.com/Conferences/BorCon2001/DragAndDrop/4114.htm
Sinon le changement du curseur peut aussi être une bonne idée, mais je pense que l'utilisateur se perdrait de voir une image à la place du curseur.
Enfin bon, j'ai du boulot, merci pour tout ;)
30 juin 2005 à 10:23
Par contre je suis preneur d'un petit exemple qui montre comment créer son curseur car je me noie avec CreateCursor() et les ANDMaskArray, XORMaskArray...
Sinon, l'avantage de ta technique, c'est qu'elle surpasse tous les controles (là, c'est limité par le Canvas de la Form, les compos mis dessus masquent l'image).
C'est peut-être une solution à envisager.
Merci de tes remarques toujours très constructives.
29 juin 2005 à 23:51
As-tu exploré la voie qui consiste à créer un curseur, à l'enregistrer et à l'utiliser lors des opérations de glisser-déposer ?
Beaucoup de composants possèdent une propriété Cursor dont l'une des valeurs possibles est celle de l'image d'un drag'n drop standard (Cursor = crDrag) ? En utilisant son propre curseur, on est déchargé des problèmes de transparence, de positionnement, etc.