WEB开发网
开发学院软件开发C语言 浅析如何用C#.NET做屏幕截图软件以及注册全局快捷... 阅读

浅析如何用C#.NET做屏幕截图软件以及注册全局快捷键(上)

 2010-09-30 22:42:43 来源:WEB开发网   
核心提示: 里面,现在继续回来说截取透明窗体的问题,浅析如何用C#.NET做屏幕截图软件以及注册全局快捷键(上)(3),我们知道它跟dwRop参数有关,在codeproject上面可以找到的源码,但是还是相当繁琐的,涉及到句柄操作,调用BitBlt()时,都是这样的:BitBlt(hMemDC,0,0,si

里面。

现在继续回来说截取透明窗体的问题,我们知道它跟dwRop参数有关,在codeproject上面可以找到的源码,调用BitBlt()时,都是这样的:

BitBlt( hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.TernaryRasterOperations.SourceCopy); 

我想一般的屏幕截图软件也是这样做的,这样做的话,你是不能截取到透明窗体的,我们应该改成这个样子:

BitBlt( hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, (uint)(PlatformInvokeGDI32.TernaryRasterOperations.SourceCopy | PlatformInvokeGDI32.TernaryRasterOperations.CaptureBlt) ); 

通过试验可知是实现了预期效果。CaptureBlt的作用在上面~

需要注意的是,当我们使用BitBlt的时候,涉及设备上下文句柄操作,需要用到另外几个API函数来创建和释放资源。贴个例子:

GetDesktopImage

public static Bitmap GetDesktopImage()
    {
      //In size variable we shall keep the size of the screen.
      SIZE size;
      //Variable to keep the handle to bitmap.
      IntPtr hBitmap;
      //Here we get the handle to the desktop device context.
      IntPtr   hDC = PlatformInvokeUSER32.GetDC(PlatformInvokeUSER32.GetDesktopWindow()); 
      //Here we make a compatible device context in memory for screen device context.
      IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);
      //We pass SM_CXSCREEN constant to GetSystemMetrics to get the X coordinates of screen.
      size.cx = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN);
      //We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of screen.
      size.cy = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CYSCREEN);
      //We create a compatible bitmap of screen size using screen device context.
      hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy);
      //As hBitmap is IntPtr we can not check it against null. For this purspose IntPtr.Zero is used.
      if (hBitmap!=IntPtr.Zero)
      {
        //Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
        IntPtr hOld = (IntPtr) PlatformInvokeGDI32.SelectObject(hMemDC, hBitmap);
        //We copy the Bitmap to the memory device context.
        PlatformInvokeGDI32.BitBlt( hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, (uint)(PlatformInvokeGDI32.TernaryRasterOperations.SRCCOPY | PlatformInvokeGDI32.TernaryRasterOperations.CAPTUREBLT) );
        //We select the old bitmap back to the memory device context.
        PlatformInvokeGDI32.SelectObject(hMemDC, hOld);
        //We delete the memory device context.
        PlatformInvokeGDI32.DeleteDC(hMemDC);
        //We release the screen device context.
        PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.GetDesktopWindow(), hDC);
        //Image is created by Image bitmap handle and stored in local variable.
        Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap); 
        //Release the memory to avoid memory leaks.
        PlatformInvokeGDI32.DeleteObject(hBitmap);
        //This statement runs the garbage collector manually.
        GC.Collect();
        //Return the bitmap 
        return bmp;
      }
      //If hBitmap is null retunrn null.
      return null;
    }

可见虽然直接的平台调用相比Graphics.CopyFromScreen()速度快,灵活,但是还是相当繁琐的。涉及到句柄操作。这些操作在Graphics.CopyFromScreen()已经替我们做了。

下面来说第三种方法:

出处:http://1971ruru.cnblogs.com/

上一页  1 2 3 

Tags:浅析 如何 NET

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接