我是否错误地使用Windows剪贴板?

时间:2011-10-21 00:16:59

标签: c++ winapi clipboard

我有一些代码要复制和粘贴:

void WinClipboard::copy( const std::string& input )
    {
        LPWSTR  lptstrCopy; 
        HGLOBAL hglbCopy; 
        std::wstring text;

        text = _winUTF8ToUTF16(input);

        // Open the clipboard, and empty it. 

        if (!OpenClipboard(NULL)) 
            return; 

        EmptyClipboard(); 

        // Allocate a global memory object for the text. 
        hglbCopy = GlobalAlloc(GMEM_MOVEABLE, 
            ((text.length() + 1) * sizeof(WCHAR))); 

        if (hglbCopy == NULL) 
        { 
            CloseClipboard(); 
            return; 
        } 

        // Lock the handle and copy the text to the buffer. 
        lptstrCopy = (LPWSTR)GlobalLock(hglbCopy); 
        memcpy(lptstrCopy, text.c_str(), 
            (text.length() + 1) * sizeof(WCHAR) ); 
        lptstrCopy[(text.length() + 1) * sizeof(WCHAR)] = (WCHAR) 0;    // null character 
        GlobalUnlock(hglbCopy); 

        // Place the handle on the clipboard. 

        SetClipboardData(CF_UNICODETEXT, hglbCopy); 


        // Close the clipboard. 

        CloseClipboard(); 
    }

    std::string WinClipboard::paste()
    { 
        HGLOBAL   hglb; 
        LPWSTR    lptstr; 

        std::string result;
        std::wstring input;

        // get the clipboard text. 

        if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) 
            return result;

        if (!OpenClipboard(NULL)) 
            return result; 

        hglb = GetClipboardData(CF_UNICODETEXT); 
        if (hglb != NULL) 
        { 
            lptstr = (LPWSTR)GlobalLock(hglb); 


            if (lptstr != NULL) 
            { 
                GlobalUnlock(hglb); 
                input = lptstr;
                result = _winUTF16ToUTF8(input);
            } 
            CloseClipboard(); 
        }
        return result;
    }

除非我快速执行CTRL C然后按CTRL-V(基本上调用上面的复制和粘贴函数),整个应用程序冻结,它的效果很好。

我忘记检查某些内容或忘记发布资源了吗?

3 个答案:

答案 0 :(得分:5)

我在paste()函数中看到两个问题:

1)在将剪贴板数据分配给GlobalUnlock()变量之前,它正在调用std::wstring。您需要撤消这些操作 - 复制数据后调用GlobalUnlock(),而不是之前。

2)如果CloseClipboard()失败,则不会调用GetClipboardData()

答案 1 :(得分:1)

这里有很棒的文章,对于那些仍然在这个链接上磕磕绊绊的人来说,有关如何做到这一点的有用提示(BUMP!): http://www.codeproject.com/Articles/2242/Using-the-Clipboard-Part-I-Transferring-Simple-Tex

答案 2 :(得分:1)

另一个"问题"。

copy函数中:

该行

lptstrCopy[(text.length() + 1) * sizeof(WCHAR)] = (WCHAR) 0;

应该是

lptstrCopy[text.length() + 1] = (WCHAR) 0;

避免溢出/堆损坏。