我是使用WPF和GDI的新手,我在显示图像方面遇到了麻烦。我最终的目标是构建类似暴露的东西。到目前为止,我将屏幕灰显,收集所有活动的HWND,并捕获所有窗口的屏幕。现在,我有一个Image元素,我尝试设置源,但没有任何东西出现。
foreach (IntPtr hwnd in hwndlist)
{
IntPtr windowhdc = GetDC((IntPtr) hwnd);
IntPtr bmap = CreateBitmap(400, 400, 1, 32, null);
IntPtr bitmaphdc = GetDC(bmap);
BitBlt(bitmaphdc, 0, 0, System.Convert.ToInt32(this.Width), System.Convert.ToInt32(this.Height), windowhdc, 0, 0, TernaryRasterOperations.SRCCOPY);
ReleaseDC(hwnd, windowhdc);
BitmapSource bmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmap, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
image1.Source = bmapSource;
image1.BeginInit();
}
完整的代码在这里:
http://pastebin.com/m70af590 - 代码
http://pastebin.com/m38966750 - xaml
我知道我现在拥有它的方式对于我正在尝试做的事情没有多大意义(运行循环并只是一遍又一遍地写入相同的图像),但我希望能有所改进那个图像到最后。
我已经尝试对可见窗口的HWND进行硬编码,但它仍然无效。
感谢您的帮助!
答案 0 :(得分:1)
我认为使用Memory DC可以解决您的问题。为此,首先导入:
[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll", EntryPoint = "SelectObject")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
[DllImport("gdi32.dll",EntryPoint="DeleteDC")]
public static extern IntPtr DeleteDC(IntPtr hDc);
而不是这个:
IntPtr bitmaphdc = GetDC(bmap);
BitBlt(bitmaphdc, 0, 0, System.Convert.ToInt32(this.Width), System.Convert.ToInt32(this.Height), windowhdc, 0, 0, TernaryRasterOperations.SRCCOPY);
这样做:
IntPtr memdc = CreateCompatibleDC(windowhdc);
SelectObject(memdc, bmap);
BitBlt(memdc, 0, 0, System.Convert.ToInt32(this.Width), System.Convert.ToInt32(this.Height), windowhdc, 0, 0, TernaryRasterOperations.SRCCOPY);
不要忘记稍后删除Memort DC:
DeleteDC(memdc);
顺便说一下,你不需要image1.BeginInit();
。
另外要检查,您不需要枚举所有窗口。请改用user32.dll中的GetDesktopWindow
方法。