在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