我使用以下代码将文本复制到剪贴板:
Clipboard.Open;
try
Clipboard.AsText := GenerateClipboardText;
finally
Clipboard.Close;
end;
看似随意我得到“无法打开剪贴板:拒绝访问”错误。我猜这些错误是由其他应用程序锁定剪贴板引起的,但我似乎从来没有对应该导致锁定的其他应用程序做任何事情。
奇怪的是,我的用户似乎报告了Vista和Windows 7的错误,而不是XP。
在尝试访问剪贴板之前,有没有办法检查剪贴板是否已锁定?
答案 0 :(得分:16)
这不是德尔福问题。由于剪贴板可以随时锁定,即使您检查,如果剪贴板当前未锁定,它可能会在检查后直接锁定。
这里有两种可能性:
我建议使用第二种解决方案,因为它更像是类似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;
答案 1 :(得分:8)
奇怪的是我的用户似乎是 报告更多的错误 Vista和Windows 7比使用XP
这可能与Vista / Win7如何处理剪贴板查看器通知有关。虽然他们仍然支持XP“剪贴板查看器链”,它会发送一条必须依次重新发送给每个侦听器的通知消息(如果一个应用程序无法执行此操作,则不会通知其他应用程序)。从Vista开始,应用程序会直接通知。没有什么可以阻止他们一次性尝试访问剪贴板。
打个比方:我有3个孩子。我有一个蛋糕。根据XP规则,我告诉最大的孩子要有一些蛋糕,然后告诉下一个最大的孩子有一个切片。她得到她的切片,告诉她的兄弟,他得到他的,并告诉他的兄弟,谁得到他的,一切都有序地进行。
问题:中间孩子将蛋糕带到他的房间,没有告诉最小的,最年轻的人错过了。
使用Vista / Windows7,该系统仍然存在。但是,一旦蛋糕到达厨房,新的应用程序可以立即请求立即通知我。我喊“蛋糕准备好了!”他们都出现在同一时间并尝试抓住一些。但是只有一把服务刀,所以他们必须继续伸手去拿刀,不能拿到它,等待下一次机会。
答案 2 :(得分:1)
没有办法检查某些东西,然后根据结果做一些其他的东西,期望它不会失败,因为除非检查和动作是一个原子操作,总是有可能是另一个进程或线程同时做同样的事。
这可以判断您是否尝试打开剪贴板,打开文件,创建或删除目录 - 您应该只是尝试这样做,可能在循环中多次,并优雅地处理错误。
答案 3 :(得分:1)
尝试检查GetClipboardOwner,如果它不是null而不是您的Application.Handle,则无法打开以修改其内容。
即使它似乎很好,但实际上它可能不再存在了
所以在循环中添加一个try,直到你得到它或放弃(例如通知用户)。
答案 4 :(得分:1)
首先请注意,这可能不是您的应用程序中的问题。其他应用程序锁定了剪贴板或弄乱了通知链,现在您的应用程序无法访问它。当我遇到这样的问题时,我重新启动计算机并且他们神奇地离开......好吧......至少在我再次运行产生问题的应用程序之前。
此代码(未在Delphi中检查)可能对您有所帮助。它不会解决问题是通知链被破坏(除了PC重启之外什么都不会修复它)但如果应用程序锁定剪贴板一段时间它将解决问题。如果那个讨厌的应用程序将剪贴板锁定了很长时间(秒),则增加MaxRetries:
procedure Str2Clipboard(CONST Str: string; iDelayMs: integer);
CONST
MaxRetries= 5;
VAR RetryCount: Integer;
begin
RetryCount:= 0;
for RetryCount:= 1 to MaxRetries DO
TRY
inc(RetryCount);
Clipboard.AsText:= Str;
Break;
EXCEPT
on Exception DO
if RetryCount = MaxRetries
then RAISE Exception.Create('Cannot set clipboard')
else Sleep(iDelayMs)
END;
end;
此外,放弃'加注'并将其转换为函数并使用它可能是个好主意:
if not Str2Clipboard
then Log.AddMsg('Dear user, other applications are blocking the clipboard. We have tried. We really did. But it didn''t work. Try again in a few seconds.');
答案 5 :(得分:1)
我猜你在Win 8或更高版本上运行你的应用程序。
只需右键单击您的App .exe文件,转到兼容性选项卡,然后在Windows XP或更低版本上更改兼容模式。它会起作用,保证!