如何拖放文件?

时间:2009-01-16 08:42:02

标签: c++ windows drag-and-drop

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

6 个答案:

答案 0 :(得分:13)

在Windows上的纯C / C ++中,开始阅读DragAcceptFiles函数和WM_DROPFILES消息。如果您正在使用功能更强大的C ++库(Qt,Wx等),请查看各自的文档。更具体地说,了解你的用途会有所帮助。

此外,this discussion可能会回答您的问题。如果这是你的意思,请关闭这个问题。

答案 1 :(得分:1)

在发布之后

编辑 ,编辑问题以符合C ++标准;我将在此留下这个答案仅供参考。


“什么样的编码进入应用程序”:

这在很大程度上取决于平台和语言。例如,以下是通过C#/.NETVB/.NET的Windows示例。对于C ++,Delphi等 - 技巧会有所不同。

答案 2 :(得分:1)

使用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);
    }

}

干杯!

答案 3 :(得分:0)

你应该使用COM的Ole拖放接口。

答案 4 :(得分:0)

在OLE / COM / ActiveX之前,我们会做类似以下的事情:

  • 如果我们收到了鼠标停止事件, 注意光标位置。
  • 如果我们收到了鼠标移动并且 它移动了一定距离 原点然后我们开始了 拖动操作。构建一个游标 表示您正在拖动的对象 (根据原始光标确定 位置)。
  • 当我们收到鼠标时:如果拖动从未开始,那么只需点击一下,否则使用掉落 确定如何处理的位置 对象。

注意:这些都不允许您在应用之间拖动对象,只是在单个应用内。

答案 5 :(得分:0)

对于几乎所有问题,例如“我如何做这个UI的事情?”

我的回答总是:“使用wxWidgets。”

雨果