使用 StretchBlt 和 GetDesktopWindow 将图像绘制到屏幕
Draw image to screen using StretchBlt and GetDesktopWindow
我试图在屏幕上显示 Bitmap
使用 GetDesktopWindow()
获取桌面句柄 window,并使用 StretchBlt
将图像复制到它。
但是,这不起作用。它显示完全空白的图像或完全白色的图像,具体取决于我使用 SRCCOPY
还是其他常量。
代码如下:
[DllImport("GDI32.DLL", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern bool StretchBlt(IntPtr hdcDest, int nXDest, int nYDest, int nDestWidth, int nDestHeight,
IntPtr hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, TernaryRasterOperations dwRop);
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling = true)]
private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling = true)]
private static extern IntPtr BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
private static extern IntPtr GetDesktopWindow();
public enum TernaryRasterOperations
{
SRCCOPY = 0x00CC0020, /* dest = source*/
SRCPAINT = 0x00EE0086, /* dest = source OR dest*/
SRCAND = 0x008800C6, /* dest = source AND dest*/
SRCINVERT = 0x00660046, /* dest = source XOR dest*/
SRCERASE = 0x00440328, /* dest = source AND (NOT dest )*/
NOTSRCCOPY = 0x00330008, /* dest = (NOT source)*/
NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */
MERGECOPY = 0x00C000CA, /* dest = (source AND pattern)*/
MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest*/
PATCOPY = 0x00F00021, /* dest = pattern*/
PATPAINT = 0x00FB0A09, /* dest = DPSnoo*/
PATINVERT = 0x005A0049, /* dest = pattern XOR dest*/
DSTINVERT = 0x00550009, /* dest = (NOT dest)*/
BLACKNESS = 0x00000042, /* dest = BLACK*/
WHITENESS = 0x00FF0062, /* dest = WHITE*/
};
public static void DrawBitmapToScreen(Bitmap bmp, TernaryRasterOperations operations)
{
int width = bmp.Width;
int height = bmp.Height;
IntPtr hwnd = GetDesktopWindow();
IntPtr hdc = GetDC(hwnd);
//create Graphic from source bitmap
Graphics bmpGraphic = Graphics.FromImage(bmp);
//because (when uncommented) the following line works for coping a block from the form???
//Graphics bmpGraphic = this.CreateGraphics();
//get handle to source graphic
IntPtr srcHdc = bmpGraphic.GetHdc();
//copy it
bool res = StretchBlt(hdc, 20, 20, width, height,
srcHdc, 0, 0, width, height, operations);
//release handles
bmpGraphic.ReleaseHdc();
ReleaseDC(hwnd, hdc);
}
要调用它,我会使用:
DrawBitmapToScreen((Bitmap)pictureBox1.Image, TernaryRasterOperations.SRCCOPY);
我做错了什么?
编辑:如果您刷新 Windows 资源管理器或在其上移动 window
,我需要图像从屏幕上删除
我找到了一个不使用 StretchBlt()
或 BitBlt()
的解决方案(在 Graphics
class 的基础代码之外)。
唯一的非托管代码是 GetDC()
、GetDesktopWindow()
和 ReleaseDC()
。
这是代码
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling = true)]
private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
private static extern IntPtr GetDesktopWindow();
public static void DrawBitmapToScreen(Bitmap bmp)
{
int width = bmp.Width;
int height = bmp.Height;
IntPtr hwnd = GetDesktopWindow();
IntPtr hdc = GetDC(hwnd);
using (Graphics g = Graphics.FromHdc(hdc))
{
g.DrawImage(bmp, new Point(0, 0));
}
ReleaseDC(hwnd, hdc);
}
我试图在屏幕上显示 Bitmap
使用 GetDesktopWindow()
获取桌面句柄 window,并使用 StretchBlt
将图像复制到它。
但是,这不起作用。它显示完全空白的图像或完全白色的图像,具体取决于我使用 SRCCOPY
还是其他常量。
代码如下:
[DllImport("GDI32.DLL", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern bool StretchBlt(IntPtr hdcDest, int nXDest, int nYDest, int nDestWidth, int nDestHeight,
IntPtr hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, TernaryRasterOperations dwRop);
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling = true)]
private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling = true)]
private static extern IntPtr BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
private static extern IntPtr GetDesktopWindow();
public enum TernaryRasterOperations
{
SRCCOPY = 0x00CC0020, /* dest = source*/
SRCPAINT = 0x00EE0086, /* dest = source OR dest*/
SRCAND = 0x008800C6, /* dest = source AND dest*/
SRCINVERT = 0x00660046, /* dest = source XOR dest*/
SRCERASE = 0x00440328, /* dest = source AND (NOT dest )*/
NOTSRCCOPY = 0x00330008, /* dest = (NOT source)*/
NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */
MERGECOPY = 0x00C000CA, /* dest = (source AND pattern)*/
MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest*/
PATCOPY = 0x00F00021, /* dest = pattern*/
PATPAINT = 0x00FB0A09, /* dest = DPSnoo*/
PATINVERT = 0x005A0049, /* dest = pattern XOR dest*/
DSTINVERT = 0x00550009, /* dest = (NOT dest)*/
BLACKNESS = 0x00000042, /* dest = BLACK*/
WHITENESS = 0x00FF0062, /* dest = WHITE*/
};
public static void DrawBitmapToScreen(Bitmap bmp, TernaryRasterOperations operations)
{
int width = bmp.Width;
int height = bmp.Height;
IntPtr hwnd = GetDesktopWindow();
IntPtr hdc = GetDC(hwnd);
//create Graphic from source bitmap
Graphics bmpGraphic = Graphics.FromImage(bmp);
//because (when uncommented) the following line works for coping a block from the form???
//Graphics bmpGraphic = this.CreateGraphics();
//get handle to source graphic
IntPtr srcHdc = bmpGraphic.GetHdc();
//copy it
bool res = StretchBlt(hdc, 20, 20, width, height,
srcHdc, 0, 0, width, height, operations);
//release handles
bmpGraphic.ReleaseHdc();
ReleaseDC(hwnd, hdc);
}
要调用它,我会使用:
DrawBitmapToScreen((Bitmap)pictureBox1.Image, TernaryRasterOperations.SRCCOPY);
我做错了什么?
编辑:如果您刷新 Windows 资源管理器或在其上移动 window
,我需要图像从屏幕上删除我找到了一个不使用 StretchBlt()
或 BitBlt()
的解决方案(在 Graphics
class 的基础代码之外)。
唯一的非托管代码是 GetDC()
、GetDesktopWindow()
和 ReleaseDC()
。
这是代码
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling = true)]
private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
private static extern IntPtr GetDesktopWindow();
public static void DrawBitmapToScreen(Bitmap bmp)
{
int width = bmp.Width;
int height = bmp.Height;
IntPtr hwnd = GetDesktopWindow();
IntPtr hdc = GetDC(hwnd);
using (Graphics g = Graphics.FromHdc(hdc))
{
g.DrawImage(bmp, new Point(0, 0));
}
ReleaseDC(hwnd, hdc);
}