вот описание моей проблемы:Не удался получить FileContents от внешнего вида при выполнении падения
Я тащу почту от внешнего вида и поместите его на моей форме и все эти методы не смог получить FileContents от IDataObject, который я получаю, когда произошло событие drop .:
1) Я пробовал C++ framework Qt ver 5.5. для получения данных и получил следующие результаты:
Это форматы и доступны байты получили для каждого формата:
"application/x-qt-windows-mime;value=\"RenPrivateSourceFolder\"" 206
"application/x-qt-windows-mime;value=\"RenPrivateLatestMessages\"" 420
"application/x-qt-windows-mime;value=\"RenPrivateMessages\"" 420
"application/x-qt-windows-mime;value=\"RenPrivateItem\"" 0
"application/x-qt-windows-mime;value=\"FileGroupDescriptor\"" 668
"application/x-qt-windows-mime;value=\"FileGroupDescriptorW\"" 1188
"application/x-qt-windows-mime;value=\"FileNameW\"" 0
"application/x-qt-windows-mime;value=\"FileContents\"" 0
"application/x-qt-windows-mime;value=\"Object Descriptor\"" 194
"text/plain" 166
"application/x-qt-windows-mime;value=\"Csv\"" 98
, как вы можете увидеть формат FileContents возвращает нулевой ByteArray.
2) Хорошо, я подумал, что проблема может быть связана с реализацией функции drag'n'drop qt, поэтому я реализовал подход win API для реализации интерфейса IDropTarget, включающий регистрацию моего окна, чтобы иметь возможность поймать
событие падения. Когда происходит событие drop, я получаю IDataObject, который должен содержать отбрасываемые данные.
Все результаты те же самые. Я получил нулевой элемент структуры FileContents. Вот фрагмент моего кода:
STDMETHODIMP QDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, LPDWORD pdwEffect)
{
static UINT cf = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
static FORMATETC fmtetc = { cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL };
//getting the description of the files being dropped
STGMEDIUM medium;
HRESULT hr = pDataObj->GetData(&fmtetc, &medium);
if (!FAILED(hr))
{
FILEGROUPDESCRIPTOR* files = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(medium.hGlobal));
int items_count=files->cItems;
for (int i=0;i<items_count;i++){
QString filename=QString::fromWCharArray(files->fgd[i].cFileName).toUtf8().data();//getting filenames - works as expected
}
static UINT cf = RegisterClipboardFormat(CFSTR_FILECONTENTS);
static FORMATETC fileContentFormat = { cf, NULL, DVASPECT_CONTENT,0, TYMED_HGLOBAL|TYMED_ISTORAGE|TYMED_ISTREAM};
STGMEDIUM medium2;
HRESULT hr2 = pDataObj->GetData(&fileContentFormat, &medium2);
if (!FAILED(hr2))
{
qDebug()<<GlobalSize(medium2.hGlobal);//zero result
qDebug()<<(medium2.pstg==NULL);//zero result
qDebug()<<(medium2.pstm==NULL);//zero result
qDebug()<<"Filecontents extracted";
.......
3) Я загрузил утилиту ClipSpy, которая позволяет копировать файлы на его форму и показать Avaible форматы и размер структуры, представленной каждым форматом. И снова размер filecontent равен нулю.
Можете ли вы сказать мне, что это проблема с перспективой? Действительно ли Outlook способен передавать содержимое сообщения через подход WINAPI drag'n'drop через объекты COM? Спасибо заранее.
[Документация] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms678431 (v = vs.85) .aspx) говорит об этом обходным путем, но вы должны инициализировать поля 'typed' и' pUnkForRelease' объекта 'STGMEDIUM', который вы передаете в' GetData() ', чтобы он мог знать, как вы хотите данные и кто будет отвечать за его освобождение. Возможно, вам удастся просто обнулить всю структуру, но вам все равно нужно определить ее как-то, поскольку по умолчанию для стека указана неопределенная информация, которая будет путать 'GetData()'. Но если ClipSpy (сторонняя утилита) также терпит неудачу ... – andlabs
У вас есть основания предполагать, что * FileContents * не должно быть пустым? – IInspectable
Да. Существует решение, написанное на C# (http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C). И автор получает контент, используя формат FileContents. Вот фрагмент: // с помощью интерфейса Com IDataObject получить данные с помощью определенного FORMATETC this.comUnderlyingDataObject.GetData (ref formatetc, out medium) –