Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content
This repository has been archived by the owner on Jul 26, 2023. It is now read-only.

[Question] Issue with IntPtr versus Safehandles in Gdi32.BitBlt #593

Closed
josdemmers opened this issue Jan 23, 2022 · 1 comment · Fixed by #594
Closed

[Question] Issue with IntPtr versus Safehandles in Gdi32.BitBlt #593

josdemmers opened this issue Jan 23, 2022 · 1 comment · Fixed by #594

Comments

@josdemmers
Copy link

josdemmers commented Jan 23, 2022

I was wondering if I was missing some overload functions or I'm implementing this wrong.
Will first post the relevant code:

public Bitmap GetScreenCapture(IntPtr handle)
{
      Bitmap bitmap;

      PInvoke.RECT region;
      PInvoke.User32.GetWindowRect(handle, out region);
      
      var desktopWindowHandle = PInvoke.User32.GetDesktopWindow();
      var windowDCHandle = PInvoke.User32.GetWindowDC(desktopWindowHandle);
      var memoryDCHandle = PInvoke.Gdi32.CreateCompatibleDC(windowDCHandle);
      var bitmapHandle = PInvoke.Gdi32.CreateCompatibleBitmap(windowDCHandle, region.right - region.left, region.bottom - region.top);
      var bitmapOldHandle = PInvoke.Gdi32.SelectObject(memoryDCHandle, bitmapHandle);

      bool success = PInvoke.Gdi32.BitBlt(memoryDCHandle, 0, 0, region.right - region.left, region.bottom - region.top, windowDCHandle, region.left, region.top, SRCCOPY | CAPTUREBLT);

      try
      {
        bitmap = Image.FromHbitmap(bitmapHandle);
      }
      finally
      {
        PInvoke.Gdi32.SelectObject(memoryDCHandle, bitmapOldHandle);
        PInvoke.Gdi32.DeleteObject(bitmapHandle);
        PInvoke.Gdi32.DeleteDC(memoryDCHandle);
        PInvoke.User32.ReleaseDC(desktopWindowHandle, windowDCHandle);
      }

      return bitmap;
}

The issue is the function BitBlt wants IntPtr as input while the functions GetWindowDC and CreateCompatibleDC both return a SafeDCHandle.
Is there an overload for GetWindowDC and CreateCompatibleDC that return an IntPtr instead? Or can I make BitBlt to somehow accept the SafeDCHandles?

Before using this package I would use the code below. But this package sound really great. Safes a lot of time defining all the windows library functions you want to use.

[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
AArnott added a commit that referenced this issue Jan 24, 2022
@AArnott
Copy link
Collaborator

AArnott commented Jan 24, 2022

I suspect BitBlt should take SafeDCHandle as well. I'll send a PR to do this.
In the meantime you can always get the IntPtr from a SafeHandle using DangerousGetHandle(). Check the documentation on SafeHandle to learn how to use it safely for this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants