C++ 获取剪贴板数据(CF_TEXT)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14762456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:40:05  来源:igfitidea点击:

GetClipboardData(CF_TEXT)

c++winapiclipboard

提问by behnam27

How to use GetClipboardData(CF_TEXT);without calling and use process id of this in C++?
and which libary does GetClipboardData(CF_TEXT)belong to?

如何GetClipboardData(CF_TEXT);在 C++ 中不调用和使用 this 的进程 id 的情况下使用?
哪个图书馆GetClipboardData(CF_TEXT)属于?

回答by Mr.C64

GetClipboardData()is a Win32 API function.

GetClipboardData()是一个 Win32 API 函数。

The handle returned by GetClipboardData()must be first locked with GlobalLock(), then you can retrieve the char*pointer of the ANSI text in the clipboard (note that if you want to retrieve Unicode text, you should use the CF_UNICODETEXTformat).

返回的句柄GetClipboardData()必须先用 锁定GlobalLock(),然后才能char*在剪贴板中检索ANSI文本的指针(注意,如果要检索Unicode文本,应使用CF_UNICODETEXT格式)。

A sample code to retrieve the text from the clipboard and store it in a convenient std::stringclass instance follows (error management omitted for simplicity):

下面是从剪贴板检索文本并将其存储在方便的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;
}

You can use C++ RAII pattern and manage error conditions using exceptions, something like this:

您可以使用 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;
  }
}