При каких обстоятельствах GetClipboardData(CF_TEXT) возвращает NULL?

У меня есть эта периодически возникающая проблема, которая сводит меня с ума в течение долгого времени: в моей программе GetClipboardData(CF_TEXT) успешно выполняется в 90% (или около того) времени, но время от времени возвращает NULL.

Это несмотря на то, что OpenClipboard() всегда успешно (и возвращаемое значение проверяется) перед вызовом GetClipboardData(CF_TEXT).

Обратите внимание, что коэффициент успеха 90% относится к той же самой странице! (т.е. я знаю, что там есть контент CF_TEXT)

Примечание. Когда происходит сбой, я немедленно вызываю GetLastError(), но все, что он возвращает, это: "Операция успешно завершена".

Рассматриваемый код так же прост, как:

if (::OpenClipboard(hwndW))
{
  HANDLE handleClip = ::GetClipboardData(CF_TEXT);
  if (handleClip == NULL)
    dw = GetLastError()
}

Что может ввести неправильный код GetLastError() в это?

Есть идеи, что может вызвать такое противоречивое поведение?

Возможно ли, что какой-то другой процесс блокирует буфер обмена? Если так, как я могу вернуть это?

Как устранить неполадки или отладить что-то подобное?

2 ответа

Решение

Я выполнил поиск в Google и нашел кого-то еще с похожей проблемой (прокрутите вниз, чтобы найти конкретный ответ), которая оказалась из-за повторного входа. Вы вызываете EmptyClipboard() где-нибудь, а затем реагируете на изменения? Возможно, у вас есть проблема с повторным входом.

Обновление после предоставленного фрагмента кода
В коде, который вы разместили, условие неверно перед вызовом GetLastError, Вы называете это только тогда, когда получаете ненулевой результат, а не когда получаете NULL результат. Если вы исправите это, вы должны получить лучший ответ от GetLastError, Эта статья MSDN должна помочь в расшифровке, что результат GetLastError на самом деле означает.

Обновить после исправления фрагмента кода
Я предполагаю, что вы столкнулись с расой, когда какое-то другое приложение обращается к буферу обмена. Я бы порекомендовал проверить, есть ли у вас запущенные другие инструменты, которые могли бы сделать это.

Вы используете WebRoot SecureAnywhere? Это функция Identity Shield автоматически очищает буфер обмена, если недопустимое приложение (в основном все, что не было предварительно одобрено) пытается извлечь текст из буфера обмена, который был помещен в буфер обмена защищенным приложением (включает в себя множество браузеров и почтовых клиентов дефолт). Когда это произойдет, GetClipboardData(CF_TEXT) вернет NULL, даже если предыдущий вызов IsClipboardFormatAvailable(CF_TEXT) вернул истину.

Другие вопросы по тегам