我可以从 WPF 窗口获取 HDC 以便我可以使用 Gdi+ API 绘制它吗?

Posted

技术标签:

【中文标题】我可以从 WPF 窗口获取 HDC 以便我可以使用 Gdi+ API 绘制它吗?【英文标题】:Can I get HDC from WPF window so that I can draw to it with Gdi+ API? 【发布时间】:2012-01-29 05:17:06 【问题描述】:

我有一个使用 GDI+ api 来利用给定 HDC 的库。 我想在 WPF 应用程序中使用它。我确实尝试从WindowInteropHelper 类中获取句柄并将其传递给进行绘图的库方法。然而,它失败只是因为它无法从该句柄创建 Gdi+ 图形。

然后我尝试在WindowsFormsHost 控件中使用 WinForm 元素并使用 WinForm 控件的绘制事件中可用的 HDC,它确实工作正常。 我想知道的是,同样的事情可以直接在 WPF 控件\窗口上工作吗? 是否有其他方法可以从 WPF 元素中获取 HDC,可以在其上使用 GDI 绘图 API?

【问题讨论】:

【参考方案1】:

如果您有 WPF 窗口的窗口句柄 (HWND),大概是使用 WindowInteropHelper 类获得的,那么您可以轻松获得该窗口的设备上下文 (HDC) 的句柄。

有两种方法可以实现,尽管最终都做同样的事情。第一个是 P/Invoke 必要的 GDI+ API 函数,但我们可以很快将其排除为不必要的耗时。请记住,.NET Framework 已经在System.Drawing namespace,特别是Graphics class 中包装了所有这些用于WinForms 开发的东西。因此,您只需在 WPF 应用程序中添加对 System.Drawing 的引用,您就可以免费获得所有这些封装的功能。

您感兴趣的部分是Graphics.FromHwnd method,它从指定的窗口句柄(HWND)创建一个新的Graphics 对象。

一旦你得到了这个,你可以通过调用Graphics.GetHdc method来获得一个设备上下文的句柄(HDC),它会返回你所追求的——一个IntPtr值,它代表一个句柄设备上下文。

请记住,您需要在完成后调用 Dispose method 对象上的 Dispose method 以释放其相关资源。

【讨论】:

以上是关于我可以从 WPF 窗口获取 HDC 以便我可以使用 Gdi+ API 绘制它吗?的主要内容,如果未能解决你的问题,请参考以下文章

Win32:一个窗口在其整个生命周期中是不是具有相同的 HDC?

从 WPF 窗口获取 System.Windows.Forms.IWin32Window

禁止“活动WPF”中的“背景”窗口

更改WPF窗口的启动位置

WPF 窗口仅垂直拖动

如何在 WPF 中将 MessageBox 窗口保留在前台