Trucs et Astuces

Sélectionner l'objet sous le curseur avant d'appeler le Menu contextuel

Lorsqu'on associe un menu contextuel à un contrôle tel que TStringGrid ou TTreeView, on s'apperçoit lorsqu'on clique sur le bouton droit de la souris, que la sélection dans le contrôle ne se met pas à jour, c'est à dire que la sélection ne vient pas se mettre à l'endroit du curseur, comme cela se ferait en cliquant sur le bouton gauche.

C'est plutôt pénible pour l'utilisateur qui doit avant tout sélectionner la cellule ou l'objet dans le contrôle, puis cliquer avec le bouton droit pour faire surgir le menu contextuel.

La solution à ce problème est donc de sélectionner la cellule juste avant de faire apparaître le menu contextuel, ceci grâce à l'évènement OnPopup du menu contextuel. Pour illustrer la méthode, on suppose que l'utilisateur associe un menu Menu à un composant TStringGrid Grille.

Il faut récupérer les coordonnées de la souris dans le repère Ecran avec GetCursorPos et les placer dans la variable ScreenPoint.
Puis changer de repère, c'est à dire trouver les coordonnées de la souris dans le repère de TStringGrid et les placer dans la variable ClientPoint.
Enfin, trouver la cellule qui se trouve sous le curseur avec MouseToCell qui renvoie la colonne et la ligne de cette cellule, et la sélectionner.

Voici le source:

procedure TForm1.MenuPopup(Sender: TObject);
var
  Col,
  Row: Longint;
  ClientPoint,
  ScreenPoint: TPoint;
begin
  GetCursorPos(ScreenPoint);
  ClientPoint := Grille.ScreenToClient(ScreenPoint);
  Grille.MouseToCell(ClientPoint.X, ClientPoint.Y, Col, Row);
  Grille.Col := Col;
  Grille.Row := Row;
end;
Opération Glisser avec le composant TDBGrid

Le composant TDBGrid fournit en standard avec Delphi ne permet pas de faire glisser un élément de la grille vers une destination quelconque. Voici un remède à cette lacune.

Il faut créer un composant qui hérite de TDBGrid, par exemple TDBGrid2.
Puis ajouter une méthode qui va récupérer l'évènement "Bouton gauche de la souris": WMLButtonDown.
Et de répondre à ce message en initialisant le mode glisser avec BeginDrag(False).

Voici le source (ce composant apparaîtra dans la page "ContrôlesBD")

unit dbgrid2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids, DBGrids;

type
  TDBGrid2 = class(TDBGrid)
    private
    protected
    public
      procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    published
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('ContrôleBD', [TDBGrid2]);
end;

procedure TDBGrid2.WMLButtonDown(var Message: TWMLButtonDown);
begin
  inherited;
  BeginDrag(False);
end;

end.