【问题标题】:How to draw directly on the Windows desktop, C#?如何直接在Windows桌面上绘制,C#?
【发布时间】:2010-12-04 21:38:47
【问题描述】:

已经针对其他语言提出了这个问题,即使对于那些其他语言,我也发现他们的答案缺乏如何准确地做到这一点,干净(没有搞砸的屏幕重绘等)。

是否可以从 C# 绘图到 Windows 桌面?如果可能的话,我正在寻找一个例子。

【问题讨论】:

  • 没有官方支持的干净方式从任何语言在桌面窗口上绘图。在实践中,大多数在桌面上实现最接近清洁绘图的方法都涉及将自己的 dll 注入到 Explorer 进程中,并将窗口过程子类化为桌面窗口。不过,我不建议在 C# 中这样做。此外,无法保证此类方法将继续适用于任何未来版本的 Windows,或适用于现有 Windows 版本的任何未来服务包或修补程序。

标签: c# desktop


【解决方案1】:

尝试以下方法:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;

class Program {

    [DllImport("User32.dll")]
    static extern IntPtr GetDC(IntPtr hwnd);

    [DllImport("User32.dll")]
    static extern int ReleaseDC(IntPtr hwnd, IntPtr dc);

    static void Main(string[] args) {
        IntPtr desktop = GetDC(IntPtr.Zero);
        using (Graphics g = Graphics.FromHdc(desktop)) {
            g.FillRectangle(Brushes.Red, 0, 0, 100, 100);
        }
        ReleaseDC(IntPtr.Zero, desktop);
    }
}

【讨论】:

  • 仅供参考,对于那些说你不能的人,这对我来说确实有效,尽管将任何窗口移到它上面会立即重新粉刷它:(
  • 我刚刚在 WPF、C# 4.0 应用程序中尝试过这个,我在启动鼠标后立即得到“检测到 PInvokeStackImbalance”。仅供路过的其他人参考。
  • 我遇到了同样的不平衡堆栈错误。解决方法是什么?将您的项目改回 3.5 客户端配置文件? :)
  • 看来将我的项目更改为 .NET 3.5 使这个不平衡问题消失了。
  • 堆栈不平衡是由于 ReleaseDC 方法定义不正确造成的。应该是:static extern int ReleaseDC(IntPtr hwnd, IntPtr dc);
【解决方案2】:

你可以试试:

Graphics.FromHwnd(IntPtr.Zero)

【讨论】:

  • Paolo Tedesco 的回答曾经对我有用,但后来停止了,我不知道为什么。 Leppie 的回答让它再次为我工作。
【解决方案3】:

您可以在https://uiautomationverify.codeplex.com/SourceControl/latest#UIAVerify/Tools/visualuiverify/utils/screenrectangle.cs 中查看真实世界的代码示例

这将绘制一个矩形,该矩形将出现在屏幕上,直到用户选择在任意位置移除它(不会被重新绘制)。它使用一个隐藏/显示为弹出窗口的窗体。

这是当前 Windows SDK 中 UIAVerify.exe 工具背后的代码。

如果你想使用上面的,请将以下文件复制到你的项目中:

  • utils\screenboundingrectangle.cs
  • utils\screenrectangle.cs
  • win32\*

可能需要相应地更新命名空间 + 添加对 System.Drawing + System.Windows.Forms 的引用

然后就可以用下面的代码画一个矩形了:

namespace Something
{
    public class Highlighter
    {
        ScreenBoundingRectangle _rectangle = new ScreenBoundingRectangle();
        public void DrawRectangle(Rectangle rect)
        {
            _rectangle.Color = System.Drawing.Color.Red;
            _rectangle.Opacity = 0.8;
            _rectangle.Location = rect;
            this._rectangle.Visible = true;
        }
    }
}

var rect = Rectangle.FromLTRB(100, 100, 100, 100);
var hi = new Highlighter();
hi.DrawRectangle(rect);

【讨论】:

    猜你喜欢
    • 2010-11-26
    • 1970-01-01
    • 2012-11-09
    • 2012-01-03
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多