c++ - 获取剪贴板数据(CF_UNICODETEXT);

标签 c++ unicode clipboard

请告诉我,为什么我会遇到这个问题:

  • 如果剪贴板包含 unicode 字符(例如俄语),我只会得到第一个选定的单词。 “空格”字符前的第一个单词。

  • 如果剪贴板不包含 unicode 字符(仅限英文),我会获取所选文本的第一个字符。

获取选中的文本:

CStringA getClipboard()
{
     CStringA strData;

     if (OpenClipboard(NULL)){

         HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
         char *pchData = (char*)GlobalLock(hClipboardData);
         strData = pchData;
         GlobalUnlock(hClipboardData);
         CloseClipboard();

    }
    return strData;
}

设置文本:

bool setClipboard(CStringA textToclipboard)
{
    bool success = true;

    if (OpenClipboard(NULL)){

        EmptyClipboard();
        HGLOBAL hClipboardData;
        size_t size = (textToclipboard.GetLength()+1) * sizeof(TCHAR);
        hClipboardData = GlobalAlloc(NULL, size);
        TCHAR* pchData = (TCHAR*)GlobalLock(hClipboardData);
        memcpy(pchData, LPCTSTR(textToclipboard.GetString()), size);
        SetClipboardData(CF_UNICODETEXT, hClipboardData);
        GlobalUnlock(hClipboardData);
        CloseClipboard();
    }

    return success;

}

简单地获取和设置剪贴板内容。

CStringA str = getClipboard();
setClipboard(str);

最佳答案

CF_UNICODETEXT 使用 UTF-16。在 Windows 上,wchar_t 数据元素用于 UTF-16,但您的代码使用的是 charCStringA 与 UTF-16 不兼容。您在这两个函数中不匹配数据,这就是您没有得到预期结果的原因。

一种解决方案是使用 CStringW 而不是 CStringA:

CStringW getClipboard()
{
    CStringW strData;

    if (OpenClipboard(NULL))
    {
        HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
        if (hClipboardData)
        {
            WCHAR *pchData = (WCHAR*) GlobalLock(hClipboardData);
            if (pchData)
            {
                strData = pchData;
                GlobalUnlock(hClipboardData);
            }
        }
        CloseClipboard();
    }
    return strData;
}

bool setClipboard(CStringW textToclipboard)
{
    bool success = true;

    if (OpenClipboard(NULL))
    {
        EmptyClipboard();
        size_t size = (textToclipboard.GetLength()+1) * sizeof(WCHAR);
        HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
        if (hClipboardData)
        {
            WCHAR* pchData = (WCHAR*) GlobalLock(hClipboardData);
            if (pchData)
            {
                memcpy(pchData, (WCHAR*) textToclipboard.GetString(), size);
                GlobalUnlock(hClipboardData);
                SetClipboardData(CF_UNICODETEXT, hClipboardData);
            }
        }
        CloseClipboard();
    }
    return success;
}

如果您需要坚持使用 CStringA,则:

  1. 使用 CF_TEXT 而不是 CF_UNICODETEXT 并让剪贴板为您处理 Ansi 和 Unicode 之间的转换:

    CStringA getClipboard()
    {
        CStringA strData;
    
        if (OpenClipboard(NULL))
        {
            HANDLE hClipboardData = GetClipboardData(CF_TEXT);
            if (hClipboardData)
            {
                CHAR *pchData = (CHAR*) GlobalLock(hClipboardData);
                if (pchData)
                {
                    strData = pchData;
                    GlobalUnlock(hClipboardData);
                }
            }
            CloseClipboard();
        }
        return strData;
    }
    
    bool setClipboard(CStringA textToclipboard)
    {
        bool success = true;
    
        if (OpenClipboard(NULL))
        {
            EmptyClipboard();
            size_t size = (textToclipboard.GetLength()+1) * sizeof(CHAR);
            HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
            if (hClipboardData)
            {
                CHAR* pchData = (CHAR*) GlobalLock(hClipboardData);
                if (pchData)
                {
                    memcpy(pchData, (CHAR*) textToclipboard.GetString(), size);
                    GlobalUnlock(hClipboardData);
                    SetClipboardData(CF_TEXT, hClipboardData);
                }
            }
            CloseClipboard();
        }
        return success;
    }
    
  2. 使用 CF_UNICODETEXT 时手动转换为 UTF-16 或从 UTF-16 转换:

    CStringA getClipboard()
    {
        CStringW strData;
    
        if (OpenClipboard(NULL))
        {
            HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
            if (hClipboardData)
            {
                WCHAR *pchData = (WCHAR*) GlobalLock(hClipboardData);
                if (pchData)
                {
                    strData = pchData;
                    GlobalUnlock(hClipboardData);
                }
            }
            CloseClipboard();
        }
    
        return CStringA((WCHAR*)strData.GetString());
    }
    
    bool setClipboard(CStringA strData)
    {
        CStringW textToclipboard((CHAR*)strData.GetString());
        bool success = true;
    
        if (OpenClipboard(NULL))
        {
            EmptyClipboard();
            size_t size = (textToclipboard.GetLength()+1) * sizeof(WCHAR);
            HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
            if (hClipboardData)
            {
                WCHAR* pchData = (WCHAR*) GlobalLock(hClipboardData);
                if (pchData)
                {
                    memcpy(pchData, (WCHAR*) textToclipboard.GetString(), size);
                    GlobalUnlock(hClipboardData);
                    SetClipboardData(CF_UNICODETEXT, hClipboardData);
                }
            }
            CloseClipboard();
        }
        return success;
    }
    

另一种解决方案是使用 CString 代替 CStringACStringW,然后使用 CF_TEXTCF_UNICODETEXT 取决于 TCHAR 是 Ansi 还是 Unicode:

#ifdef UNICODE
#define CF_TEXT_T CF_UNICODETEXT
#else
#define CF_TEXT_T CF_TEXT
#endif

CString getClipboard()
{
    CString strData;

    if (OpenClipboard(NULL))
    {
        HANDLE hClipboardData = GetClipboardData(CF_TEXT_T);
        if (hClipboardData)
        {
            TCHAR *pchData = (TCHAR*) GlobalLock(hClipboardData);
            if (pchData)
            {
                strData = pchData;
                GlobalUnlock(hClipboardData);
            }
        }
        CloseClipboard();
    }
    return strData;
}

bool setClipboard(CString textToclipboard)
{
    bool success = true;

    if (OpenClipboard(NULL))
    {
        EmptyClipboard();
        size_t size = (textToclipboard.GetLength()+1) * sizeof(TCHAR);
        HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
        if (hClipboardData)
        {
            TCHAR* pchData = (TCHAR*) GlobalLock(hClipboardData);
            if (pchData)
            {
                memcpy(pchData, (TCHAR*) textToclipboard.GetString(), size);
                GlobalUnlock(hClipboardData);
                SetClipboardData(CF_TEXT_T, hClipboardData);
            }
        }
        CloseClipboard();
    }
    return success;
}

关于c++ - 获取剪贴板数据(CF_UNICODETEXT);,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15362859/

相关文章:

python - 语法错误 : Non-ASCII character but no encoding declared

c# - 如何在C#中实现OLE服务器

c++ - forloop 数组行

python - 如何在Python中获取UTF-16(十进制)?

unicode - 哪些字符不存在于 Unicode 中?

c# - 我可以将剪贴板作为命令参数发送吗?

Python获取选定的文本

c++ -/SUBSYSTEM 参数的意义 - msdn

c++ - 我怎样才能解决破坏对象的逻辑错误?

c++ - 减法时整数溢出的种类