2009-11-15 6 views
3

С Windows Presentation Foundation, если у меня есть HWND, как я могу захватить его в качестве изображения, которое я могу манипулировать и отображать?Захват окна с WPF

+0

Что вы имеете в виду? HWND другого, не окна WPF? –

+0

Действительно, HWND произвольного окна. – directedition

ответ

8

Вы можете:

  1. CreateBitmap() создать HBitmap
  2. Вызов GetDC() на HWND
  3. BitBlt() содержание в HBitmap
  4. ReleaseDC()
  5. Зов Imaging.CreateBitmapSourceFromHBitmap() для создания управляемого BitmapSource
  6. DeleteObject() на HBitmap
  7. Используйте BitmapSource по желанию

шаги 1-4 и 6 используют Win32 API (GDI, чтобы быть точным), шаги 5 и 7 выполнены с использованием WPF

+0

Спасибо! У меня есть все настройки и компиляция без проблем. Я все еще замечаю, как применить BitmapSource к моему directedition

+0

В коде: Image.Source = myImageSource. В XAML:

+0

Это 'DeleteObject()' http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx not Release – Ciantic

7

В то время как выше ответ велик, это спасло бы массу времени тоже:

Использование раздела:

using System; 
using System.Windows; 
using System.Windows.Interop; 
using System.Runtime.InteropServices; 
using System.Windows.Media.Imaging; 

Код:

/// <summary> 
/// Captures screenshot using WINAPI. 
/// </summary> 
static public class CaptureScreenshot 
{ 
    /// <summary> 
    /// Capture the screenshot. 
    /// <param name="area">Area of screenshot.</param> 
    /// <returns>Bitmap source that can be used e.g. as background.</returns> 
    /// </summary> 
    public static BitmapSource Capture(Rect area) 
    { 
     IntPtr screenDC = GetDC(IntPtr.Zero); 
     IntPtr memDC = CreateCompatibleDC(screenDC); 
     IntPtr hBitmap = CreateCompatibleBitmap(screenDC, (int)SystemParameters.VirtualScreenWidth, (int)SystemParameters.VirtualScreenHeight); 
     SelectObject(memDC, hBitmap); // Select bitmap from compatible bitmap to memDC 

     // TODO: BitBlt may fail horribly 
     BitBlt(memDC, 0, 0, (int)area.Width, (int)area.Height, screenDC, (int)area.X, (int)area.Y, TernaryRasterOperations.SRCCOPY); 
     BitmapSource bsource = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); 

     DeleteObject(hBitmap); 
     ReleaseDC(IntPtr.Zero, screenDC); 
     ReleaseDC(IntPtr.Zero, memDC); 
     return bsource; 
    } 

    #region WINAPI DLL Imports 

    [DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)] 
    static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); 

    [DllImport("gdi32.dll")] 
    private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); 

    [DllImport("gdi32.dll", SetLastError = true)] 
    private static extern IntPtr CreateCompatibleDC(IntPtr hdc); 

    [DllImport("gdi32.dll")] 
    private static extern bool DeleteObject(IntPtr hObject); 

    [DllImport("gdi32.dll")] 
    private static extern IntPtr CreateBitmap(int nWidth, int nHeight, uint cPlanes, uint cBitsPerPel, IntPtr lpvBits); 

    [DllImport("user32.dll")] 
    private static extern IntPtr GetDC(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); 

    private enum TernaryRasterOperations : uint 
    { 
     /// <summary>dest = source</summary> 
     SRCCOPY = 0x00CC0020, 
     /// <summary>dest = source OR dest</summary> 
     SRCPAINT = 0x00EE0086, 
     /// <summary>dest = source AND dest</summary> 
     SRCAND = 0x008800C6, 
     /// <summary>dest = source XOR dest</summary> 
     SRCINVERT = 0x00660046, 
     /// <summary>dest = source AND (NOT dest)</summary> 
     SRCERASE = 0x00440328, 
     /// <summary>dest = (NOT source)</summary> 
     NOTSRCCOPY = 0x00330008, 
     /// <summary>dest = (NOT src) AND (NOT dest)</summary> 
     NOTSRCERASE = 0x001100A6, 
     /// <summary>dest = (source AND pattern)</summary> 
     MERGECOPY = 0x00C000CA, 
     /// <summary>dest = (NOT source) OR dest</summary> 
     MERGEPAINT = 0x00BB0226, 
     /// <summary>dest = pattern</summary> 
     PATCOPY = 0x00F00021, 
     /// <summary>dest = DPSnoo</summary> 
     PATPAINT = 0x00FB0A09, 
     /// <summary>dest = pattern XOR dest</summary> 
     PATINVERT = 0x005A0049, 
     /// <summary>dest = (NOT dest)</summary> 
     DSTINVERT = 0x00550009, 
     /// <summary>dest = BLACK</summary> 
     BLACKNESS = 0x00000042, 
     /// <summary>dest = WHITE</summary> 
     WHITENESS = 0x00FF0062 
    } 

    [DllImport("gdi32.dll")] 
    private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop); 

    #endregion 
} 

Обратите внимание, что это занимает скриншот данной области на экране, а не окна. Он работает для моих целей, вам, вероятно, придется его модифицировать :)

+0

Спасибо. Я сделал что-то очень похожее. Я бы хотел .hide() все окна, которые мне не нужны, screencap тот, который я делаю, и восстановление остальных после. – directedition

Смежные вопросы