我可能应该使用DirectX或OpenGL来执行此操作,但是我对内置dotnet(gdi +)的工具更为熟悉,所以我的问题就来了:
我正在尝试通过从Hwnd
IntPtr.Zero
创建图形来在屏幕上绘制,并且可以正常工作。
编辑:
IntPtr.Zero
实际上没有“屏幕”手柄,而是桌面手柄(将鼠标绘制在其顶部),如果可能,可以指出一种直接在屏幕上绘制的方式很好
但是当我尝试渲染某些东西时,就像动画一样,它会闪烁得太多。
我的代码:
static class Program
{
[STAThread]
static void Main()
{
Graphics screenGraphics = Graphics.FromHwnd(IntPtr.Zero);
while (true)
{
screenGraphics.Clear(Color.Red);
screenGraphics.FillRectangle(Brushes.White, 50, 50, 100, 100);
screenGraphics.Flush();
}
}
}
我也尝试过使用Bitmap
作为后台缓冲区,但是情况变得更糟,您实际上可以在屏幕上看到图形扫描线。
static class Program
{
[STAThread]
static void Main()
{
Graphics screenGraphics = Graphics.FromHwnd(IntPtr.Zero);
Bitmap backBuffer = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics backBufferGraphics = Graphics.FromImage(backBuffer);
Point origin = new Point(0, 0);
while (true)
{
backBufferGraphics.Clear(Color.Red);
backBufferGraphics.FillRectangle(Brushes.White, 50, 50, 100, 100);
backBufferGraphics.Flush();
screenGraphics.DrawImageUnscaled(backBuffer,origin);
screenGraphics.Flush();
}
}
}
dotnet提供了一个名为BufferedGraphics
的类,文档说:“为双缓冲区提供图形缓冲区”,但是它没有构造函数。
我发现了如何做到这一点,有一个优雅的解决方案:
static class Program
{
[STAThread]
static void Main()
{
BufferedGraphicsContext currentContext;
BufferedGraphics backBuffer;
currentContext = BufferedGraphicsManager.Current;
Graphics screenGraphics = Graphics.FromHwnd(IntPtr.Zero);
backBuffer = currentContext.Allocate(screenGraphics, Screen.PrimaryScreen.Bounds);
while (true)
{
//Things are static, but you can render an animation here.
backBuffer.Graphics.Clear(Color.Red);
backBuffer.Graphics.FillRectangle(Brushes.White, 50, 50, 100, 100);
backBuffer.Render();
}
}
}