【问题标题】:In what circumstances will GetClipboardData(CF_TEXT) return NULL?GetClipboardData(CF_TEXT) 在什么情况下会返回 NULL?
【发布时间】:2011-01-19 20:26:49
【问题描述】:

我有这个断断续续的问题,这让我发疯了很长时间:在我的一个程序中,GetClipboardData(CF_TEXT) 有 90%(左右)的时间成功,但是每隔一段时间它就会返回 NULL。

尽管事实上 OpenClipboard() 在调用 GetClipboardData(CF_TEXT) 之前总是成功(并检查返回值)。

请注意,90% 的成功率是针对同一页的! (即我知道那里有一个 CF_TEXT 内容)

注意:当它失败时,我立即调用 GetLastError() 但它返回的只是:“操作成功完成”

有问题的代码很简单:

if (::OpenClipboard(hwndW))
{
  HANDLE handleClip = ::GetClipboardData(CF_TEXT);
  if (handleClip == NULL)
    dw = GetLastError()
}

什么可能会在其中注入错误的 GetLastError() 代码?

知道什么会导致这种不一致的行为吗?

是否有其他进程正在锁定剪贴板?如果是,我该如何取回?

如何解决或调试此类问题?

【问题讨论】:

  • OpenClipboard() 不会告诉你任何事情。 EnumClipboardFormats() 告诉你什么?
  • 你怎么知道内容还在剪贴板上?
  • @Jeff 这是个好问题。我“知道”它在那里,因为如果我再试一次(完全相同的页面)它会成功。这不是很“科学”,但是当 GetLastError() 返回“操作成功完成”时,我的工具包中还有什么?我将尝试 Hans 的调用 EnumClipboardFormats() 的建议,但即使它告诉我 CF_TEXT 存在(或不存在),它也不会告诉我为什么它是如此不一致。
  • 我一直在研究我的一个类似(重复发生)的问题,几个月前读过这个帖子今天再次遇到它。就我而言,我不介意最后一个成功错误——只要我复制到剪贴板的最后一件事是空字符串,在已经清空剪贴板之后,我就会得到它。没有内容,不是失败,只是没有返回,错误成功。但是,我现在的问题是“空字符串副本”返回一个陈旧的最后一个错误“找不到文件”。 GetClipboardData 没有在空句柄上设置错误成功!现在我在调用之前设置了最后一个错误(0)。

标签: winapi clipboard clipboard-interaction


【解决方案1】:

您是否在使用 WebRoot SecureAnywhere?如果不允许的应用程序(基本上是任何未经预先批准的应用程序)尝试从剪贴板中检索由受保护的应用程序(包括许多浏览器和电子邮件客户端通过默认)。发生这种情况时,GetClipboardData(CF_TEXT) 将返回 NULL,即使之前对 IsClipboardFormatAvailable(CF_TEXT) 的调用返回 true。

【讨论】:

  • 这只是花了我一个下午的时间试图弄清楚我的程序出了什么问题。用户正在运行 WebRoot,这完全符合我的问题和解决方案。
  • 我们无法弄清楚是什么在为我们的软件中的一位用户清除剪贴板的 CF_TEXT 部分。就是这样!感谢您为我们节省了大量时间。
【解决方案2】:

我进行了 Google 搜索,发现 someone else with a similar problem(向下滚动以查找特定响应)原来是由于重新进入。您是否在任何地方调用 EmptyClipboard() 然后对更改做出反应?也许你有重入问题。

提供代码 sn-p 后更新
在您发布的代码中,调用GetLastError 之前的条件是错误的。只有在获得非 NULL 结果时才调用它,而不是在获得 NULL 结果时调用它。如果你解决了这个问题,你应该从GetLastError 得到更好的答案。 This MSDN article 应该有助于破译 GetLastError 的结果的实际含义。

更正后的代码 sn-p 更新
我的猜测是,您正面临与其他一些应用程序访问剪贴板的竞争条件。我建议您检查一下您是否正在运行任何其他可能执行此操作的工具。

【讨论】:

  • @Jeff 很抱歉没有提到我当然调用了 GetLastError()。这是它返回的内容:“操作成功完成”。我对此完全感到困惑。
  • @Android Eve:我已经根据其他信息修改了我的答案。
  • @Jeff +1 获取此链接。了解了我的程序,我认为您正在做某事……不,我不调用 EmptyClipboard(),但我确实调用了 CloseClipboard()——这不是更好吗?此外,即使我忘记调用空/关闭函数,为什么 GetLastError() 会返回“成功”?
  • Android Eve:不幸的是,GetLastError 返回由当前线程上最后一次调用 SetLastError 设置的最后一个错误,而不是您一定想看到的最后一个错误。如果您遇到重入问题,则可能会返回除 GetClipboardData 之外的其他 API 调用的最后一个错误。此外,也可能是调用未设置最后一个错误。
  • @Jeff:在这种情况下,您如何定义“重入问题”?
猜你喜欢
  • 2020-02-07
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
相关资源
最近更新 更多