5

winampやvlcプレーヤーのように、ファイルのドラッグアンドドロップを行う方法は?つまり、どのようなコーディングがアプリケーションに組み込まれるのか知りたいのですか?C++について知りたい

4

5 に答える 5

15

Windowsの純粋なC/C ++では、DragAcceptFiles 関数とWM_DROPFILESメッセージについて読み始めます。より強力なC++ライブラリ(Qt、Wxなど)を使用している場合は、それぞれのドキュメントを確認してください。より具体的には、何を使用しているかを知るのに役立ちます。

また、この議論はあなたの質問に答えるかもしれません。それがあなたの意図したことであるならば、この質問を閉じてください。

于 2009-01-16T09:53:19.933 に答える
2

コムで:

public が IDropTarget を拡張するクラスを作成する

クラスをドロップに登録します。WM_CREATE でこれを行う

RegisterDragDrop(hwnd,static_cast<IDropTarget*>(pointer_to_your_class));

クラスでは、純粋な仮想関数であるため、いくつかの関数をオーバーライドする必要があります。

virtual HRESULT STDMETHODCALLTYPE DragEnter( 
        /* [unique][in] */ __RPC__in_opt IDataObject *pDataObj,
        /* [in] */ DWORD grfKeyState,
        /* [in] */ POINTL pt,
        /* [out][in] */ __RPC__inout DWORD *pdwEffect) = 0;

virtual HRESULT STDMETHODCALLTYPE DragOver( 
    /* [in] */ DWORD grfKeyState,
    /* [in] */ POINTL pt,
    /* [out][in] */ __RPC__inout DWORD *pdwEffect) = 0;

virtual HRESULT STDMETHODCALLTYPE DragLeave( void) = 0;

virtual HRESULT STDMETHODCALLTYPE Drop( 
    /* [unique][in] */ __RPC__in_opt IDataObject *pDataObj,
    /* [in] */ DWORD grfKeyState,
    /* [in] */ POINTL pt,
    /* [out][in] */ __RPC__inout DWORD *pdwEffect) = 0;

これらの関数のそれぞれは、これらのイベントが発生したときに呼び出されます。つまり、誰かがウィンドウ内でファイルをマウスで通過すると、クラスの DragEnter が呼び出されます。

また、IDropTarget が拡張するいくつかの関数を実装する必要があります。MSDN で IUnknown を確認してください。

次に、IDataObject パラメータを照会してデータを取得する必要があります。

FORMATETC fdrop = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};

if (SUCCEEDED(pDataObj->QueryGetData(&fdrop)) ){
    STGMEDIUM stgMedium = {0};
    stgMedium.tymed = TYMED_HGLOBAL;
    HRESULT hr = pDataObj->GetData(&fdrop, &stgMedium);
    if (SUCCEEDED(hr))
    {
        HGLOBAL gmem = stgMedium.hGlobal;
        HDROP hdrop = (HDROP)GlobalLock(gmem);
        UINT numOfFiles =  DragQueryFile( (HDROP) hdrop,
                            0xFFFFFFFF,
                           NULL,
                            0
                        );

        TCHAR buffer[MAX_PATH];
        for( int i=0;i<numOfFiles;i++ ){
            UINT charsCopied = DragQueryFile( (HDROP) hdrop,
                            i,
                           buffer,
                            MAX_PATH
                        );
            MessageBox(NULL,buffer,_T("Archivos a copiar: "),MB_OK);


        }
        // use str
        GlobalUnlock(gmem);


        /*TCHAR* str = (TCHAR*)GlobalLock(gmem);
        // use str
        GlobalUnlock(gmem);*/
        ::ReleaseStgMedium(&stgMedium);
    }

}

乾杯!

于 2009-12-12T03:15:10.560 に答える
1

これを投稿した後、編集して、質問は C++ として認定されるように編集されました。この回答は参考のためにここに残しておきます。


「どのようなコーディングが適用されるのか」:

これは、プラットフォームと言語に大きく依存します。たとえば、C#/.NETまたはVB/.NETを介した Windows の例を次に示します。C++、Delphi などの場合、トリックは異なります。

于 2009-01-16T08:44:59.167 に答える
0

COM の Ole ドラッグ アンド ドロップ インターフェイスを使用する必要があります。

于 2009-01-16T15:36:14.980 に答える
0

OLE/COM/ActiveX が登場する前は、次のようなことをしていました。

  • マウス ダウン イベントを受け取った場合は、カーソル位置に注意してください。
  • マウスの動きを受け取り、それが元のポイントから一定の距離を移動した場合、ドラッグ操作を開始しています。ドラッグしているオブジェクトを表すカーソルを作成します (元のカーソル位置から決定されます)。
  • マウス ダウンを受け取った場合: ドラッグが開始されなかった場合はクリックです。それ以外の場合は、ドロップ位置を使用してオブジェクトをどうするかを決定します。

注: これでは、個々のアプリ内だけで、アプリ間でオブジェクトをドラッグすることはできません。

于 2009-01-17T12:31:46.443 に答える