Problemi con il rilevamento dei movimenti del mouse in un TcxGrid quando si trascinano i file da Esplora risorse

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

Domanda

Di recente ho aggiunto una funzione a una grande applicazione scritta in Delphi (versione 2009) che consente all'utente di trascinare i file da Windows Explorer e rilasciarli su un controllo TcxGrid. Ho raggiunto questo obiettivo tramite il metodo comune di collegare il mio proc finestra alla griglia e intercettare il messaggio 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

Ora sto cercando di migliorare questa funzione per rilevare quando l'utente rilascia un file su una riga esistente nella griglia, che inizierà il processo di sovrascrittura di un file esistente con una nuova versione.

Il mio primo pensiero è stato quello di vedere se l'evento del mouseover del controllo della griglia avrebbe funzionato. Lo fa, ma non durante l'operazione di trascinamento.

Ho quindi usato un programma chiamato Winspector per vedere quali messaggi venivano inviati al controllo della griglia mentre il mouse veniva spostato sulla griglia e ora posso rilevare su quale riga si trova il mouse ed evidenziarlo. Sto usando la stessa tecnica di cui sopra, ma in questo caso sto sovrascrivendo la finestra proc per GridSite e non la griglia stessa, perché è lì che i messaggi sembrano andare secondo Winspector:

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

Ecco il corpo di 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;

Come puoi vedere, intrappolo il messaggio WM_NCHITTEST per raggiungere questo obiettivo. Secondo Winspector, questo messaggio viene anche inviato alla finestra del sito della griglia durante l'operazione di trascinamento, ma se decomprimo quell'istruzione Log () che genererà il valore del messaggio in un elenco di stringhe (che successivamente scarico manualmente in un campo memo), Ho determinato che, per qualche motivo, ottengo solo uno o due di questi messaggi quando trascino un file sulla griglia.

Ora, ecco la parte interessante: se ho Winspector in esecuzione e il monitoraggio dei messaggi che vanno a quella finestra, inizio improvvisamente a ottenere tutti i messaggi WM_NCHITTEST durante l'operazione di trascinamento dei file. Questo è anche il caso se output il valore intero di tutti i messaggi che arrivano alla finestra proc direttamente in una finestra di registro separata anziché prima in un buffer dell'elenco di stringhe. Spero che qualcuno sarà in grado di offrire qualche indizio sul perché questo accada o su come farlo funzionare.

È stato utile?

Soluzione

Invece di usare il messaggio WM_DROPFILES, dovresti usare OLE Drag'n'Drop. Guarda l'API RegisterDropTarget. Puoi ottenere informazioni più dettagliate su dove si sta verificando un trascinamento della selezione. Puoi anche accettare altri tipi di oggetti di trascinamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top