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

huangapple go评论127阅读模式
英文:

C++ Clipboard entries keep overwriting instead of having separate entries

问题

这是您提供的代码的中文翻译部分:

void loadOldClipboard() {
    // 从文件加载JSON数据
    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;

        // 为剪贴板数据分配全局内存
        HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, entry.size() + 1);
        if (hMem == NULL) {
            // 处理内存分配错误
            CloseClipboard();
            return;
        }

        // 将数据复制到全局内存
        char* pMem = static_cast<char*>(GlobalLock(hMem));
        if (pMem == NULL) {
            // 处理内存锁定错误
            GlobalFree(hMem);
            CloseClipboard();
            return;
        }
        strcpy_s(pMem, entry.size() + 1, entry.c_str());
        GlobalUnlock(hMem);

        // 为当前条目设置剪贴板数据
        SetClipboardData(CF_TEXT, hMem);
    }
    CloseClipboard();
}
[
    {
        "clipboardEntry": "Entry 1"
    },
    {
        "clipboardEntry": "Entry 2"
    },
    {
        "clipboardEntry": "Entry 3"
    }
]

请注意,这些是您提供的代码和JSON文件的中文翻译部分。如果您需要进一步的帮助或解释,请随时提出。

英文:

I am writing a program that takes all objects from a JSON array and copies them into the clipboard. However, when I open the Clipboard history only the last object from the file is shown, therefore they keep overwriting each other.

This is my Code:

void loadOldClipboard() {
    // Load the JSON data from our File
    std::ifstream file(&quot;pastEntries.json&quot;);
    Json::Value root;
    file &gt;&gt; root;
    file.close();
    OpenClipboard(0);
    EmptyClipboard();
    for (const auto&amp; obj : root) {
        std::string entry = obj[&quot;clipboardEntry&quot;].asString();
        std::cout &lt;&lt; &quot;clipboardEntry: &quot; &lt;&lt; entry &lt;&lt; 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&lt;char*&gt;(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();
}

just in case I also added my current JSON File:

[
	{
		&quot;clipboardEntry&quot;: &quot;Entry 1&quot;
	},
	{
		&quot;clipboardEntry&quot;: &quot;Entry 2&quot;
	},
	{
		&quot;clipboardEntry&quot;: &quot;Entry 3&quot;
	}
]

UPDATE:

I tried opening and closing the clipboard on each loop iteration, but it still doesn't work.

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

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

        // Empty the clipboard
        EmptyClipboard();

        std::string entry = text[&quot;clipboardEntry&quot;].asString();
        std::cout &lt;&lt; &quot;clipboardEntry: &quot; &lt;&lt; entry &lt;&lt; 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&lt;char*&gt;(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();
    }
}

UPDATE:

I got it to work, it turns out that similar to what @Halfix mentioned, I needed to put in a Sleep() delay of around 1/2 - 1 second. Otherwise, the program couldn't process it properly.

答案1

得分: 0

这是预期行为。在调用CloseClipboard()之前,数据并没有完全提交(即,其他应用程序无法访问它)。剪贴板允许代码多次调用SetClipboardData(),并使用不同类型的数据,然后一次性提交它们。但是,由于您在每次迭代中仅设置了CF_TEXTCloseClipboard()将仅提交您设置的最后一个项目。

如果您希望剪贴板历史记录每个CF_TEXT项目单独,您将需要在每次迭代中(重新)打开/关闭剪贴板。

英文:

This is expected behavior. Until you call CloseClipboard(), the data is not fully committed (ie, other apps can't access it). The clipboard allows code to call SetClipboardData() multiple times with different types of data, and then commit them in one go. But, since you are setting only CF_TEXT on every iteration, CloseClipboard() will commit only the last item that you set.

If you want the clipboard history to record every CF_TEXT item individually, you will have to (re-)open/close the clipboard on each iteration.

答案2

得分: 0

自 @MarioRütsche 未展示最终代码,我主动承担了这个任务。我迅速重新创建了它,并得到了这个新函数。看起来问题确实与 Windows 内置的剪贴板查看器未正确接收数据有关,因此我添加了 Sleep() 1 秒。

void loadOldClipboard() {
    // 从我们的文件中加载 JSON 数据
    std::ifstream file("pastEntries.json");
    Json::Value root;
    file >> root;
    file.close();

    // 为每个字符串分配全局内存并将其复制到剪贴板
    for (const auto& text : root) {
        if (!OpenClipboard(0)) {
            std::cerr << "无法打开剪贴板\n";
            return;
        }

        // 清空剪贴板
        EmptyClipboard();

        std::string entry = text["clipboardEntry"].asString();
        std::cout << "clipboardEntry: " << entry << std::endl;
        // 为剪贴板数据分配全局内存
        HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, entry.size() + 1);
        if (hMem == NULL) {
            // 处理内存分配错误
            CloseClipboard();
            return;
        }

        // 将文本复制到全局内存
        char* pMem = static_cast<char*>(GlobalLock(hMem));
        if (pMem == NULL) {
            // 处理内存锁定错误
            GlobalFree(hMem);
            CloseClipboard();
            return;
        }
        strcpy_s(pMem, entry.size() + 1, entry.c_str());
        GlobalUnlock(hMem);

        // 设置剪贴板数据
        SetClipboardData(CF_TEXT, hMem);

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

        // 关闭剪贴板
        CloseClipboard();
        Sleep(1000); // 在再次检查之前等待1000毫秒
    }
}
英文:

Since @MarioRütsche didn't show the final code himself, I took it upon myself. I quickly recreated it and ended up with this new function. It looks like the problem was indeed with the built-in Clipboard Viewer from Windows not properly receiving the Data, so I added a Sleep() of 1 second.

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


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

        // Empty the clipboard
        EmptyClipboard();

        std::string entry = text[&quot;clipboardEntry&quot;].asString();
        std::cout &lt;&lt; &quot;clipboardEntry: &quot; &lt;&lt; entry &lt;&lt; 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&lt;char*&gt;(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&lt;char*&gt;(GlobalLock(hData));
        std::string clipboardContent = pszData;

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

huangapple
  • 本文由 发表于 2023年3月15日 19:51:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75744319.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定