我正在尝试将文本从我正在处理的 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
并不是特别重要。
如果我执行上面的代码块,一切实际上都会按预期进行。这对我来说很奇怪,因为根据文档 https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-openclipboard:
如果应用程序在 hwnd 设置为 NULL 的情况下调用 OpenClipboard,则 EmptyClipboard 将剪贴板所有者设置为 NULL;这会导致 SetClipboardData 失败。
但我发现它正在正常工作。
然而,我只添加了EmptyClipboard()
作为一个实验。在此之前,我的代码无法正常工作。假设我放置了文本"Hello"
来自 Word 文档。然后我复制了一个号码999
从我的申请中。会发生的情况是,如果我尝试粘贴到 Excel 或 Word(例如),它会粘贴"Hello"
。但是如果我选择"Paste Special"
在(例如)Excel 中并粘贴为文本,它将粘贴"999"
。所以它可以工作,但前提是使用非默认粘贴。
如果我添加EmptyClipboard()
(根据我上面的代码),它工作得很好。它清除了之前存在的一切。但根据文档,它不应该。
有人能帮我理解吗?
我不知道如何回答这个问题,除了:
"Because the documentation says so." tm
就这样吧。其中提供的文档和示例明确指出您必须按顺序调用*(伪代码):
if(::OpenClipboard(hwnd)) {
if(::EmptyClipboard()) {
//Copy data...
::SetClipboardData(/*...*/)'
}
::CloseClipboard();
}
这也基本上说明了:“在没有先调用 OpenClipboard 的情况下,不要调用 EmptyClipboard有合适的窗户把手".
如果做不到这一点,然后想知道为什么它不起作用,那就是一种挫败感。
*There are cases where responding to specific WM messages should not call ::OpenClipboard
but they do not apply here.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)