Bonjour,
Est-il possible en cliquant sur un tbutton de le supprimer à ce moment là ?
Merci.
Version imprimable
Bonjour,
Est-il possible en cliquant sur un tbutton de le supprimer à ce moment là ?
Merci.
J'essaierai bien, dans le OnClick:Code:(Sender as TButton).Free;
Le code fonctionne mais sur TButton statique. Par contre sur un TButton dynamique il ne fonctionne pas. Comment faire ?
Merci.
Dans l'aide de Delphi j'ai trouvé ce commentaire :
TObject.Free
Avertissement : Ne libérez jamais explicitement un composant dans l'un de ses propres gestionnaires d'événement ou dans un gestionnaire d'événement d'un composant qu'il possède ou contient. Par exemple, ne libérez pas un bouton, ou la fiche le possédant, dans son gestionnaire d'événement OnClick.
Dans ton unité, avant le private, tu ajoutes:
puis, quelque part dans l'implementation:Code:
1
2
3 procedure SuppBouton(Sender: TObject); private { Déclarations privées }
ensuite, à la création de ton bouton, tu ajoutes:Code:
1
2
3
4
5 procedure TForm1.SuppBouton(Sender: TObject); // >> si ta fiche s'appelle Form1 begin (Sender as TButton).Free; end;
Code:
1
2
3
4 with TCheckBox.Create(self) do begin ..... OnClick:=SuppBouton; end;
Si ça ne marche pas, c'est uniquement car l'événement OnClick n'est pas défini, donc aucune action n'est appellée lorsque tu cliques sur ton bouton.;)Citation:
Envoyé par Desraux
Non (Matt2094), la procédure d'évènement est bien définie. D'ailleurs avec le débugger je passe bien par la procédure d'évènement. Je pense plutôt que cet la technique de libération qui est en cause. En fait jusqu'à présent j'utilisait un timer pour libérer l'objet mais j'imagine qu'il doit exister une solution (ou astuce) plus élégante mais vu la note de Borland (Voir ci-dessus) je ne sais pas si cette solution existe réellement.
Qi130 , j' ai essayé ton code mais ça ne fonctionne pas non plus. J'ai exactement le même message.
Le code que j'utilise :
Code:
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 type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); // procedure ButtonClick(Sender: TObject); private { Déclarations privées } procedure ButtonClick(Sender: TObject); public { Déclarations publiques } end; var Form1: TForm1; Button : TButton; implementation {$R *.dfm} procedure TForm1.ButtonClick(Sender: TObject); begin (Sender as TButton).Free; end; procedure TForm1.FormCreate(Sender: TObject); begin Button:=TButton.Create(Form1); Button.Parent:=Self; Button.Caption:='Ok'; Button.OnClick:=Form1.ButtonClick; end;
à mon avis la méthode du timer est la plus propre... j'ai essayé de mettre
et même sur un bouton statique ca merde ...Code:
1
2
3
4
5
6
7 procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage('avant'); (Sender as TButton).Free; ShowMessage('après'); end;
Est-ce que le timer est le seul recours ?
une autre solution consisterai peut-être à tenter d'intercepter le message du click de la souris dans la fiche (grâce à un TApplicationEvents), et d'empêcher qu'il arrive au bouton... mais à mon avis le timer est suffisant
Oui mais le timer ne me plaît pas beaucoup parce qu'il faudra bien que je le libère aussi.
Je trouve l'idée d'intercepter l'évènement du OnClick intérressante mais quel est cet évènement ?
:aie: tu poses un composant ApplicationEvents sur ta fiche, et tu regarde dans l'évènement OnMessage. pour trouver les messages qui t'intéressent, tu peux chercher dans le fichier Messages.pas ex :
ensuite en jouant avec le paramètre Handled tu peux indiquer si windows doit propager le message vers le composant ou pasCode:
1
2
3
4
5 {$EXTERNALSYM WM_LBUTTONDOWN} WM_LBUTTONDOWN = $0201; {$EXTERNALSYM WM_LBUTTONUP} WM_LBUTTONUP = $0202;
pour connaître la position de la souris au moment du click, l'aide du SDK Windows indique :
pour trouver le contrôle en fonction de sa posion : TForm.ControlAtPosCode:
1
2
3
4
5 WM_LBUTTONDOWN fwKeys = wParam; // key flags xPos = LOWORD(lParam); // horizontal position of cursor yPos = HIWORD(lParam); // vertical position of cursor
EDIT :
après quelques essais je n'arrive pas à faire fonctionner ControlAtPos qui me renvoie toujours nil :aie:
par contre tu peux essayer un truc du genre :
Code:
1
2
3 if Msg.message = WM_RBUTTONDOWN then DestroyWindow(Msg.hwnd);
salut
voici un code qui fonctionne
Code:
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 Const Wm_DestroyButton = WM_USER+1; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private procedure WmDestroyButton(var Message: TMessage); message Wm_DestroyButton; { Déclarations privées } Protected procedure ButtonClick(Sender: TObject); public { Déclarations publiques } end; var Form1: TForm1; Button : TButton; implementation {$R *.dfm} procedure TForm1.ButtonClick(Sender: TObject); begin PostMessage(handle,Wm_DestroyButton,integer((Sender)),0); end; procedure TForm1.FormCreate(Sender: TObject); begin Button:=TButton.Create(self); Button.Parent:=Self; Button.Caption:='Ok'; Button.OnClick:=ButtonClick; end; procedure TForm1.WmDestroyButton(var Message: TMessage); Begin TButton(Message.WParam).Free; End;
@+ Phil
Merci Anapurna. Je viens de tester le code, il fonctionne bien.
Salut
Si le code te convient peut tu mettre le tag resolu merci
par avance pour les personnes de ce forum
@+ Phil