在QT应用程序和Windows Explorer之间剪切和粘贴剪贴板交换



我有一个简单的文件处理小部件,可以从/到剪贴板复制/剪切/粘贴所选文件。我希望能够在此窗口小部件和Windows Explorer之间使用这些命令来交换文件(可能是其他文件管理器,例如总指挥官或免费指挥官)。我已经发现我可以使用QMimeData::setUrls()将文件名作为QList<QUrl>存储在剪贴板上,并类似地将它们存储在剪贴板上。这样,我就可以在小部件和上述文件管理器之间复制和粘贴,因为它们似乎使用相同的格式来存储文件名。但是我不知道如何将项目切成剪贴板(即文件粘贴后删除)。我假设接收器(粘贴数据的应用程序)负责删除剪切文件。在这种情况下,必须以某种方式在剪贴板数据中编码,以使文件被剪切而不是复制,可以通过接收应用程序检索此信息。这是怎么做的?还是还有其他方法?我知道这是可能的,因为这在Windows Explorer和Free Commander之间完美地工作。IE。当您在Window Explorer中剪切文件并将其粘贴到免费指挥官时,将删除原始文件,反之亦然。

更新:我发现MIME数据"Preferred DropEffect"的另一部分可以具有5(副本)或2(剪切)的值。当我将QByteArray设置为对应于值52整数的4个字节时,我可以区分Windows Explorer启动剪切还是复制。如果剪切,我可以移动文件而不是复制。它运行良好。不幸的是,这仍然只有从Windows Explorer到QT应用程序的一种方法。我仍然找不到相反方向不起作用的原因。还有其他一些MIME数据对我来说很难解码。也许有钥匙。

更新2:复制Behvaiour的模拟代码在这里。确保存在该程序中的文件硬编码。尝试运行程序,关闭窗口后,打开Windows Explorer转到任意文件夹,您可以在其中写入并按Ctrl V ...然后文件的副本应显示在该目录中,但不会从源目录中删除。下面的程序使用常数2,这意味着剪切而不是复制,这意味着原始文件应消失。

#include <QApplication>
#include <QClipboard>
#include <QDataStream>
#include <QMimeData>
#include <QUrl>
#include <QWidget>
int main(int argc, char *argv[])
{
    QApplication application(argc, argv);
    auto mimeData = new QMimeData;
    // store the URL to files which I want to cut
    QList<QUrl> urls;
    urls.append(QUrl::fromLocalFile("C:/mypath/myfile.txt")); // use your path or make sure this file exist
    mimeData->setUrls(urls);
    // store drop effect indicating whether I want to cut or copy
    int dropEffect = 2; // 2 for cut and 5 for copy
    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly);
    stream << dropEffect;
    mimeData->setData("Preferred DropEffect", data);
    QApplication::clipboard()->setMimeData(mimeData);
    QWidget window;
    window.show();
    return application.exec();
}

另请参见如何以系统标准符号表格进行编程/复制/从Windows剪贴板中获取/从Windows剪贴板获取文件?和https://msdn.microsoft.com/en-us/library/windows/desktop/bb776904(v = vs.85).aspx#delete_on_paste

看来我找到了答案。字节订单是错误的,由于某种原因,它必须是小的(QT中的默认顺序)。因此,示例中的代码应为:

QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::LittleEndian);
stream << dropEffect;

以这种方式,其他文件经理能够使用我的QT应用程序使用复制/剪切和粘贴进行互操作。解码剪贴板内容的反转过程留给了读者(这并不困难,只需扭转将数据编码为剪贴板的操作)即可。当然,还必须处理文件复制或移动/删除,这要做更多的工作,但它很简单。

所以我错了,我实际上是在寻找一个错误...感谢Scopchanov强迫我写最小的代码!:)

最新更新