私は最近、Delphi (バージョン 2009) で作成された大規模なアプリケーションに、ユーザーが Windows エクスプローラーからファイルをドラッグして TcxGrid コントロールにドロップできるようにする機能を追加しました。これは、独自のウィンドウ プロシージャをグリッドにアタッチし、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
現在、この機能を拡張して、ユーザーがグリッド内の既存の行にファイルをドロップしたことを検出できるようにしようとしています。これにより、既存のファイルを新しいバージョンで上書きするプロセスが開始されます。
私が最初に考えたのは、グリッド コントロールのマウスオーバー イベントが機能するかどうかを確認することでした。ただし、ドラッグ操作中はそうではありません。
次に、Winspector というプログラムを使用して、マウスがグリッド上を移動したときにグリッド コントロールに送信されるメッセージを確認しました。これで、マウスが置かれている行を検出して強調表示できるようになりました。上記と同じ手法を使用していますが、この場合、グリッド自体ではなく GridSite のウィンドウ プロシージャをオーバーライドしています。
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() ステートメントのコメントを外すと (後でメモ フィールドに手動でダンプします)、何らかの理由で、ファイルをグリッド上にドラッグしたときに、これらのメッセージが 1 つまたは 2 つしか表示されないことがわかりました。
ここで興味深い点があります。Winspector を実行してそのウィンドウにメッセージを監視している場合、ファイルのドラッグ操作中に突然すべての WM_NCHITTEST メッセージを取得し始めます。ウィンドウ プロシージャに送られるすべてのメッセージの整数値を、最初に文字列リスト バッファではなく別のログ ウィンドウに直接出力した場合も同様です。なぜこれが起こっているのか、またはこれを機能させる方法について、誰かが手がかりを提供できることを願っています。