Problemas com a detecção de movimentos do mouse em um TcxGrid quando arrastar arquivos do Windows Explorer

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

Pergunta

Eu recentemente adicionou um recurso a um grande aplicativo escrito em Delphi (versão 2009) que permite que o usuário arraste os arquivos do Windows Explorer e soltá-los em um controle TcxGrid. Eu consegui isso através do método comum de anexar minha própria janela proc à rede e interceptar a mensagem 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

Agora eu estou tentando melhorar esse recurso para detectar quando o usuário solta um arquivo em uma linha existente na grade, que vai começar o processo de sobrescrever um arquivo existente com uma nova versão.

Meu primeiro pensamento foi para ver se o evento mouseover do controle de grade iria funcionar. Ele faz, mas não durante a operação de arrastar.

Então, usei um programa chamado Winspector para ver o que as mensagens estavam sendo enviadas para o controle de grade como o mouse é movido sobre a grade, e agora eu posso detectar qual linha o mouse está sobre e realçá-lo. Eu estou usando a mesma técnica acima, mas neste caso estou substituindo o proc janela para a GridSite e não o próprio grid, porque é aí que as mensagens parecem estar indo de acordo com Winspector:

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

Aqui está o corpo 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;

Como você pode ver, eu estou prendendo a mensagem WM_NCHITTEST para conseguir isso. De acordo com Winspector, esta mensagem também é enviada para a janela do site rede durante a operação de arrastar, mas se eu descomente que Log () declaração que vai apresentar o valor mensagem para uma lista de strings (que eu despejar manualmente para um campo memo depois), Eu determinei que, por algum motivo, eu só tem uma ou duas dessas mensagens ao arrastar um arquivo sobre a grade.

Agora - aqui é a parte interessante: se eu tiver Winspector execução e monitoramento de mensagens que vão para essa janela, de repente começar a receber todas as mensagens WM_NCHITTEST durante a operação de arrastar. Este é também o caso se eu saída o valor inteiro de todas as mensagens que chegam ao proc janela diretamente para uma janela de log separado em vez da uma lista seqüência de tampão em primeiro lugar. Eu estou esperando que alguém será capaz de oferecer alguma pista sobre por que isso está acontecendo ou como chegar a este trabalho.

Foi útil?

Solução

Ao invés de usar a mensagem WM_DROPFILES, você deve usar OLE Drag'n'Drop. Olhe para a API RegisterDropTarget. Você pode obter informações mais detalhadas sobre onde a arrastar ou soltar está ocorrendo. Você também pode aceitar mais tipos de arrastar objetos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top