如何修复无法工作的剪贴板
是否遇到过剪贴板无法工作的问题?例如,无法复制或粘贴任何内容?
引言
你是否遇到过剪贴板无法使用的烦人问题? 无法复制或粘贴任何内容? 如果是,那么这篇文章就是为你准备的。
背景
我现在向你展示这个解决方案,因为我已经找到了解决办法。 我注意到,这似乎是 Windows 组件中的一个错误。 当然,这不应该发生,为了消除它,我将提供一个解决方案。
使用代码
首先,让我简要解释一下剪贴板的工作原理。 如你所知,剪贴板一次只能从一个程序中获取一个信息片段,这就是为什么我认为每个应用程序在向其写入任何数据之前都必须锁定剪贴板。 程序使用 Windows API OpenClipboard
打开剪贴板。 稍后,它使用 CloseClipboard
关闭它。 在剪贴板打开时,任何其他程序都无法访问剪贴板。 现在,想象一下,如果一个程序在完成操作后没有关闭剪贴板会发生什么问题! 不幸的是,Windows 不允许任何函数(据我所知)可以强制关闭剪贴板,无论哪个程序调用它。 打开剪贴板的应用程序需要关闭它。
正如你可能理解的,本文中提出的问题是当一个程序没有关闭剪贴板时。 为了解决这个问题,我们需要找到持有剪贴板打开的窗口,并关闭它。 如果失败,则销毁它,或终止其所有者进程。
首先,让我们找到打开剪贴板的窗口(并且没有关闭它)。 Windows 提供了用于此的 API。 此函数返回窗口的句柄。 而且,既然我们知道句柄,就可以做各种各样的事情了! 我将在下面展示代码,并附带注释,向你展示如何解决这种情况。
CHAR Buffer[1000]; // A local buffer to hold data
HWND h = GetOpenClipboardWindow();
// Returns the HWND of the window that is currently
// having access to the clipboard
::GetWindowText(h, Buffer, 1000);
// Get the titlebar text of the window
GetWindowModuleFileName(h, Buffer, 1000);
// Get the path to the module which owns the window
// (the EXE of the DLL where the owning window was created)
dwThreadId = GetWindowThreadProcessId(h, &dwProcessId);
// Get the thread ID and process ID that owns this window
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
// Open the process with full access; gives us a handle to the process
GetModuleFileNameEx(hProcess, NULL, Buffer, 1000);
// Get the path to the program (EXE file)
// that owns the window (aka the process)
//TerminateProcess(hProcess, 0);
// We can call this to terminate the process
// whose window is jamming the clipboard
CloseHandle(hProcess);
// We no longer need the handle to the process, so let's close the handle
::CloseWindow(h);
// Close the offending window
::DestroyWindow(h);
// Destroy the offending window. Usually called after closing the window.
就这样! 不要让那些程序窃取你的剪贴板! 它是属于所有人的!