【发布时间】:2026-02-09 12:20:03
【问题描述】:
作为我的开源 DeskPins clone 的一部分(两个单独的链接,一个用于原始链接,一个用于 GitHub 上的克隆),我需要允许用户与桌面交互。我认为最简单的方法是打开一个新表单并在其上绘制桌面内容。然后我应该能够轻松设置鼠标光标并向用户提供有关当前焦点窗口的视觉提示。
更复杂的替代方法是使用 p/invoke 到 SetSystemCursor 并在其他窗口的 WM_PAINT 事件队列中注入自定义代码(以及可能的其他 WinApi 相关工作,例如,如果我的程序异常终止,光标清理将是一个问题)。我不想走这条路。
我下面的代码正在运行,唯一的问题是屏幕闪烁。在我设置DoubleBuffered = true 后它变得更好(而不是屏幕闪烁,它变成了父窗体闪烁),但仍然很明显。所以现在我的表单每次打开覆盖表单时都会闪烁。
我可以做些什么来使它成为一个平滑过渡,即好像没有打开一个新窗口一样?可以有“冻结”效果 = 任何动画都会暂停。
public sealed partial class DesktopOverlayForm : Form
{
public DesktopOverlayForm()
{
InitializeComponent();
//make full screen
//http://*.com/a/2176683/897326
Rectangle bounds = Screen.AllScreens
.Select(x => x.Bounds)
.Aggregate(Rectangle.Union);
this.Bounds = bounds;
//set desktop overlay image
this.BackgroundImage = MakeScreenshot();
}
/// <remarks>
/// Based on this answer on *:
/// http://*.com/questions/1163761/capture-screenshot-of-active-window
/// </remarks>
private static Bitmap MakeScreenshot()
{
Rectangle bounds = Screen.GetBounds(Point.Empty);
Bitmap image = new Bitmap(bounds.Width, bounds.Height);
using (Graphics g = Graphics.FromImage(image))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
return image;
}
private void DesktopOverlayForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
this.Close();
}
}
}
【问题讨论】:
-
反对者 - 请解释一下。如果您认为此问题缺少某些内容,最好留下评论。
标签: c# winforms graphics screenshot gdi+