Question

I recently added a feature to a large application written in Delphi (version 2009) that allows the user to drag files from Windows explorer and drop them on a TcxGrid control. I achieved this via the common method of attaching my own window proc to the grid and intercepting the WM_DROPFILES message:

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

I now am trying to enhance this feature to detect when the user drops a file onto an existing row in the grid, which will begin the process of overwriting an existing file with a new version.

My first thought was to see if the grid control's mouseover event would work. It does, but not during the drag operation.

I then used a program called Winspector to see what messages were being sent to the grid control as the mouse is moved over the grid, and I can now detect what row the mouse is over and highlight it. I'm using the same technique as above, but in this case I am overriding the window proc for the GridSite and not the grid itself, because that is where the messages appear to be going according to Winspector:

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

Here is the body of 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;

As you can see, I'm trapping the WM_NCHITTEST message to achieve this. According to Winspector, this message also gets sent to the grid site window during the drag operation, but if I uncomment that Log() statement which will output the message value to a string list (which I manually dump to a memo field afterwards), I have determined that for some reason, I only get one or two of these messages when dragging a file over the grid.

Now - here's the interesting part: if I have Winspector running and monitoring messages going to that window, I suddenly start getting all the WM_NCHITTEST messages during the file drag operation. This is also the case if I output the integer value of all the messages coming to the window proc directly to a separate log window instead of to a string list buffer first. I am hoping that someone will be able to offer some clue as to why this is happening or how to get this to work.

Was it helpful?

Solution

Rather than using the WM_DROPFILES message, you should use OLE Drag'n'Drop. Look at the RegisterDropTarget API. You can get more detailed information about where a drag or drop is taking place. You can also accept more kinds of drag objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top