在TcxGrid检测鼠标的移动我最近增加了一个功能,在Delphi编写的(2009年版)的大型应用程序,允许用户从Windows资源管理器中拖动文件并放到一个TcxGrid控制。我通过我自己的窗口过程连接到电网和拦截WM_DROPFILES消息的常用方法来实现这一点:麻烦从Windows拖动文件时资源管理器
originalGridWindowProc := cxGrid.WindowProc; // remember the old one
cxGrid.WindowProc := GridWindowProc; // assign the new one
DragAcceptFiles(cxGrid.Handle, LongBool(True)); // setup to accept dropped files
我现在正在尝试加强这方面的功能,当用户将文件到在现有的行检测该网格将开始用新版本覆盖现有文件的过程。
我首先想到的是要看到,如果电网控制的鼠标悬停事件会工作。它确实,但不是在拖动操作过程中。
然后我使用一个名为Winspector的程序来查看当鼠标移动到网格上时发送到网格控件的消息,现在我可以检测到鼠标移到哪行并将其突出显示。我使用的是相同的技术上面,但在这种情况下,我重写了GridSite而不是网格本身的窗口过程,因为那是消息显示,根据Winspector将要去的地方:
originalGridSiteWindowProc := cxGrid.ActiveView.Site.WindowProc;
cxGrid.ActiveView.Site.WindowProc := GridSiteWindowProc;
这里是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;
正如你所看到的,我正在捕获WM_NCHITTEST消息来实现这一点。根据Winspector的说法,在拖动操作期间,这条消息也会被发送到网格窗口,但是如果我取消注释将输出消息值到一个字符串列表(之后我手动转储到备注字段)的Log()语句的注释,我确定出于某种原因,在网格上拖动文件时,我只会收到其中一条或两条消息。
现在 - 这里有一个有趣的现象:如果我有Winspector运行和监控消息去那个窗口,我突然开始文件拖动操作过程中让所有的WM_NCHITTEST消息。如果我将所有进入窗口proc的消息的整数值直接输出到单独的日志窗口,而不是首先输出到字符串列表缓冲区,也是如此。我希望有人能够提供一些线索,说明为什么会发生这种情况,或者如何使其发挥作用。
谢谢。由于我已经在使用OLE D&D来支持从Outlook中删除电子邮件,因此我能够增强代码以支持从资源管理器中删除,而且看起来这种方式可以很好地工作。这里有一些优秀的信息在这里: http://msdn.microsoft.com/en-us/library/bb776904(VS.85).aspx 我会走在第一位的OLE方法,但WM_DROPFILES方法似乎相当容易实现。 – PBenz 2009-10-26 15:17:26