Introduction
Ever had the annoying problem that you can't use the clipboard? When you can't copy or paste anything? If yes, then this is for you.
Background
I present this solution to you now, as I worked out a solution to fix this. There seems to be a bug in a Windows component that causes this, I've noticed. This shouldn't be there, of course, and to remove it, I will present a solution.
Using the code
First, let me explain how the clipboard works in short. As you know, the clipboard can only take one snippet of information from one program at a time, which is why I suppose each application has to lock the clipboard before writing any data to it. A program opens the clipboard using the Windows API OpenClipboard
. Later, it closes it using CloseClipboard
. While the clipboard is open, no other program can access the clipboard. Now, imagine what problems would arise if a program did not close the clipboard after it was done! Unfortunately, Windows does not allow any function (to my knowledge) that can force the clipboard to be closed, regardless of which program calls it. The application that opens the clipboard needs to close it.
As you may understand, the problem that is presented in this article is when a program does not close the clipboard. To fix this, we need to find the window that is holding the clipboard open, and close it. Failing that, destroy it, or terminate its owning process.
First, let's find the window that has opened the clipboard (and which has not closed it). Windows provides an API for this. This function returns the handle to the window. And, as we know the handle, we can do all sorts of crazy stuff! I'll present the code below, with comments of course, to show you how to solve this situation.
CHAR Buffer[1000]; HWND h = GetOpenClipboardWindow();
::GetWindowText(h, Buffer, 1000);
GetWindowModuleFileName(h, Buffer, 1000);
dwThreadId = GetWindowThreadProcessId(h, &dwProcessId);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
GetModuleFileNameEx(hProcess, NULL, Buffer, 1000);
CloseHandle(hProcess);
::CloseWindow(h);
::DestroyWindow(h);
That's it! Don't let those programs steal your clipboard! It's anyone's!