5

在 winamp 或 vlc 播放器中,如何进行文件拖放?我的意思是我想知道什么样的编码进入应用程序?我想知道 C++

4

5 回答 5

15

在 Windows 上的纯 C/C++ 中,开始阅读有关DragAcceptFiles 函数和WM_DROPFILES消息的信息。如果您使用的是更强大的 C++ 库(Qt、Wx 等),请查看它们各自的文档。更具体地说,这将有助于了解您使用的内容。

此外,此讨论可能会回答您的问题。如果这是您的意思,请关闭此问题。

于 2009-01-16T09:53:19.933 回答
2

与 com:

创建一个公共扩展 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#/.NETVB/.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 回答