2017-01-31 31 views
0

OLEドラッグ&ドロップ機能を実装したいと思います。これを行うには、マウスボタンがクリックされて移動されたことを検出する必要があります。私はDoDragDropと呼んで、ドラッグ&ドロップ機能を開始します。IDropSourceNotify - 実装方法

ドラッグ&ドロップ機能を受け取るには、その前にRegisterDragDropに電話して、ドラッグ&ドロップ操作の対象としてウィンドウを登録する必要があります。ほとんどのアプリケーションと同様に、私のメインウィンドウは、いくつかのサブウィンドウに基づいて:TreeViewListViewEditなどです。IDropTarget::DragOverの場合、ターゲットサブウィンドウがドラッグ&ドロップ操作を受け入れるかどうかを検出できます。ターゲットのサブウィンドウがドラッグ&ドロップ操作を受け入れる場合、これはうまくいきます。別のアプリケーションからオブジェクトをドラッグし、マウスカーソルも表示されます。

私のアプリケーション内でドラッグ&ドロップ機能をDoDragDropで開始すると、マウスカーソルが自動的に変更されるようになりました。どうして?

したがって、IDropSource::GiveFeedbackメソッドを使用して、ターゲットサブウィンドウのカーソルを変更できます。しかし、私はどのサブウィンドウがカーソルを変更しなければならないかを知ることができない。

私が正しいとすれば、IDropSourceNotifyはこの情報を提供する必要があります。しかし、このクラスをDragの&ドロップ操作にどのように関与させることができますか?

さらに、ソースウィンドウが自分のアプリケーションの中にある場合は自分自身でマウスカーソルを処理しなければならない理由はわかりませんが、ソースウィンドウが他のアプリケーションの中にある場合は自動的に処理されます。

最後に、私のサブウィンドウのカーソルをIDropSource::GiveFeedbackに変更すると、変更したように表示されます。しかし、私の主なスレッドはDoDragDropの中にあるので、私はWindowsがどのように変更されたカーソルを検出するのだろうかと思います。私が正しいのであれば、WindowsはWM_NCHITTESTというメッセージでアプリケーションを尋ねます。カーソルは表示されます。しかし、メインスレッドはDoDragDropの内部でブロックされていますが、私のアプリケーションはこのメッセージにどのように答えますか?

私はDelphi XE4をWindow 7システムで使用しています。

+0

オブジェクトは2つのインタフェース 'IDropSourceNotify'と' IDropSource'を実装する必要があります。'IDropSource'を' DoDragDrop'に渡すと、 'IDropSourceNotify'システムが' IDropSource'で 'QueryInterface'を呼び出したときに発生します。 – RbMm

+0

@RbMmここでIDropSourceNotifyがどのように関連しているのか分かりません。 IDropSourceNotifyはVistaで導入され、IDropSource(カーソルの制御機能を含む)はW2Kで導入されました。 – SpeedFreak

+0

@SpeedFreak - 質問は「IDropSourceNotify'をどのように実装するのか」ということで、後でそのIDropSourceNotifyが導入されたのは何ですか? – RbMm

答えて

2

ドロップソースは、ドロップターゲットについて何も想定してはいけません。ターゲットのUIを改変しないでください。 つまり、カーソルの下のコントロールのカーソルプロパティを混乱させないでください。

IDropSource.GiveFeedbackからの戻り値は、Windowsに標準のドラッグドロップカーソルを使用するか、またはその詳細を自分で処理するように指示します。

DRAGDROP_S_USEDEFAULTCURSORSを返すと、現在のドロップエフェクト(GiveFeedbackに渡されたパラメータ)に対応する標準カーソルが使用されます。 S_OKを返す場合は、SetCursor API関数を呼び出してカーソルを設定できます。

DRAGDROP_S_USEDEFAULTCURSORSを返すことをお勧めします。

COMベースのドラッグアンドドロップの内部の詳細を知りたいという熱心な希望がない限り、私はあなたにGoogleの "drag delphiをドラッグ"し、すでに利用可能なライブラリの1つを使用することをお勧めします。