如何修复"无法打开剪贴板:拒绝访问"错误?

nor*_*aul 15 delphi clipboard copy-paste delphi-2010

我使用以下代码将文本复制到剪贴板:

  Clipboard.Open;
  try
    Clipboard.AsText := GenerateClipboardText;
  finally
    Clipboard.Close;
  end;
Run Code Online (Sandbox Code Playgroud)

看似随意我得到"无法打开剪贴板:拒绝访问"错误.我猜这些错误是由其他应用程序锁定剪贴板引起的,但我似乎从来没有对应该导致锁定的其他应用程序做任何事情.

奇怪的是,我的用户似乎报告了Vista和Windows 7的错误,而不是XP.

有没有办法在尝试访问它之前检查剪贴板是否已锁定?

Dan*_*ski 17

这不是德尔福问题.由于剪贴板可以随时锁定,即使您检查,如果剪贴板当前未锁定,它可能会在检查后直接锁定.

你有两种可能性:

  1. 不要使用Delphi剪贴板类.而是使用原始API函数,您可以对可能的错误情况进行更细粒度的控制.
  2. 通过添加异常处理程序,预计代码会失败.然后添加一些重试代码,即重新设置文本三次,可能是指数退避,然后再抛出自己的错误.

我建议使用第二种解决方案,因为它更像是类似Delphi的方法,最终会产生更清晰的代码.

while not Success do
try
  //Set the clipboard
  Success := True;
except
  on Exception do
  begin
    Inc(RetryCount);
    if RetryCount < 3 then 
      Sleep(RetryCount * 100)
    else 
      raise MyException.Create('Cannot set clipboard');
  end;
end;
Run Code Online (Sandbox Code Playgroud)

  • 这也不是Win32问题 - 在为并发系统编程时这是一个简单的事实. (3认同)

Chr*_*ton 8

奇怪的是,我的用户似乎报告了Vista和Windows 7的错误,而不是XP

这可能与Vista/Win7如何处理剪贴板查看器通知有关.虽然他们仍然支持XP"剪贴板查看器链",它会发送一条必须依次重新发送给每个侦听器的通知消息(如果一个应用程序无法执行此操作,则不会通知其他应用程序).从Vista开始,应用程序会直接通知.没有什么可以阻止他们一次性尝试访问剪贴板.

打个比方:我有3个孩子.我有一个蛋糕.根据XP规则,我告诉最大的孩子要有一些蛋糕,然后告诉下一个最大的孩子有一个切片.她得到了她的切片,告诉她的兄弟,他得到了他的,然后告诉他的兄弟,他得到了他的,一切都在有条不紊地进行.
问题:中间孩子将蛋糕带到他的房间,没有告诉最小的,最年轻的人错过了.

使用Vista/Windows7,该系统仍然存在.但是,一旦蛋糕到达厨房,新的应用程序可以立即请求立即通知我.我喊"蛋糕准备好了!" 他们都出现在同一时间并尝试抓住一些.但是只有一把服务刀,所以他们必须继续伸手去拿刀,不能拿到它,等待下一次机会.