c++ 将Unicode文本放置在具有NULL所有者窗口的剪贴板上时出现意外行为

gfttwv5a  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(100)

我尝试将正在使用的Windows桌面应用程序中的文本放置到剪贴板上,但出现了一些我不理解的行为。
我使用的函数如下:

bool Clipboard::CopyText(const XStringW& txt)
{
    size_t memsize = sizeof(wchar_t) * (txt.Length() + 1);
    HGLOBAL glob = GlobalAlloc(GMEM_MOVEABLE, memsize);
    if (glob != NULL)
    {
        void* mem = GlobalLock(glob);
        if (mem != NULL)
        {
            memcpy(mem, (LPCWSTR) txt, memsize);
            GlobalUnlock(glob);

            HANDLE handle = NULL;

            if (OpenClipboard(NULL))
            {
                EmptyClipboard();
                handle = SetClipboardData(CF_UNICODETEXT, glob);
                ASSERT(handle != NULL);
                CloseClipboard();
            }

            return handle != NULL;
        }
        else

字符串
else之后发生的事情并不特别重要。
如果我执行上面的代码块,一切实际上都像它应该的那样工作。这对我来说很奇怪,因为根据documentation
如果应用程序在hwnd设置为NULL的情况下调用OpenClipboard,则EmptyClipboard将剪贴板所有者设置为NULL;这导致SetClipboardData失败。
但我发现它的工作,因为它应该。
但是,我只是添加了EmptyClipboard()作为实验。在此之前,我的代码无法正常工作。假设我从Word文档中放置文本"Hello"。然后我从应用程序中复制了一个数字999。如果我尝试粘贴到Excel或Word(例如),它会粘贴"Hello"。但是,如果我在Excel中选择"Paste Special"并粘贴为文本,它将粘贴"999"。因此,它将工作,但只有当使用非默认粘贴。
如果我添加EmptyClipboard()(按照我上面的代码),它可以完美地工作。它清除了之前存在的东西。但根据文件,应该不会。
有人能帮我理解吗?

mlmc2os5

mlmc2os51#

我不知道该如何回答这个问题,除了:
“因为文件上是这么说的。”tm
就这样吧文档和其中提供的示例明确指出,您必须调用,以便 *(伪代码):

if(::OpenClipboard(hwnd)) {
    if(::EmptyClipboard()) {
        //Copy data...
        ::SetClipboardData(/*...*/)'
    }
    ::CloseClipboard();
}

字符串
上面还写着:“在调用OpenClipboard * 之前,请先使用窗口的适当句柄 * 调用EmptyClipboard *”。
做不到这一点,然后想知道为什么它不起作用是一个挫折的练习。

  • 在某些情况下,响应特定WM消息不应调用::OpenClipboard,但在此不适用。
m528fe3b

m528fe3b2#

这更像是一个猜测,而不是一个正确的答案,但我做了几个测试,发现了有趣的结果。我有一个假设,它的工作方式取决于你调用它的线程类型。
例如,如果您从无窗口线程/进程调用OpenClipboard(NULL),它应该仍然工作,并给予您访问剪贴板。这是合乎逻辑的,因为您实际上不能传递任何有效的HWND,因为您没有任何有效的HWND
但是如果你试图从一个实际上有活动的、可见的窗口的线程/进程调用OpenClipboard(NULL),它 * 应该 * 失败,因为你只是懒惰而没有传递你手上肯定有的HWND
这是它应该工作的方式,正如我所看到的。然而,看起来,即使他们最初有这个计划,在某些时候,Windows开发人员只是因为一些未公开的原因而放弃了它,并使OpenClipboard(NULL)工作,不管你是否有Windows,没有更新文档。

相关问题