Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BitBlt screen capture not working on Windows 10

Tags:

I'm using this code to capture a process window in the background:

IntPtr = Process.GetProcessByName("memu")[0].MainWindowHandle; RECT rc; GetClientRect(hwnd, out rc);  IntPtr hdcFrom = GetDC(hwnd); IntPtr hdcTo = CreateCompatibleDC(hdcFrom);  int Width = rc.right; int Height = rc.bottom;  Bitmap bmp = null;  IntPtr hBitmap = CreateCompatibleBitmap(hdcFrom, Width, Height); if (hBitmap != IntPtr.Zero) {    IntPtr hLocalBitmap = SelectObject(hdcTo, hBitmap);     BitBlt(hdcTo, 0, 0, Width, Height, hdcFrom, 0, 0, CopyPixelOperation.SourceCopy);    SelectObject(hdcTo, hLocalBitmap);     DeleteDC(hdcTo);    ReleaseDC(hwnd, hdcFrom);     bmp = Image.FromHbitmap(hBitmap);    DeleteObject(hBitmap);    return bmp; } 

This code is capture an Android emulator called MEmu, it is using DirectX to render the content. But this code stopped to work after Windows 10 updated to version 16299 (it was working normally before), it still working on Windows 7 with Aero mode enabled.

When I use this method in the Windows 10 Pro v16299.X it simply return a white image or it returns the emulator "loading screen", not the running content. On Windows 7, if I remove the Aero mode it will act the same, capturing the "loading screen", so looks like somehow the way the transparency works in the new windows 10 pro update changed.

I've tried everything, tried install some modules to force Aero Mode to work on Windows 10, tried PrintWindow to capture the screen in the background, but still the same.

Any ideas what could be happening? Or a possible solution? Or what changed in this last Windows 10 Pro version that could break that code?

Thank you!

like image 392
Imac Avatar asked Dec 13 '17 20:12

Imac


1 Answers

Hopefully this will solve the problem. There is a method for capturing the screen that is built in to the .net framework that may work. Not sure if it will capture DirectX content, but it may be worth a try.

Please note that this solution captures the current screen, but you will probably be able to modify it to capture only the area you are interested in.

I found this solution here: https://www.c-sharpcorner.com/UploadFile/2d2d83/how-to-capture-a-screen-using-C-Sharp/

private void CaptureMyScreen() {       try       {            //Creating a new Bitmap object           Bitmap captureBitmap = new Bitmap(1024, 768, PixelFormat.Format32bppArgb);           //Bitmap captureBitmap = new Bitmap(int width, int height, PixelFormat);          //Creating a Rectangle object which will            //capture our Current Screen          Rectangle captureRectangle = Screen.AllScreens[0].Bounds;           //Creating a New Graphics Object          Graphics captureGraphics = Graphics.FromImage(captureBitmap);          //Copying Image from The Screen         captureGraphics.CopyFromScreen(captureRectangle.Left,captureRectangle.Top,0,0,captureRectangle.Size);          //Saving the Image File (I am here Saving it in My E drive).         captureBitmap.Save(@"E:\Capture.jpg",ImageFormat.Jpeg);          //Displaying the Successfull Result          MessageBox.Show("Screen Captured");     }     catch (Exception ex)     {         MessageBox.Show(ex.Message);     } } 
like image 163
user3308241 Avatar answered Sep 20 '22 17:09

user3308241