windows 文件的拖放是如何完成的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/449872/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:49:35  来源:igfitidea点击:

How drag and drop of files is done?

c++windowsdrag-and-drop

提问by kasperasky

as in winamp or vlc player, how to do a file drag and drop? i mean i want to know what sort of coding goes into application? i want to know for c++

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

回答by Eli Bendersky

In pure C/C++ on Windows, start reading about the DragAcceptFilesfunction and the WM_DROPFILESmessage. If you're using a more powerful C++ library (Qt, Wx, etc) check their respective documentation. It would help to know what you use, more specifically.

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

Also, this discussionmay answer your question. If it's what you meant, please close this question.

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

回答by no_ripcord

With com:

与 com:

Create a class that public extends IDropTarget

创建一个公共扩展 IDropTarget 的类

Register your class for drops. Do this in WM_CREATE

注册您的课程以获取滴剂。在 WM_CREATE 中执行此操作

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

In your class you need to override a couple of functions since they are pure virtual:

在您的课程中,您需要覆盖几个函数,因为它们是纯虚拟的:

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;

Each of those functions will get called when those events occur, i.e. when someone pass the mouse in your window with a file DragEnter on your class will get called.

当这些事件发生时,这些函数中的每一个都会被调用,即当有人在你的窗口中传递鼠标时,你的类上的文件 DragEnter 将被调用。

You will also need to implement a couple more functions that IDropTarget extends, check out IUnknown in your MSDN.

您还需要实现 IDropTarget 扩展的更多功能,请查看 MSDN 中的 IUnknown。

Then you need to query IDataObject param to get the data:

然后你需要查询 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);
    }

}

Cheers!

干杯!

回答by Marc Gravell

editafterI posted this, the question was edited to qualify as C++; I'm going to leave this answer here for reference only.

编辑后,我贴这个,这个问题是编辑资格作为C ++; 我将把这个答案留在这里仅供参考。



"what sort off coding goes into application":

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

That depends hugely on the platform and language. For example, here are examples for Windows via C#/.NETor VB/.NET. For C++, Delphi, etc - the tricks will be different.

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

回答by Vinay

You should use COM's Ole Drag and drop interfaces.

您应该使用 COM 的 Ole 拖放界面。

回答by Ferruccio

Before the days of OLE/COM/ActiveX, we would do something like the following:

在 OLE/COM/ActiveX 出现之前,我们会做如下的事情:

  • If we received a mouse down event, take note of cursor position.
  • If we received a mouse movement and it moved a certain distance from the original point then we're starting a drag operation. Build a cursor that represents the object you're dragging (determined from the original cursor position).
  • When we received a mouse down: if dragging never started then it's a click otherwise use the drop position to determine what to do with the object.
  • 如果我们收到鼠标按下事件,请注意光标位置。
  • 如果我们收到鼠标移动并且它从原点移动了一定距离,那么我们开始拖动操作。构建一个表示您正在拖动的对象的光标(根据原始光标位置确定)。
  • 当我们收到鼠标按下时:如果拖动从未开始,那么它是点击,否则使用放置位置来确定如何处理对象。

Note: none of this would allow you to drag objects between apps, just inside individual apps.

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

回答by Rocketmagnet

For almost any question like "How do I do this UI thing?"

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

My answer is always: "Use wxWidgets."

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

Hugo

雨果