Bonjour à tous,
je voudrais faire un représentation visuelle de la liste des Employés en créant dynamiquement des Timage pour chaque employé . Mais la création devient lente dés que le nbre d'employés dépasse un certain nbre.
Bonjour à tous,
je voudrais faire un représentation visuelle de la liste des Employés en créant dynamiquement des Timage pour chaque employé . Mais la création devient lente dés que le nbre d'employés dépasse un certain nbre.
Un TListView VCL permet de faire un affichage de vignette sans effort : https://www.developpez.net/forums/d1...e/#post9679007
Pense juste à stocker une image réduite des Employés, inutile de charger une image de grande taille pour afficher une vignette, autant déjà stocker les vignettes et au clic sur la vignette affiché l'original
Pour un listing produit, genre 300 000 au catalogue, on avait 4 taille d'image, la vignette de listing, la vignette de fiche, le grande image au clic gauche, la version originale au clic droit (celle-ci étant brut taille du capteur les vieux produit en 3000x4000, les produits récent pouvant avoir du 6000x8000)
Evidemment, les images téléchargés via un Thread, téléchargé au moment opportun type Lazy Loading ...
Si tu veux passer par des Timage, surtout ne pas créer autant de Timage que d'employées, il faut faire comme pour la TDBGrid, en fait, tu as un nombre fixe de TImage, une TScrollBar (et pas une TScrollBox) et tu simule le défilement, tu affiches un segment du lot d'image et tu ne charges que celle utilisée.
On a parlé de cela sur le forum récemment, j'ai dit exactement la même chose.
Voir si la TDBCtrlGrid supporte le TDBImage, cela utilise l'astuce citée ci-dessus, utile si l'image est dans un blob en DB.
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
Bonjour,ce que je veux faire c'est de créer des Composants Timage amovible c'est à dire que je peut les placer ou je veut sur la fiche
Pour un système de controle d'accès, j'ai fait un truc similaire, cela crée des fiches selon les dernières entrée-sortie d'un site.
Tout simplement des TForm contenant un Timage et quelques Labels, couleur différente selon entrée sortie et selon quelques zones sensibles.
L'utilisateur pouvait choisir la disposition, soit sur un écran annexe, soit aligné sur l'écran principale (au bord), soit aligné avec l'application de Supervision (Plan de Batiment), soit aligné au Moniteur Caméra ...
Placer des composants n'importe où sur la fiche, c'est le b.a.-ba, quelle est la difficulté ?
Encore une fois, ne créer que les composants utiles, au pire sur un écran classique de bureautique, vous avec 1920x1080, ça fait quoi, entre 20x10 vignettes de 100x100, une machine actuelle qui rame pour avoir afficher 200 petites images, il y a un problème annexe.
Sur des écrans de moteurs vidéo, plus grand que le HD classique, parfois 4 moniteurs, il y a avait un plan en MDI, un écran entrée sortie, deux afficher 32 caméras soit 2 x 4 x 4, oui cela consommait du CPU mais c'est la transformation du flux H264 ... c'était en 2012 ... comment une liste d'image pourrait être lente de nos jours ?
Soyez plus clair, on ne comprend jamais vos demandes, faites une maquette.
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
Du style trombinoscope ?
Selon ton besoin et la version de Delphi il peut aussi être intéressant de jeter un oeil au TControlList sur lequel Serge Girard a fait une présentation avec plein d'exemples disponibles sur Github et une série d'articles sur son blog.
La rediffusion et les liens sont disponibles sur https://serialstreameur.fr/webinaire-20210520.php
Si Checkal est toujours en version XE2, pas de TControlList
Comme quoi indiqué sa version Delphi lorsqu'on pose la question est une bonne chose, @Checkal ce n'est pas la première fois que je vous fait cette reflexion !
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
TControlList c'est la version non DB du TDBCtrlGrid ... je suppose qu'il est codé de la même façon, tout est dessiné sur une curseur fenêtré dans les données calculées à la volée comme un TListView en mode OwnerData
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
Désolé, effectivement je suis toujours sur delphi XE2.Ici tout est crée dynamiquement et chaque composant à ses propres événements (onmousedown,onmousemove,onmouseup,onclick)
Comme je vois beaucoup de similitudes entre chaque shape je commencerai par utiliser un TFrame du coup, dans chaque cadre, un Tlistwiew me semble convenir
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
Il y a une raison pour que les employés soient placé ainsi, non aligné, espacé ?
Est-ce l'utilisateur qui fait une sorte de Drag'N'Drop entre les groupes (TShape)
Pour une allure plus professionnelle, une liste propre bien ordonné sera plus efficace, une TListView en multi ligne je ne sais pas, sinon un TFlowPanel pour organiser des Frame effectivement
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
@Shai :Il y a une raison pour que les employés soient placé ainsi, non aligné, espacé ?
le placement sur la fiche est effectué par l'utilisateur pour satisfaire un organisation voulue
@Shai :Est-ce l'utilisateur qui fait une sorte de Drag'N'Drop entre les groupes (TShape)
OUI, ici les (Tshape) représentent des Sites(Chantiers) de travail et l'utilisateur peut mettre ou déplacer un employé d'un Site à un autre .
En fait, faudrait que vous fassiez une application de test annexe, des donnée en dur pour juste tester la partie dessin, car vu la simplicité de l'écran, cela ne peut pas être lent !
En réalité, est-ce que les employés sont disposés sur un plan pour avoir cette disposition libre ?
Car on peut très bien faire une liste alignée si le positionnement plus ou moins vers la droite ou vers la gauche n'a pas un sens,
Comme dans l'explorateur de fichier, une TListView on peut très bien glissé un fichier d'une liste à une autre ... en mode grande icone, cela serait à mon avis tellement plus simple
Et à côté, une application de test opposé, un mode grille simpliste et voire si ce n'est pas la partie données qui est lente, genre des SQL mal fichu
Sinon, je recommande de grouper Timage + 2 TLAbels dans un TPanel transparent (ParentBackground)
Si le clic, le Drap 'N' drop est global, autant utilise plutôt un conteneur, même mettre Timage et labels en enabled false, ne capturant pas la soursi c'est le conteneur qui gère de Drag ...
le TPanel étant un TWinControl cela ajoute un handle mais on peut l'utiliser pour la partie Drag en utilisant les messages Windows
Voir aussi OnDockDrop et OnDockOver pour le déplacement d'un Control d'un parent vers un autre voir DockSite
Enfin, une gestion de planning de chantier avec un outil pareil, votre client est un idiot !
Où est la notion de jour, d'heure, pas de calendrier ? c'est mal parti !
pas de gestion d'équipe ni de gestion des congés ?
Pas de gestion des équipement et matériaux à synchroniser avec les chantiers ?
à terme cet écran sera en pratique inutilisable.
Ce une Désorganisation voulue ça !
Regardez un peu la concurrence, vous verrez à quoi ressemble un logiciel de gestion de planning d'équipe
Là autant qu'il fasse son truc sur un tableau eu mur avec des post-it, ambiance planning poker.
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
Bonjour,
@shaill:Sinon, je recommande de grouper Timage + 2 TLAbels dans un TPanel
la on va créer un autre composant et ça va devenir encore plus lent. En effet, j'ai met un Tprogress personnalisé pour tester la rapidité de création des composants et j'ai remarqué que de plus en plus qu'il ya de composants créer la création devient plus lente, conclusion faite que c'est un problème de mémoire allouée.
Sans le Progress, est-ce que ça n'accélère pas un peu le traitement ?
Et on parle de combien de composants en tout, parce que franchement, j'vois pas pourquoi 50 trucs à l'écran en plus peut générer des anomalies (en dehors de ralentir le traitement des clics parce qu'il y a beaucoup plus de collisions à tester).
Crées-tu tous les composants en une fois ou juste ceux qui sont affichés à l'écran ?
Au final, si créer trois composants pose problème, et que la solution TFrame t'ennuie parce qu'en effet ça en ajoute encore, il va peut-être falloir passer par la création de ton propre composant dans lequel tu gèreras le onPaint en direct. Du coup au lieu d'en créer X tu n'en feras qu'un que tu pourras gérer toi-même. Suffit de descendre d'une image par exemple, comme ça tu n'as que son Canvas à changer quand tu modifies l'une des propriétés.
Quand les techniques classiques sont insatisfaisantes il est de bon ton de regarder ce qu'on fait en jeux vidéos et en optimisation du fonctionnement des programmes.
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
de mon expérience, la meilleur solution c'est de dissocier l'UI des datas, et à ne pas hésiter à faire du CustomPaint...ce à quoi Delphi ne pousse pas vraiment
je m'explique, on a deux choses dans une appli, les données et l'affichage. Pouvoir manipuler les données est souvent un besoin, je vois trop souvent des traitements attachés à une DBGrid alors qu'ils ne concernent pas l'affichage...on ajoute un DisableControls pour rendre les choses moins lentes, alors que le problème est dès le départ l'usage d'un composant inadapté.
donc une fois qu'on a accès aux données (sous forme de liste, de tableau dynamique d'un DateSet etc...peu importe) on passe à leur affichage. Là j'aime bcp la ListBox virtuelle, on lui fixe un Count et hop ! elle réclame au besoin de dessiner l'item n°X...on peut évidemment décliner ce principe sur tout type d'affichage, une simple TPaintBox (ou son dérivé) peut être utilisé pour définir un rectangle cliquable qui réclamera dans son évènement OnPaint de dessiner son contenu - et il ne le fera QUE quand il est visible à l'écran....donc au lieu de mettre un TImage, de le charger afin qu'il puisse au besoin se dessiner, je préfère dessiner un Bitmap (ou PNG...) sur un Canvas, lequel Bitmap n'est chargé qu'à la demande. La différence est très sensible quand au lieu de charger 1000 TImage, le OnPaint ne déclenche le chargement des 5 images visibles à l'écran, les 995 autres attendant d'être affichées quelque part pour être chargées....de même ce Bitmap pourra apparaitre à différents endroits sur la fiche (au besoin) avec un seul chargement au lieu de créer autant de TImage qu'on a besoin d'afficher ledit bitmap.
Je le répète sans cesse qu'il faut travailler son modèle avec une vue bidon, régler les perfs à ce niveau là en premier
Puis ensuite construire la vue avancé avec un contrôleur bidon qui va fournir des données en dur factice, pour régler les perfs à ce niveau
Et enfin, brancher la vue avancé sur le modèle réel et tout doit se passer correctement car l'effort fourni pour découpler les classes IHM des classes Modèle avec un éventuel contrôleur qui fait le Bridge, on a déjà réglé un tas de problème.
Comme d'habitude avec chekkal, on a jamais les bonnes infos ... si cela se trouve il y a un SQL lancé dans OnMouseMove qui fait tout ramer
Après ce n'est pas à la portée de tous de gérer un TPaintBox complet et devoir gérer soit même les positions X, Y des éléments affichés par rapport à son propre système de gestion de Control.
Même avec 1000 composants* à l'écran, je n'ai jamais eu besoin d'aller à cette extrème en PROD, même il y 10 ans.
* des des TWinControl, genre 2 x 4 x 50 TCheckBox réprésentant un codon d'ADN viral.
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
Bonjour,
Je vois que mon programme sollicite beaucoup d'interrogations et je le comprend. Cependant, je me suis engagé dans ce petit projet suite à une demande de clients qui sont pas satisfait de l'affichage fait par les composants déjà existant (Tdbgrid, TdbctrlGrid). En fait , le besoin est de voir l'employé virtuellement sous forme de composant visuelle avec la photo associé sur l’écran et ainsi le positionné d'une manière à satisfaire des besoins internes à l'entreprise.
voici les code complet que je utilise
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 ////CETTE PROCEDURE CREER LES COMPOSANTS TLABEL ET TSHAPE ASSOCIE AU CHANTIER procedure creer(pa:Twincontrol;n1,n2,c2:shortstring;gau,lar,hau,haut:integer;col:Tcolor); var p1:TShape; S:shortstring; begin P1:=Tshape.Create(form1); with p1 do begin parent:=pa;pen.color:=col;brush.Style:=bsclear; name:=n1;hint:=c2;tag:=900; if gau<>0 then begin left:=gau; top:=hau; width:=lar; height:=haut; end else begin left:=10;top:=10;width:=200;height:=200; end; onmouseup:=form1.P1MouseUp; onmousemove:=form1.P1MouseMove; onmousedown:=form1.P1MouseDown; SENDTOBACK; end; with Tlabel.Create(p1) do begin parent:=form1;left:=p1.Left;top:=p1.Top; caption:=c2; name:=n2; color:=clyellow;transparent:=false; font.Name:='Microsft sans Serif'; font.style:=[fsitalic]; onmouseup:=form1.P11MouseUp; onmousemove:=form1.P11MouseMove; onmousedown:=form1.P11MouseDown; ondblclick:=form1.CHADblClick; end; End; ////CETTE PROCEDURE CREER LES COMPOSANTS TLABEL ET TIMAGE ASSOCIE A L'EMPLOYE procedure creer2(i:TWINCONTROL;c2:shortstring); var j:Tlabel; k:integer; begin if Tlabel(form1.FindComponent('mat'+Fdm.PER.fieldbyname('mat').asstring))<>nil then Tlabel(form1.FindComponent('mat'+Fdm.PER.fieldbyname('mat').asstring)).Destroy; j:=Tlabel.create(i); with j do begin parent:=i;hint:=c2; font.size:=7;top:=100;left:=100; font.Name:='Microsoft sans Serif'; name:='mat'+Fdm.PER.fieldbyname('mat').asstring; caption:=fdm.PER.fieldbyname('mat').asstring+' '+fdm.PER.fieldvalues['nom']+' '+fdm.PER.fieldvalues['pre']+#13+ Fdm.PER.fieldbyname('sit').asstring; onmouseup:=form1.PAGMouseUp; onmouseDown:=form1.PAGMouseDown; onmouseMove:=form1.PAGMouseMove; ondblclick:=form1.pagdblclick; LEFT:=Fdm.PER.fieldbyname('gau').asinteger; top:=Fdm.PER.fieldbyname('hau').asinteger; if Fdm.PER.fieldValues['cha']<>'' then hint:=Fdm.PER.fieldbyname('cha').asstring else hint:=''; ondblclick:=form1.ajoempClick; end; if TImage(form1.FindComponent('imat'+Fdm.PER.fieldbyname('mat').asstring))<>nil then TImage(form1.FindComponent('imat'+Fdm.PER.fieldbyname('mat').asstring)).Destroy; with Timage.create(i) do begin parent:=i; name:='imat'+Fdm.PER.fieldbyname('mat').asstring; width:=j.width div 3;height:=width; left:=j.left-width-5; top:=j.top; picture.Bitmap.Assign(fdm.PER.fieldbyname('pho1')); onmouseup:=form1.PAGMouseUp; onmouseDown:=form1.PAGMouseDown; onmouseMove:=form1.PAG2MouseMove; ondblclick:=form1.ajoempClick; stretch:=true; end; end; procedure TForm1.PAG2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var i, j,n: Integer;s,l,m:shortstring; begin Timage(sender).cursor:=crmultidrag; cha := Timage(Sender).name; if Timage(Sender).tag = 1 then begin i := mouse.cursorpos.X-Tpanel(Timage(sender).parent).left ; j := mouse.cursorpos.Y-Tpanel(Timage(sender).parent).top; Timage(Sender).left :=i-i1; Timage(Sender).top := j-j1; s:='m'+copy(Timage(Sender).name,3,length(Timage(Sender).name)-2); Tlabel(form1.FindComponent(s)).left:=Timage(Sender).left+Timage(Sender).width+5;i:=Tlabel(form1.FindComponent(s)).left; Tlabel(form1.FindComponent(s)).top:=Timage(Sender).top;///+Tlabel(form1.FindComponent(s)).height div 2; j:=Tlabel(form1.FindComponent(s)).top; s:='m'+copy(Timage(Sender).name,3,length(Timage(Sender).name)-2); for n:=0 to form1.controlcount-1 do if (form1.Controls[n] is Tshape)and(Tshape(form1.Controls[n]).Tag=900)and (Tshape(form1.Controls[n]).left<=Tlabel(form1.FindComponent(s)).Left)and(Tshape(form1.Controls[n]).left+Tshape(form1.Controls[n]).width>Tlabel(form1.FindComponent(s)).Left) and(Tshape(form1.Controls[n]).top<=Tlabel(form1.FindComponent(s)).top)and(Tshape(form1.Controls[n]).top+Tshape(form1.Controls[n]).height>Tlabel(form1.FindComponent(s)).top) then begin l:=inttostr(Tlabel(form1.FindComponent(s)).left-Tshape(form1.Controls[n]).left); m:=inttostr(Tlabel(form1.FindComponent(s)).top-Tshape(form1.Controls[n]).top); Tlabel(form1.FindComponent(s)).hint:=taille1(Tshape(form1.Controls[n]).name,25,1)+taille1(l,5,1)+taille1(m,5,1); end; end; end; procedure TForm1.PAGMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var i, j: Integer;s,l,m:shortstring; k:Tpanel; begin Tlabel(sender).cursor:=crmultidrag; cha := TLabel(Sender).name; if Tlabel(Sender).tag = 1 then begin i := mouse.cursorpos.X-Tpanel(Tlabel(sender).parent).left ; j := mouse.cursorpos.Y-Tpanel(Tlabel(sender).parent).top; TLabel(Sender).left :=i-i1; TLabel(Sender).top := j-j1; k:=Tpanel(Tlabel(sender).parent); { s:='lm'+copy(TLabel(Sender).name,2,length(TLabel(Sender).name)-1); Tlabel(k.FindComponent(s)).left:=TLabel(Sender).left; Tlabel(k.FindComponent(s)).top:=TLabel(Sender).top+10;} s:='im'+copy(TLabel(Sender).name,2,length(TLabel(Sender).name)-1); Timage(k.FindComponent(s)).left:=TLabel(Sender).left-Timage(k.FindComponent(s)).width-5; TImage(k.FindComponent(s)).top:=TLabel(Sender).top;///-TLabel(Sender).height div 2; for j:=0 to form1.controlcount-1 do begin if (form1.Controls[j] is Tshape)and(Tshape(form1.Controls[j]).Tag=900)and (Tshape(form1.Controls[j]).left<=TLabel(Sender).Left)and(Tshape(form1.Controls[j]).left+Tshape(form1.Controls[j]).width>TLabel(Sender).Left) and(Tshape(form1.Controls[j]).top<=TLabel(Sender).top)and(Tshape(form1.Controls[j]).top+Tshape(form1.Controls[j]).height>TLabel(Sender).top) then begin l:=inttostr(Tlabel(sender).left-Tshape(form1.Controls[j]).left); m:=inttostr(Tlabel(sender).top-Tshape(form1.Controls[j]).top); Tlabel(sender).hint:=taille1(Tshape(form1.Controls[j]).name,25,1)+taille1(l,5,1)+taille1(m,5,1); end; end; end; end; procedure TForm1.PAGMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Tlabel(Sender).tag := 0; i1 := 0; j1 := 0; end; procedure TForm1.PAGMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Tlabel(Sender).tag := 1; i1 := mouse.cursorpos.X-(Tpanel(Tlabel(sender).parent).left+Twincontrol(Sender).left) ; j1 := mouse.cursorpos.Y-(Tpanel(Tlabel(sender).parent).Top+Twincontrol(Sender).top) ; end; procedure TForm1.P1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if (varglobal<>'') then ///11/05/2022 begin Timage(form1.FindComponent(varglobal)).Left:=x; TImage(form1.FindComponent(varglobal)).top:=y+Tshape(sender).top; Timage(form1.FindComponent(varglobal)).tag:=1; pag2mousemove(Tlabel(form1.FindComponent(varglobal)),[SSShift],x,y); TImage(form1.FindComponent(varglobal)).tag:=0; varglobal:=''; end else if (tshape(sender).Cursor<>crcross)and(boitecouleur.Execute) then TShape(sender).Pen.Color:=boitecouleur.Color; end; procedure TForm1.P11MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if ((TwinCONTROL(sender).Width-x)<10)and((TwinCONTROL(sender).Height-y)<=10) then champ:='OK' else champ:=''; ii1 := mouse.cursorpos.X - (tshape(Sender).left); jj1 := mouse.cursorpos.Y -(tshape(Sender).top); end; procedure TForm1.P1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); VAR I:Tshape;s:shortstring;j:word; begin i:=tshape(sender); if ((i.Width-x)<20)and((i.Height-y)<=20) then tshape(sender).Cursor:=crcross else tshape(sender).Cursor:=crdefault; if (getasynckeyState(VK_LBUTTON)and $8000)<>0 then begin if tshape(sender).Cursor=crcross then begin i.width:= mouse.cursorpos.X-i.Left;if i.width<100 then i.Width:=100; i.height:= mouse.cursorpos.Y-i.top;if i.height<100 then i.height:=100; end; end; end; procedure TForm1.P11Mouseup(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); VAR s,s1:shortstring;j:word;i:Tshape; begin s:='P'+trim(copy(Tlabel(sender).Name,2,length(Tlabel(sender).Name)-1)); i:=Tshape(form1.findcomponent(s)); for j:=0 to form1.controlcount-1 do if (form1.Controls[j] is Tlabel)and(copy(Tlabel(form1.Controls[j]).name,1,3)='mat')and(trim(copy(Tlabel(form1.Controls[j]).hint,1,25))=s) then begin Tlabel(form1.Controls[j]).left:=i.Left+strtoint(trim(copy(Tlabel(form1.Controls[j]).hint,26,5))); Tlabel(form1.Controls[j]).top:=i.top+strtoint(trim(copy(Tlabel(form1.Controls[j]).hint,31,5))); s1:='l'+form1.Controls[j].Name; Tlabel(form1.findcomponent(s1)).left:=Tlabel(form1.Controls[j]).left; Tlabel(form1.findcomponent(s1)).top:=Tlabel(form1.Controls[j]).top+10; s1:='i'+form1.Controls[j].Name; Timage(form1.findcomponent(s1)).left:=Tlabel(form1.Controls[j]).left-Timage(form1.findcomponent(s1)).width-5; Timage(form1.findcomponent(s1)).top:=Tlabel(form1.Controls[j]).top;///-Tlabel(form1.Controls[j]).height div 2; end; end; procedure TForm1.P11MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); VAR I:Tlabel;s,s1:shortstring;j:word; begin i:=tlabel(sender); tlabel(sender).Cursor:=crHANDPOINT; if (getasynckeyState(VK_LBUTTON)and $8000)<>0 then begin if champ='' then begin i.Left:=mouse.cursorpos.X-ii1; if i.left+30>screen.width then i.left:=screen.Width-30; if i.left<1 then i.left:=1; i.top:=mouse.cursorpos.y-jj1; if i.top+100>screen.height then i.top:=screen.height-100; if i.top<50 then i.top:=50; s:='P'+trim(copy(i.Name,2,length(i.Name)-1)); for j:=0 to form1.controlcount-1 do if form1.Controls[j].Name=s then begin Tshape(form1.Controls[j]).left:=i.Left; Tshape(form1.Controls[j]).top:=i.top; break; end; end; end end; procedure TForm1.P1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin ii1:=0;jj1:=0; END;
FindComponent !
Vous devriez maintenir une liste interne pour éviter ce balayage lourd.
et en plus, plusieurs FindComponent pour le même controle à la suite, et vous vous demandez pourquoi c'est lent !
Le MouseMove est trop compliqué, en utilisant un Panel comme Parent, retrouver les controles groupés sera plus aisé pour déplacer l'ensemble et aussi séparer les TShape 900 dans une liste des control contenus
Jetez ce code, recommencez !
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
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager