0

私は最近、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 メッセージを取得し始めます。ウィンドウ プロシージャに送られるすべてのメッセージの整数値を、最初に文字列リスト バッファではなく別のログ ウィンドウに直接出力した場合も同様です。なぜこれが起こっているのか、またはこれを機能させる方法について、誰かが手がかりを提供できることを願っています。

4

1 に答える 1

3

WM_DROPFILESメッセージを使用するのではなく、OLEドラッグアンドドロップを使用する必要があります。RegisterDropTargetAPIを見てください。ドラッグまたはドロップが行われている場所に関する詳細情報を取得できます。より多くの種類のドラッグオブジェクトを受け入れることもできます。

于 2009-10-25T16:53:08.570 に答える