'OpenClipboard crashes with CLIPBRD_E_CANT_OPEN

I have a problem with opening clipboard multiple times. It opens up fine on the first call, however, my program needs to access the clipboard several times, but shuts down on the second call of OpenClipboard(NULL) with the CLIPBRD_E_CANT_OPEN error).

This is a function that opens the clipboard

    void Translator::process_copied()
    {
       //cout << "processing" << endl;

       if (OpenClipboard(NULL))
       {
           HANDLE clip;
           clip = GetClipboardData(CF_UNICODETEXT);
           Relayout((WCHAR*)clip);
 
           HANDLE res = GlobalAlloc(GMEM_FIXED, sizeof(WCHAR)*wcslen((WCHAR*)clip)+1);
           res = clip;
           EmptyClipboard();
           SetClipboardData(CF_UNICODETEXT, res);       
           CloseClipboard();
       }
       else
       {
           std::cout << GetLastError();
           //throw clipboard_did_not_open;
           //cout << "error in opening clipboard" << endl;
       }
   }

I suspect that the problem appears in the SetClipboardData() function, because if I remove it, clipboard doesn't have any problem opening multiple times. The same goes to res = clip; line.

I am new to WinAPI and C++ in general, so I apologize if my question is silly.



Solution 1:[1]

#include <Windows.h>

vvvWorking Function to Copy Text into Clipboard - Use it if neadedvvv
Without Warnings

This Function Puts Text into ClipBoard

bool copyTextToClipboard(HWND hwnd, LPWSTR text, INT textLength) {

    /// <summary>
    /// This Function Puts Text into ClipBoard
    /// </summary>
    /// <param name="hwnd">newClipBoardOwner</param>
    /// <param name="text">Text into ClipBoard</param>
    /// <param name="textLength">TextLength</param>
    /// <returns>If Succeeded Returns True, but If not False</returns>

    if (OpenClipboard(hwnd)) {
        HGLOBAL CopyData = { 0 };
        void *buffer = NULL;
        EmptyClipboard();
        CopyData = GlobalAlloc(GMEM_FIXED, sizeof(TCHAR) * textLength);
        if (CopyData != NULL) {
            buffer = GlobalLock(CopyData);
        }
        if (buffer != NULL) {
            memcpy(buffer, (void*)text, sizeof(TCHAR) * textLength);
            GlobalUnlock(CopyData);
            SetClipboardData(CF_UNICODETEXT, CopyData);
            CloseClipboard();
            return true;
        }
        CloseClipboard();
        return false;
    }
    return false;

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1