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

2024-01-24

我正在尝试将文本从我正在处理的 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(使用前将#替换为@)

将 Unicode 文本放置到具有 NULL 所有者窗口的剪贴板上时出现意外行为 的相关文章

  • 删除字符串 C 的第一个字符

    我试图删除字符串的第一个字符并保留其余部分 我当前的代码无法编译 我对如何修复它感到困惑 My code char newStr char charBuffer int len strlen charBuffer int i 1 char
  • VSTS 构建失败/发布无法在 bin 文件夹中找到 roslyn\csc.exe

    我们有一个网站项目 安装了以下 nuget 软件包 Microsoft CodeDom Providers DotNetCompilerPlatform 1 0 8 Microsoft Net Compilers 2 4 0 The web
  • MVC Core IActionResult 含义

    什么是IActionResult 我尝试查看 MSDN 和其他网站 但需要通用 常见 易于理解的答案 MSDN IActionResult https learn microsoft com en us dotnet api microso
  • 中间件 API 的最佳实践是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们正在开发一个中间件 SDK 采用 C 和 Java 语言 供游戏开发人员 动画软件开发人员 阿凡达开
  • CMake 和 Visual Studio:如何获得快速、安静的命令行构建?

    我有一个 cmake 项目 它成功地完成了我想要的一切 但我有大约 100 个文件 当我只需要重新编译一个文件时 我厌倦了每次看到生成的巨大输出 每个文件 30 行 明确地说 我正在编译cmake build 得到这个结果 我需要传递给编译
  • C 中的复合语句表达式

    下面的代码不起作用 int i void 999 100 添加括号就可以了 为什么 int i void 999 100 还有另一种方法可以完成此类分配 int i void 999 100 是什么让他们与众不同 在这份声明中 int i
  • C++ 中的单例和抽象基类

    最近我遇到了关于实现 Singleton 但涉及抽象基类的问题 假设我们有这样的类层次结构 class IFoo it s ABC class Foo public IFoo 我们的单例类定义如下 template
  • 如何从 List 中的字符串中删除数字/数字?

    我有一个字符串列表 List
  • 使用 Selenium for C# 登录 Facebook

    我一直在使用 Selenium C 框架并尝试进行 facebook 登录 但没有任何运气 这是我到目前为止得到的 基于这篇文章 使用 Selenium 测试 Facebook Connect 应用程序 https stackoverflo
  • 有没有办法使 C90 标准中的枚举无符号? (符合 MISRA-C 2004 标准)

    我正在尝试找到一种使枚举 无符号 的方法 enum x1 0 x2 x3 uint8 t x2 lt PC LINT MISRA C 2004 will complain about mixing signed and unsigned h
  • 从窗口内容截取屏幕截图(无边框)

    我正在寻找有关如何使用 C 将表单内容保存在位图中的解决方案 我已经尝试过使用 DrawToBitmap 但它捕获了所有带边框的窗口 这就是这段代码的结果 public static Bitmap TakeDialogScreenshot
  • 在不使用 Thread.Sleep c# 的情况下延迟发送电子邮件

    我有一个 for 循环 它循环并每个循环发送一封电子邮件 现在我正在使用 thread sleep 但我希望用户仍然能够与程序交互 只需取消该循环即可 是否可以在不使用 thread sleep 的情况下做到这一点 您是否在 UI 线程上运
  • 简单的文档管理系统和API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 无法将方法组“Read”转换为非委托类型“bool”

    我正在尝试使用SqlDataReader检查条目是否存在 如果存在则返回ID 否则返回false 当我尝试编译时 出现错误 无法将方法组 Read 转换为非委托类型 bool 我一直在遵循在 VB 中找到的示例 但似乎翻译可能不正确 pri
  • C 的“char”使用什么字符集? [复制]

    这个问题在这里已经有答案了 简单的问题 我最近开始用 C 编程 有一个简单的问题 C 编程语言在其 char 类型中使用什么字符集 例如 ASCII 还是取决于软件 操作系统 char 本质上是 1 个字节 主要在所有操作系统上 所以默认情
  • 如何解释“错误C2018:未知字符'0x40'?[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 在编译一些代码时 我收到以下信息 错误 C2018 未知字符 0x40 我想知道如何解决这样的问题 这是我要开始的地方
  • 我应该使用多个 HttpClient 来进行批量异步 GET 请求吗?

    我有一个场景 我需要在尽可能短的时间内发出大量 GET 请求 想想大约 1000 个 我知道通常最好保留一个客户端并尽可能重用它 Create Single HTTP Client HttpClient client new HttpCli
  • 将小数格式化为两位或整数

    对于 10 我想要 10 而不是 10 00 对于 10 11 我想要 10 11 没有代码可以实现吗 即通过指定格式字符串类似于 0 N2 decimal num 10 11M Console WriteLine num ToString
  • C/C++ 通过 Android NDK 在 JNI 中看不到 Java 方法

    我正在尝试从使用 NDK 构建的 C 类文件调用 Java 方法 它不断抛出常见的 未找到非静态方法 错误并导致整个 Android 应用程序崩溃 下面的代码片段 有些东西可能不需要 但我按原样保留它们 因为焦点 问题在于refreshJN
  • 具有多种类型的 C# 泛型类型推断

    我有以下通用方法 用于将一种类型的输入对象序列化为超类型 如下所示 public string SerialiseAs

随机推荐