【问题标题】:Windows Messaging - Various ways to get a Device Context with the non client areaWindows 消息 - 使用非客户区获取设备上下文的各种方法
【发布时间】:2016-05-27 02:30:07
【问题描述】:

此问题适用于所有 Windows 专家。

我正在研究获取包含窗口非客户区的设备上下文 (DC) 的不同方式(使用 Windows API)

我知道两种方法:

  1. GetWindowDC() - 为包括非客户区在内的整个窗口返回一个 DC。
  2. GetDCEx() - 如果您传递 DCX_WINDOW 的标志,您将获得一个带有非客户区的 DC。

还有其他方法可以在非客户区获得 DC 吗?

【问题讨论】:

  • 这两个选项不足有什么特别的原因吗?我不熟悉任何其他选项。
  • 为什么是 C# 和 VB6 标签? 2 种不同的语言
  • @andlabs - 我为我的应用程序使用挂钩,我需要捕获所有正在检索非客户区的事件。
  • 恐怕这可能是一场失败的战斗...您考虑过 CS_CLASSDC、CS_OWNDC、CS_PARENTDC 类样式吗?此外,调用 BeginPaint() 时,在 PAINTSTRUCT 中返回 DC 的句柄。此外,还可以使用低级 API 通过进程的 GDI 表找到它。简而言之 - 我怀疑人们可以列举获得 HDC 的每一种方法。
  • @VladFeinstein:从BeginPaint 返回的 DC 被剪裁到客户区。它不能用于渲染非客户区。除非应用程序使用 DWM 魔法。或者在其客户区内模仿非客户区。

标签: c++ windows winapi


【解决方案1】:

你让这变得比现在更复杂。实际上只有一种方法可以获取设备上下文来呈现窗口的非客户区:GetDCEx

基本原理很简单:如果您正在渲染窗口的非客户区,您将在您的WM_NCPAINT 处理程序中进行。此消息附带一个更新区域(可能不是矩形),并且只有GetDCEx 可以为您设置非矩形剪辑区域。


当然,您可以通过在从GetWindowDC 返回的设备上下文上手动调用SelectClipRgn 来实现相同的目的。但这就像通过在循环中重复添加一个值来实现乘法,而不是使用乘法运算符。


由于您尝试挂接您无法控制的应用程序,因此您可能还需要查找对GetDCCreateDC 的调用。任何一个都可以为整个屏幕(包括窗口的可见非客户区)返回一个 DC。

【讨论】:

  • 您的回答很好,但与我无关。我不需要通过调用函数来获取 dc,而是在检索具有非客户区的 dc 时使用钩子捕获。我正在捕捉前面提到的 2 种方式,但我的测试表明我遗漏了一些东西
  • Tnx,我猜你是对的。我希望我可以避免这种情况,因为它增加了很多复杂性(跟踪 SelectObject() 调用等......)但我越研究它似乎越是不可避免
【解决方案2】:

这是做完全相同的事情的两种方式——我认为微软不会添加第三个函数来做到这一点。 但是,获取桌面窗口的 DC 并仅绘制到您的窗口当前所在的部分也可以工作。 (但我不推荐它!)

你有没有尝试实现一些目标?

【讨论】:

    猜你喜欢
    • 2010-11-04
    • 2018-03-21
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 2012-01-11
    相关资源
    最近更新 更多