2016-08-10 2 views
0

вот описание моей проблемы:Не удался получить 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? Спасибо заранее.

+0

[Документация] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms678431 (v = vs.85) .aspx) говорит об этом обходным путем, но вы должны инициализировать поля 'typed' и' pUnkForRelease' объекта 'STGMEDIUM', который вы передаете в' GetData() ', чтобы он мог знать, как вы хотите данные и кто будет отвечать за его освобождение. Возможно, вам удастся просто обнулить всю структуру, но вам все равно нужно определить ее как-то, поскольку по умолчанию для стека указана неопределенная информация, которая будет путать 'GetData()'. Но если ClipSpy (сторонняя утилита) также терпит неудачу ... – andlabs

+0

У вас есть основания предполагать, что * FileContents * не должно быть пустым? – IInspectable

+0

Да. Существует решение, написанное на C# (http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C). И автор получает контент, используя формат FileContents. Вот фрагмент: // с помощью интерфейса Com IDataObject получить данные с помощью определенного FORMATETC this.comUnderlyingDataObject.GetData (ref formatetc, out medium) –

ответ

0

кажется, что разработчики в Outlook не придерживаются общего подхода к перетаскиванию n на Windows, описанного в article. Я спросил у microsoft forum, и ответ от их разработчика:

Статья MSDN - это общее описание передачи данных оболочки. I дали вам решение, специфичное для того, как Outlook реализует перетаскивание .

Смежные вопросы