У меня есть приложение 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()
. Любые идеи?