C++剪贴板条目保持覆盖,而不是具有单独的条目

kqlmhetl  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(111)

我正在编写一个程序,从JSON数组中取出所有对象,并将它们复制到剪贴板中,但是,当我打开剪贴板历史记录时,只显示文件中的最后一个对象,因此它们不断地相互覆盖。
这是我的密码:

void loadOldClipboard() {
    // Load the JSON data from our File
    std::ifstream file("pastEntries.json");
    Json::Value root;
    file >> root;
    file.close();
    OpenClipboard(0);
    EmptyClipboard();
    for (const auto& obj : root) {
        std::string entry = obj["clipboardEntry"].asString();
        std::cout << "clipboardEntry: " << entry << std::endl;

        // Allocate global memory for the clipboard data
        HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, entry.size() + 1);
        if (hMem == NULL) {
            // Handle memory allocation error
            CloseClipboard();
            return;
        }

        // Copy the entry to the global memory
        char* pMem = static_cast<char*>(GlobalLock(hMem));
        if (pMem == NULL) {
            // Handle memory locking error
            GlobalFree(hMem);
            CloseClipboard();
            return;
        }
        strcpy_s(pMem, entry.size() + 1, entry.c_str());
        GlobalUnlock(hMem);

        // Set the clipboard data for the current entry
        SetClipboardData(CF_TEXT, hMem);
    }
    CloseClipboard();
}

以防万一我还添加了我当前的JSON文件:

[
    {
        "clipboardEntry": "Entry 1"
    },
    {
        "clipboardEntry": "Entry 2"
    },
    {
        "clipboardEntry": "Entry 3"
    }
]

更新日期:

我尝试在每次循环迭代时打开和关闭剪贴板,但它仍然不起作用。

void loadOldClipboard() {
    // Load the JSON data from our File
    std::ifstream file("pastEntries.json");
    Json::Value root;
    file >> root;
    file.close();

    // Allocate global memory for each string and copy it to the clipboard
    for (const auto& text : root) {
        if (!OpenClipboard(0)) {
            std::cerr << "Failed to open clipboard\n";
            return;
        }

        // Empty the clipboard
        EmptyClipboard();

        std::string entry = text["clipboardEntry"].asString();
        std::cout << "clipboardEntry: " << entry << std::endl;
        // Allocate global memory for the clipboard data
        HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, entry.size() + 1);
        if (hMem == NULL) {
            // Handle memory allocation error
            CloseClipboard();
            return;
        }

        // Copy the text to the global memory
        char* pMem = static_cast<char*>(GlobalLock(hMem));
        if (pMem == NULL) {
            // Handle memory locking error
            GlobalFree(hMem);
            CloseClipboard();
            return;
        }
        strcpy_s(pMem, entry.size() + 1, entry.c_str());
        GlobalUnlock(hMem);

        // Set the clipboard data
        SetClipboardData(CF_TEXT, hMem);

        // Close the clipboard
        CloseClipboard();
    }
}

更新日期:

我让它工作起来,结果是类似于@Halfix提到的,我需要在Sleep()中放置大约1/2 - 1秒的延迟。否则,程序无法正确处理它。

bejyjqdl

bejyjqdl1#

由于@MarioRütsche没有亲自展示最终代码,所以我自己动手。我很快重新创建了它,并以这个新函数结束。看起来问题确实是Windows内置的剪贴板查看器没有正确接收数据,所以我添加了一个1秒的Sleep()

void loadOldClipboard() {
    // Load the JSON data from our File
    std::ifstream file("pastEntries.json");
    Json::Value root;
    file >> root;
    file.close();

    // Allocate global memory for each string and copy it to the clipboard
    for (const auto& text : root) {
        if (!OpenClipboard(0)) {
            std::cerr << "Failed to open clipboard\n";
            return;
        }

        // Empty the clipboard
        EmptyClipboard();

        std::string entry = text["clipboardEntry"].asString();
        std::cout << "clipboardEntry: " << entry << std::endl;
        // Allocate global memory for the clipboard data
        HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, entry.size() + 1);
        if (hMem == NULL) {
            // Handle memory allocation error
            CloseClipboard();
            return;
        }

        // Copy the text to the global memory
        char* pMem = static_cast<char*>(GlobalLock(hMem));
        if (pMem == NULL) {
            // Handle memory locking error
            GlobalFree(hMem);
            CloseClipboard();
            return;
        }
        strcpy_s(pMem, entry.size() + 1, entry.c_str());
        GlobalUnlock(hMem);

        // Set the clipboard data
        SetClipboardData(CF_TEXT, hMem);

        HANDLE hData = GetClipboardData(CF_TEXT);
        char* pszData = static_cast<char*>(GlobalLock(hData));
        std::string clipboardContent = pszData;

        // Close the clipboard
        CloseClipboard();
        Sleep(1000); // Wait for 1000ms before checking again
    }
 }
zzwlnbp8

zzwlnbp82#

这是预期行为。在您调用CloseClipboard()之前,数据不会完全提交(即其他应用无法访问它)。剪贴板允许代码使用 * 不同 * 类型的数据多次调用SetClipboardData(),然后一次性提交它们。但是,由于您在每次迭代中仅设置CF_TEXTCloseClipboard()将仅提交您设置的最后一项。
如果希望剪贴板历史记录单独记录每个CF_TEXT项,则必须在每次迭代时(重新)打开/关闭剪贴板。

相关问题