What is the best way to capture an application window in C#?
I've developed a simple windows forms application to capture the windows of a video chat application (inbound, aka Remote, and outbound, aka Local). I use unmanaged Windows API code for this. Here is the Capture code:
// Set Local Window
localHandle = FindWindow(null, "local");
// Backup parent window for local
prevLocalHandle = GetParent(localHandle);
SetParent(localHandle, this.pBoxLocal.Handle);
SetWindowLong(localHandle, GWL_STYLE, WS_VISIBLE + (WS_MAXIMIZE | WS_BORDER | WS_DISABLED));
MoveWindow(localHandle, 0, -TOP_BAR_HEIGHT, this.pBoxLocal.Width, this.pBoxLocal.Height + LOWER_BAR_HEIGHT, true);
// Set Remote Window
remoteHandle = FindWindow(null, "remote");
// Backup parent window for remote
prevRemoteHandle = GetParent(remoteHandle);
SetParent(remoteHandle, this.pBoxRemote.Handle);
SetWindowLong(remoteHandle, GWL_STYLE, WS_VISIBLE + (WS_MAXIMIZE | WS_BORDER | WS_DISABLED));
MoveWindow(remoteHandle, 0, -TOP_BAR_HEIGHT, this.pBoxRemote.Width, this.pBoxRemote.Height + LOWER_BAR_HEIGHT, t开发者_运维百科rue);
Here is the Return code:
// Return Windows
SetParent(localHandle, prevLocalHandle);
SetWindowLong(localHandle, GWL_STYLE, (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX));
MoveWindow(localHandle, 0, 0, NORMAL_WIDTH, NORMAL_HEIGHT, true);
SetParent(remoteHandle, prevRemoteHandle);
SetWindowLong(remoteHandle, GWL_STYLE, (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX));
MoveWindow(remoteHandle, 0, 0, NORMAL_WIDTH, NORMAL_HEIGHT, true);
The goal is to go from this:
To this:
And then back again! :)
There are currently two issues with my way of doing things:
first of all, when I return the windows to the video chat application, ocasionally a black rectangle is left on my top-left corner of the screen. It disappears when I refresh the area.
second and most important of all, there are times that when I capture the window of the application, I also capture its toolbars (although the measurements I supply are just the ones regarding the video area of the window).
Is there a better way of doing this? Even if its just better functions! Remember: I want to obtain the windows of the video chat application and return them afterwards.
Thanks in advance for any tips!
Ok well the first issue you stated is an easy one to fix. You can just call Refresh() when you return the windows. However if you meant there is a black rectangle on your main desktop not a window then you can use http://msdn.microsoft.com/en-us/library/bb776346(VS.85).aspx which will allow you to force the whole desktop to refresh.
As for the second issue you are having since you are already messing with the Window Long method why not just remove all borders, I believe what might be happening is the border may have a "ThickFrame" which you specify in your return methods but not capture methods so that may be why you are getting toolbars and borders. You can check this by calling GetWindowLong storing that value and seeing what is there, this way you can know exactly what to remove.
Although I am not sure as to what the use of this application is. I believe what you are doing may be the only way to do it, since you are manipulating external screens.
精彩评论