2015-07-01 3 views
5

Я делаю следующие вещи:Почему программа Qt обрабатывает данные буфера обмена при вставке из буфера обмена во внешнюю программу?

1) Копирование данных в буфер обмена в моей программе Qt в Windows.

QApplication::clipboard()->setText(data); 

2) Вставьте данные во внешнюю программу (notepad.exe). После этого моя программа начинает обрабатывать данные буфера обмена. Это вызывает определенные методы Windows:

QWindowsOleDataObject::GetData(...); 
... QWindowsMimeText::convertFromMime(...); 

Это проблема, потому что, когда размер данных в буфере обмена большая моя программа не на выделения памяти в этих методах.

Я не могу понять, потому что стек вызовов довольно странно:

qwindowsd.dll!QWindowsMimeText::convertFromMime(const tagFORMATETC & formatetc, const QMimeData * mimeData, tagSTGMEDIUM * pmedium) Line 606 C++ 
qwindowsd.dll!QWindowsOleDataObject::GetData(tagFORMATETC * pformatetc, tagSTGMEDIUM * pmedium) Line 144 C++ 
[External Code] 
Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 740 C++ 
qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 73 C++ 
Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 129 C++ 
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 204 C++ 
Qt5Cored.dll!QCoreApplication::exec() Line 1188 C++ 
Qt5Guid.dll!QGuiApplication::exec() Line 1508 C++ 
Qt5Widgetsd.dll!QApplication::exec() Line 2957 C++ 
main(int argc, char * * argv) Line 759 C++ 

Это некоторая внутренняя работа Qt, я не знаю, как воздействовать на него.

ответ

1

Qt может оптимизировать использование «внутреннего» буфера обмена. Таким образом, QApplication::clipboard()->setText(data); на самом деле не копирует data в буфер обмена Windows - вы можете вставить его в одно и то же приложение Qt, поэтому копирование в буфер обмена Windows и обратно не требуется. Только при использовании внешнего приложения происходит реальное копирование.

Qt, вероятно, регистрирует поставщика данных OLE в качестве «источника данных буфера обмена», и Windows использует его, когда данные буфера обмена необходимы во внешнем приложении.

Таким образом, большие данные приведены в data с самого начала.

Источники: реализация Qt Clipboard для Windows, QWindowsClipboard использует: OleSetClipboard, которая принимает указатель на источник данных, а не сами данные

+0

Спасибо! Звучит логически хорошо. Это ваша гипотеза или она работает так, как вы описали? Не могли бы вы поделиться ссылкой на какую-нибудь документацию, пожалуйста, если она у вас есть? – Deutsche

+0

@ Deutsche это было предположение, основанное на том, как это сработало некоторое время назад, глядя на код - кажется, все еще адекватным (ссылки в отредактированном ответе) – Hcorg

+0

Отлично! Спасибо за ответ, это объясняет проблему. Если вы так опытны в этой теме, возможно, вы знаете, как поймать эту ситуацию (bad_alloc в этом Qt-коде при обработке событий) и правильно ли продолжить работу программного обеспечения? – Deutsche

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