【问题标题】:Sharing HDC between different processes在不同进程之间共享 HDC
【发布时间】:2011-01-30 18:23:12
【问题描述】:

我正在编写某种 IPC 功能,需要将某些资源从一个进程传递到另一个进程。这适用于可以通过 DuplicateHandle 复制的管道句柄等。现在我需要将 HDC 从一个进程传递到另一个进程。这甚至可能吗?如果是:如何?

子问题:我假设将窗口句柄 (HWND) 从一个进程传递到另一个进程是安全的。这个假设正确吗?

【问题讨论】:

    标签: windows winapi ipc gdi


    【解决方案1】:

    HWND 可以在进程之间共享,否则 SendMessage() 将无法工作。然而,它们仅限于特定桌面,桌面与会话相关联。每个登录用户都有一个会话。会话 0 是特殊的,服务运行的会话。还有一个安全桌面,您在登录时或按 Ctrl+Alt+Del 时看到的桌面,您不会弄乱密码输入框。但只要这两个进程在同一个桌面上运行,你就不会有任何问题。

    HDC 很模糊,从未尝试过。我不会推荐它。您始终可以使用 GetDC() 从 HWND 创建一个。

    【讨论】:

    • SendMessage 确实是一个很好的例子,它必须在进程之间工作(并且我的进程将在同一个会话中的同一个桌面上运行)。谢谢。所以我主要关心的仍然是 HDC。你是对的,我可以通过 HWND,但这意味着我必须重组我不想接触的代码。我只是再等一会儿,也许有人知道一个明确的是或否......
    • 你为什么不试试呢?如果您不必重构代码,那么您很快就会发现。
    • 嗯,你说得有道理。但即使它有效,我也会感觉更好地建立在记录的行为而不是巧合上,这可能使它在我的机器上工作但在其他机器上中断(它也必须在 XP、Vista 和 7 上工作)。但尝试绝对不会受到伤害。然后至少我可以知道它不起作用:)
    • 我遇到了同样的问题。传递了 HWND 而不是 HDC 并从 HWND 创建了一个 HDC。它工作正常。感谢@HansPassant 的提示
    【解决方案2】:

    所有 GDI 句柄都存储在映射到每个进程的表中。表中的条目包含拥有进程的进程 ID,并且在每次 GDI 访问句柄时都会对其进行检查。

    因此,(具有讽刺意味的是)GDI 句柄(包括 HDC)在系统范围内有效。但只能从创建它们的进程中使用。


    This Page 记录 GDI 对象的进程亲和性。当然,作为一个反驳点,值得注意的是,一些 COM 函数和窗口消息(如 WM_PRINT)没有任何进程间限制,并且它们通过 HDC,因此它们显然必须在幕后做一些事情来从一个进程编组 HDC到下一个。

    【讨论】:

    • 我认为你和 nobugz 都强调我的问题通常可以被视为共享 GDI 资源是正确的。我在这里找到了一个相关的帖子:stackoverflow.com/questions/133948/… 有人想分享 HFONT。也许这和 HDC 是同一个联盟。但是如果这个表映射到每个进程中,那么我希望有一个简单的 DuplicateGDIHandleFromThisTableForTheCurrentProcess 函数......
    • 表存在于所有进程中的事实是当前 GDI 实现的产物,而不是设计特性。它可以消失。在很多情况下,GDI 对象都有指向用户模式数据结构的指针,因此,即使句柄在系统范围内有效,实际的 GDI 对象也只能在单个进程中成功访问。
    • 好的,所以绝对行不通的是使用相同的句柄而不进一步编组到其他进程。这就留下了一个问题,是否有一个公开可用的功能可以做到这一点......
    • +1 指向 MSDN,它确实非常清楚地指出:“GDI 对象的句柄是进程私有的。也就是说,只有创建 GDI 对象的进程才能使用对象句柄。”它还列出了它所理解的术语“GDI 对象”。再次感谢!
    【解决方案3】:

    假设您想从另一个进程(例如通过使用 BitBlt)绘制属于一个进程的 HDC,那么正如 nobugz 和 Chris Becke 指出的那样,您不能跨进程边界共享该 HDC。但是,进一步假设该进程的 HDC 属于一个窗口(并且您的意图是最终绘制到该窗口上),那么您可以将该窗口句柄传递给另一个进程,并在此过程中使用 GetDc 获取 HDC。使用此 HDC,您可以在其他进程的窗口上进行绘制。

    【讨论】:

      猜你喜欢
      • 2021-04-30
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 2012-07-22
      • 2012-04-09
      • 2011-07-06
      • 2014-10-22
      • 1970-01-01
      相关资源
      最近更新 更多