Чтение окон буфера обмена в цикле в c ++ [дубликат]

Из Разбор имени файла в пакетном файле и другие идиомы - Real-How [to] :

Путь (без диска), где скрипт: ~ p0

Диск, где скрипт: ~ d0

2
задан KKastaneda 1 July 2016 в 16:25
поделиться

1 ответ

GetClipboardData() - это функция Win32 API.

Обработчик, возвращенный GetClipboardData(), должен быть сначала заблокирован с помощью GlobalLock(), после чего вы можете получить char* указатель текста ANSI в буфере обмена (обратите внимание, что если вы хотите получить текст Юникода, вы должны использовать формат CF_UNICODETEXT ).

Пример кода для извлечения текста из буфера обмена и сохранить его в удобном экземпляре класса std::string (управление ошибками опущено для простоты):

std::string GetClipboardText()
{
  // Try opening the clipboard
  if (! OpenClipboard(nullptr))
    ... // error

  // Get handle of clipboard object for ANSI text
  HANDLE hData = GetClipboardData(CF_TEXT);
  if (hData == nullptr)
    ... // error

  // Lock the handle to get the actual text pointer
  char * pszText = static_cast<char*>( GlobalLock(hData) );
  if (pszText == nullptr)
    ... // error

  // Save text in a string class instance
  std::string text( pszText );

  // Release the lock
  GlobalUnlock( hData );

  // Release the clipboard
  CloseClipboard();

  return text;
}

Вы можете использовать шаблон C ++ RAII и управлять условиями ошибки с использованием исключений, примерно так:

#include <exception>
#include <iostream>
#include <ostream>
#include <stdexcept>
#include <string>
#include <windows.h>
using namespace std;

class RaiiClipboard
{
public:
  RaiiClipboard()
  {
    if (! OpenClipboard(nullptr))
      throw runtime_error("Can't open clipboard.");
      // ... or define some custom exception class for clipboard errors.
  }

  ~RaiiClipboard()
  {
    CloseClipboard();
  }

  // Ban copy   
private:
  RaiiClipboard(const RaiiClipboard&);
  RaiiClipboard& operator=(const RaiiClipboard&);
};

class RaiiTextGlobalLock
{
public:
  explicit RaiiTextGlobalLock(HANDLE hData)
    : m_hData(hData)
  {
    m_psz = static_cast<const char*>(GlobalLock(m_hData));
    if (! m_psz)
      throw runtime_error("Can't acquire lock on clipboard text.");  
  }

  ~RaiiTextGlobalLock()
  {
    GlobalUnlock(m_hData);
  }

  const char* Get() const
  { 
    return m_psz;
  }

private:
  HANDLE m_hData;
  const char* m_psz;

  // Ban copy
  RaiiTextGlobalLock(const RaiiTextGlobalLock&);
  RaiiTextGlobalLock& operator=(const RaiiTextGlobalLock&);
};

string GetClipboardText()
{
  RaiiClipboard clipboard;

  HANDLE hData = GetClipboardData(CF_TEXT);
  if (hData == nullptr)
    throw runtime_error("Can't get clipboard text.");

  RaiiTextGlobalLock textGlobalLock(hData);
  string text( textGlobalLock.Get() );

  return text;
}

int main()
{
  static const int kExitOk = 0;
  static const int kExitError = 1;
  try
  {
    cout << GetClipboardText() << endl;
    return kExitOk;
  }
  catch(const exception& e)
  {
    cerr << "*** ERROR: " << e.what() << endl;
    return kExitError;
  }
}
25
ответ дан Mr.C64 18 August 2018 в 00:49
поделиться
  • 1
    Плохой вопрос, очень хороший ответ. Фрагмент был очень полезен. – PTS 15 March 2014 в 02:48
  • 2
    @PaulGreen: Спасибо. Я рад, что это помогло. – Mr.C64 15 March 2014 в 02:54
  • 3
    @ Mr.C64 почему он работает, даже когда я не блокирую ручку с GlobalLock? – jave.web 26 November 2014 в 14:53
Другие вопросы по тегам:

Похожие вопросы: