[Reproduced from: http://www.yqdown.com/chengxukaifa/cc/4012.htm]
When I wrote an automated test case yesterday, I encountered a serious problem. I called a function to intercept a popup window, but I always cut down the background program. The popup window is the same as I couldn't see it. I thought it was a synchronization problem, so I clicked the pop-up window first. Then I added n threads. Sleep for testing. I found that the function couldn't cut down the window, not for this reason.
For this reason, I had to look at the function code. Previously, this method was used:
Bitblt (dcimage, 0, 0, (INT) (rect. width), (INT) (rect. height), dcscreen, (INT) (rect. left), (INT) (rect. top), ternaryrasteroperations. srccopy );
Intuitively, it should be because this method of DC has a problem with WPF program support, but it is strange that it is no problem to intercept other WPF components and windows, but the popup window cannot.
The other day I heard about another screenshot method. This method can even be used to intercept blocked windows. So I tried to find the printwindow function, so I had the second solution, the Code is as follows:
Intptr HDC = native. getwindowdc (this. Handle );
If (HDC! = Intptr. Zero)
{
Intptr hdcmem = native. createcompatibledc (HDC );
If (hdcmem! = Intptr. Zero)
{
Intptr hbitmap = native. createcompatiblebitmap (HDC, (INT) (rect. width), (INT) (rect. Height ));
If (hbitmap! = Intptr. Zero)
{
Native. SelectObject (hdcmem, hbitmap );
Native. printwindow (this. Handle, hdcmem, 0 );
Native. deleteobject (hbitmap );
Bitmap BMP = bitmap. fromhbitmap (hbitmap );
BMP. Save (Spath );
}
Native. deleteobject (hdcmem );
}
Native. releasedc (this. Handle, HDC );
}
It is to get the window handle and intercept the window through the printwindow API.
However, even more angry things happen. In the cut-out window, as long as the WPF component is used, all the parts are black. Only the window framework and buttons of MFC can be intercepted normally.
As a result, we have no choice but to continue to analyze this issue. I remember that WPF did not go through GDI, but was rendered through DirectX. That is to say, the DC method and the printwindow method are unreliable, however, the DirectX interception seems complicated.
Suddenly, when a bug is reported, we press printscreen and try again. The printscreen button should work. It seems that we can only save the country by curve. But that would have to go through the clipboard. It seems that the data on the clipboard will be damaged. However, if I save the data before the clipboard is intercepted, and then restore the Clipboard data, then there will be no problem.
So there is a third solution (there is no code to restore the Clipboard data at the moment ):
Const uint keyeventf_extendedkey = 0x1;
Const uint keyeventf_keyup = 0x2;
Const byte vk_snapshot = 0x2c;
Native. keybd_event (vk_snapshot, 0x45, keyeventf_extendedkey, uintptr. Zero );
Native. keybd_event (vk_snapshot, 0x45, keyeventf_extendedkey keyeventf_keyup, uintptr. Zero );
Idataobject iobj = clipboard. getdataobject ();
If (iobj. getdatapresent (dataformats. bitmap, true ))
{
Bitmap BMP screen = iobj. getdata (dataformats. bitmap, true) as bitmap;
Bitmap bmpoutput = new Bitmap (INT) This. rect. Width, (INT) This. rect. Height, system. Drawing. imaging. pixelformat. format24bpprgb );
Graphics G = graphics. fromimage (bmpoutput );
Rectangle destrectangle = new rectangle (0, 0, (INT) This. rect. Width, (INT) This. rect. Height );
G. drawimage (BMP screen, destrectangle, (INT) This. rect. x, (INT) This. rect. y, (INT) This. rect. width, (INT) This. rect. height, graphicsunit. pixel );
Bmpoutput. Save (Spath, system. Drawing. imaging. imageformat. BMP );
}
Test is available, so you have to use it first.
However, there are still many problems. Write them down first and leave them for further processing:
1. For the third solution, since you can press the printscreen key, what is the corresponding API? I always feel that the keyboard message is not directly tuned to the API stability.
2. Is there a better solution for WPF?