Problème de détection des mouvements de la souris dans un TcxGrid lors du déplacement de fichiers à partir de l'Explorateur Windows

StackOverflow https://stackoverflow.com/questions/1620890

Question

J'ai récemment ajouté une fonctionnalité à une grande application écrite en Delphi (version 2009) permettant à l'utilisateur de faire glisser des fichiers depuis l'explorateur Windows vers un contrôle TcxGrid. J'ai réalisé cela via la méthode habituelle consistant à attacher ma propre fenêtre proc à la grille et à intercepter le message WM_DROPFILES:

 originalGridWindowProc := cxGrid.WindowProc; // remember the old one
 cxGrid.WindowProc := GridWindowProc;  // assign the new one
 DragAcceptFiles(cxGrid.Handle, LongBool(True)); // setup to accept dropped files

J'essaie maintenant d'améliorer cette fonctionnalité pour détecter le moment où l'utilisateur dépose un fichier sur une ligne existante de la grille, ce qui entame le processus de remplacement d'un fichier existant par une nouvelle version.

Ma première pensée a été de voir si l'événement mouseover du contrôle de grille fonctionnerait. C'est le cas, mais pas pendant l'opération de glisser.

J'ai ensuite utilisé un programme appelé Winspector pour voir quels messages étaient envoyés au contrôle de grille lorsque la souris est déplacée sur la grille. Je peux maintenant détecter la ligne sur laquelle se trouve la souris et la mettre en surbrillance. J'utilise la même technique que ci-dessus, mais dans ce cas, je remplace le proc de la fenêtre pour GridSite et non la grille elle-même, car c'est à cet endroit que les messages semblent se diriger vers Winspector:

  originalGridSiteWindowProc := cxGrid.ActiveView.Site.WindowProc;
  cxGrid.ActiveView.Site.WindowProc := GridSiteWindowProc;

Voici le corps de GridSiteWindowProc:

procedure Tfrm.GridSiteWindowProc(var message: TMessage);
var
  hitTest: TcxCustomGridHitTest;
  gridRecord: TcxCustomGridRecord;
begin
  //Log(IntToStr(message.Msg));
  case message.Msg of
    WM_NCHITTEST: begin
      hitTest := cxGrid.ActiveView.GetHitTest(cxGrid.ScreenToClient(Mouse.CursorPos));
      if hitTest is TcxGridRecordCellHitTest then begin
        gridRecord := TcxGridRecordCellHitTest(HitTest).GridRecord;
        if Not gridRecord.Focused then
          gridRecord.Focused := True;
      end;
      originalGridSiteWindowProc(message);
    end
    else
      originalGridSiteWindowProc(message);
  end;
end;

Comme vous pouvez le constater, je piège le message WM_NCHITTEST pour atteindre cet objectif. Selon Winspector, ce message est également envoyé à la fenêtre du site de la grille lors de l'opération de glissement, mais si je retire le commentaire de cette instruction Log (), la valeur du message sera affichée dans une liste de chaînes (que je viderai ensuite manuellement dans un champ de mémo), J'ai déterminé que pour une raison quelconque, je ne reçois qu'un ou deux de ces messages lorsque vous faites glisser un fichier sur la grille.

Maintenant, voici la partie intéressante: si Winspector exécute et surveille des messages allant à cette fenêtre, je commence soudainement à recevoir tous les messages WM_NCHITTEST lors de l'opération de glissement de fichier. C’est également le cas si j’envoie la valeur entière de tous les messages arrivant à la fenêtre proc directement à une fenêtre de journal distincte plutôt qu’à un tampon de liste de chaînes. J'espère que quelqu'un sera en mesure de nous expliquer pourquoi cela se produit ou comment faire en sorte que cela fonctionne.

Était-ce utile?

La solution

Plutôt que d'utiliser le message WM_DROPFILES, vous devez utiliser OLE Drag'n'Drop. Regardez l'API RegisterDropTarget. Vous pouvez obtenir des informations plus détaillées sur l'emplacement d'un glisser-déposer. Vous pouvez également accepter plusieurs types d’objets glissés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top