Перетаскивание файлов из приложения Qt в MS Edge - PullRequest
1 голос
/ 25 января 2020

У меня есть приложение Qt для Windows, которое содержит список файлов в виджете. Я хочу иметь возможность перетаскивать файлы из этого виджета в другое приложение. Я использую механизм перетаскивания Qt-base, и он работает хорошо в большинстве случаев. Один случай, который не работает, - это перетащить его в браузер MS Edge, например, когда я открываю MS Edge и начинаю писать электронное письмо с mail.google.com, и я хочу добавить файлы как вложение, перетащив их из моего Приложение Qt. Странно, что это работает в Chrome, Firefox, а также в древнем Inte rnet Explorer. Но не в краю. Вот мой минималистичный пример. Попробуйте перетащить файлы из виджета на веб-страницу, которая принимает перетаскивание файла. На моем компьютере это работает для всех браузеров, кроме Edge.

#include <QApplication>
#include <QDrag>
#include <QLabel>
#include <QMimeData>
#include <QMouseEvent>

class Window : public QLabel
{
public:
    void mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton)
        {
            QList<QUrl> urls;
            urls.append(QUrl::fromLocalFile("C:/test/test1"));
            urls.append(QUrl::fromLocalFile("C:/test/test2"));

            QMimeData* mimeData = new QMimeData();
            mimeData->setUrls(urls);

            QDrag* drag = new QDrag(this);
            drag->setMimeData(mimeData);
            drag->exec(Qt::CopyAction);
        }
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Window w;
    w.setText("Drag from here...");
    w.show();
    return a.exec();
}

Обратите внимание, что я передаю данные как text/uri-list MIME-тип. Я наблюдал, как другие приложения ведут себя как источник перетаскивания, и они, кажется, работают нормально - например, при перетаскивании из Проводника файлов, Total Commander et c в MS Edge. Когда я смотрю на типы MIME, которые они отправляют, я вижу также тип application/x-qt-windows-mime;value="Shell IDList Array", который мне не хватает в моем примере. Так что это то, что, как я полагаю, является проблемой, Edge, вероятно, ожидает этот тип данных MS-centri c. Я также хотел бы обернуть данные в этом формате, но я не знаю, как это сделать.

Я предполагаю, что мне придется использовать Win32 API. Поэтому я просмотрел и получил несколько фрагментов, которые должны быть в состоянии создать некоторые полезные структуры данных ...

    QVector<LPITEMIDLIST> idLists;
    for (const QString &nativePath: qAsConst(nativePaths))
    {
        PCWSTR pszFile = PCWSTR(nativePath.utf16());
        LPITEMIDLIST idl = ILCreateFromPathW(pszFile);
        if (idl == nullptr)
        {
            for (LPITEMIDLIST pid : qAsConst(idLists))
                ILFree(pid);

            return nullptr;
        }
        idLists.append(idl);
    }

    IShellItemArray *iArray = nullptr;
    HRESULT result = SHCreateShellItemArrayFromIDLists(UINT(idLists.size()), (LPCITEMIDLIST*)idLists.data(), &iArray);

    for (LPITEMIDLIST pid : qAsConst(idLists))
        ILFree(pid);

Мне кажется, что это способ, который может привести к желаемому результату, но есть еще некоторые шаги отсутствует. Я не знаю, как обернуть эти данные (они вообще пригодятся?) В QMimeData::setData(). Любые идеи?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...