J'ai un comportement étrange avec TStringGrid dans Delphi 7. Delphi n'appelle pas l'événement OnMouseUp si un menu contextuel est associé à la grille. Fondamentalement, lorsque le bouton RMB est pressé, la pop du menu annule/retarde l'OnMouseUp. En fait, pour être précis à 100%, la prochaine fois que vous appuierez sur un bouton de la souris, OnMouseUp est appelé deux fois - une fois pour l'événement en cours, et une fois pour l'événement perdu/retardé. Cela va vider toute la logique du programme car le code indésirable sera appelé la prochaine fois que l'utilisateur appuie sur un bouton de la souris.TStringGrid - OnMouseUp n'est pas appelé!
Répondre
je l'ai déjà pris une approche en quelque sorte similaire à celle décrite par Sertac: Je ne l'utilise plus la propriété PopupMenu pour attribuer un menu contextuel au réseau. Au lieu de cela, à l'intérieur de ma grille (ma grille est une grille de chaînes fortement modifiée dérivée de TStringGrid) je gère l'événement souris et affiche le pop-up comme je veux ET fais le traitement supplémentaire que je voulais faire AVANT le menu apparaît.
L'ouverture automatique d'un menu contextuel est une réponse à un clic droit de la souris. Le même clic déclenche également l'événement OnMouseUp
. Les développeurs VCL peuvent soit choisir de déclencher l'événement 'OnMouseUp' avant que le popup soit affiché, soit après. Apparemment, ce dernier est en effet, c'est-à-dire que l'événement est déclenché lorsque le popup est fermé (soit par la souris ou par le clavier comme si vous pressiez 'Esc').
Il n'y a pas de doublage de l'événement, lorsque vous appuyez sur le bouton gauche pour fermer la fenêtre contextuelle, vous déclenchez à nouveau l'événement 'OnMouseUp' en relâchant le bouton gauche.
Vous avez plusieurs alternatives. L'une consiste à dériver une nouvelle classe et à remplacer la méthode MouseDown
pour déclencher votre propre événement. Un exemple;
type
TMyStringGrid = class(TStringGrid)
private
FOnRButtonUp: TMouseEvent;
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
published
property OnRButtonUp: TMouseEvent read FOnRButtonUp write FOnRButtonUp;
end;
[...]
procedure TStringGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
if (Button = mbRight) and Assigned(FOnRButtonUp) then
FOnRButtonUp(Self, Button, Shift, X, Y);
inherited;
end;
Une autre alternative peut être à gérer un message VM_RBUTTONUP
. Cela peut être fait en dérivant une nouvelle classe comme ci-dessus, ou en remplaçant le WindowProc
de la grille. Il y a un exemple de remplacement du WindowProc here dans ce question. Une autre alternative peut être de laisser l'événement de souris seul et de faire votre traitement dans l'événement OnPopup
du menu contextuel. Cet événement est déclenché avant que la fenêtre contextuelle ne s'affiche. Vous pouvez obtenir les coordonnées de la souris avec Mouse.CursorPos
.
Pourtant, une autre alternative peut être de définir la propriété AutoPopup
du menu contextuel à False
, et en cas OnMouseUp
(ou mieux encore en cas OnContextMenu
) d'abord faire un peu de traitement et de montrer ensuite le menu contextuel. Un exemple;
procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Pt: TPoint;
begin
// Do processing
if Button = mbRight then begin
Pt := (Sender as TStringGrid).ClientToScreen(Point(X, Y));
PopupMenu1.Popup(Pt.X, Pt.Y);
end;
end;
- 1. Java Stack/Nest Count
- 2. Delphi TStringGrid Flicker
- 3. Clonage d'un composant TStringGrid
- 4. Access 2007 Nest requête parameterful
- 5. Pocket IE onmousedown onmousemove onmouseup?
- 6. TStringGrid bidouille - Restreindre la sélection à une seule ligne
- 7. TStringGrid ne s'actualise pas lors de l'appel de InvalidateCol()
- 8. Recherche de morceau avec Echo Nest Api
- 9. onmousedown et onmouseup avec YUI utilitaire d'animation
- 10. Evénements OnColumnChanged et OnRowChanged à TStringGrid
- 11. encodeWithCoder pas appelé
- 12. OnApplyTemplate n'est pas appelé
- 13. netServiceBrowserDidStopSearch pas appelé
- 14. ViewDidAppear/viewWillAppear pas appelé
- 15. initWithNibName est pas appelé
- 16. DllMain pas appelé
- 17. SQLAlchemy - MapperExtension.before_delete pas appelé
- 18. GridView1_RowDeleting() n'est pas appelé?
- 19. pyinotify.ThreadedNotifier, process_ * pas appelé
- 20. UITableView cellforrowatindexpath pas appelé
- 21. tableau reloadData pas appelé
- 22. didFinishLaunchingWithOptions n'étant pas appelé
- 23. sélecteur NSNotificationCenter pas appelé
- 24. Android: onTouch pas appelé
- 25. calloutAccessoryControlTapped pas appelé/déclenché
- 26. UIScrollView imageViewDidEndZooming pas appelé
- 27. Three20: CreateModel pas appelé
- 28. setOnTouchListener pas appelé ViewFlipper
- 29. accessoryButtonTappedForRowWithIndexPath n'est pas appelé
- 30. moveFocus n'est pas appelé
"Apparemment, ce dernier est en vigueur". C'est un contre-intuitif puisque l'événement OnMouseUp n'est plus un événement souris. En fait, il s'agit d'un événement "mouse-down" !!! +1 pour votre réponse très complète – Ampere
@Altar> "... counter intuitive ..." - Je suis d'accord, d'autant plus que le menu contextuel est en fait une réponse à un 'WM_CONTEXTMENU' qui est généré non seulement avec un WM_RBUTTONUP mais aussi avec un WM_NCRBUTTONUP et ' Shift + F10 'et VK_APPS, et, par exemple avec VK_APPS, 'OnKeyUp' est déclenché * avant * le popup est affiché. –