【问题标题】:Why does prevInstance exist in WinMain and wWinMain if it is always NULL如果 prevInstance 始终为 NULL,为什么在 WinMain 和 wWinMain 中存在 prevInstance
【发布时间】:2011-09-17 23:10:32
【问题描述】:

由于我是初学者,这可能是一个非常基本的问题。我正在启动 DirectX 11,在创建我的第一个应用程序时,使用了 wWinMain,在搜索 WinMain 和 wWinMain 之间的差异时,我遇到了这个参数 prevInstance。

prevInstance 根据 MSDN 永远为 null,既然永远为 null,为什么会存在(因为逻辑上认为创作者不会给出一个无用的参数)。并且(引用书中的内容),

如果您需要一种方法来确定之前的实例是否 应用程序已经在运行,文档建议创建 使用 CreateMutex 唯一命名的互斥锁。虽然互斥锁将 创建后,CreateMutex 函数将返回 ERROR_ALREADY_EXISTS。

什么是互斥锁,以及如何使用它(一个好的链接就足够了)。并且看起来需要一个方法来查找应用程序的另一个实例是否存在,prevInstance 应该有一个指针或对它的引用,显然不是这种情况,因为它是空的。为什么会这样,prevInstance的作用是什么?

【问题讨论】:

  • 仅仅因为它 is 总是 null 并不意味着它 曾经 总是 null...

标签: c++ winapi parameters winmain


【解决方案1】:

Raymond Chen's blog 几乎完全致力于讨论今天对我们来说“奇怪”的 Windows API 方面。幸运的是,他有一个 blog post 可以回答这个确切的问题:

在 16 位 Windows 中,有一个名为 GetInstanceData 的函数。这 函数接受一个 HINSTANCE、一个指针和一个长度,并复制内存 从那个实例到你当前的实例。 (有点像 16 位等效于 ReadProcessMemory,但限制是 第二个和第三个参数必须相同。)

...

这就是 WinMain 的 hPrevInstance 参数的原因。如果 hPrevInstance 非 NULL,则它是副本的实例句柄 已经运行的程序。您可以使用 GetInstanceData 从中复制数据,让自己更快地起步。例如, 您可能希望将主窗口句柄复制出上一个 实例,以便您可以与之通信。

hPrevInstance 是否为 NULL 告诉你你是否是 程序的第一个副本。在 16 位 Windows 下,只有第一个 程序的实例注册了它的类;第二次及以后 实例继续使用由 第一个例子。 (确实,如果他们尝试,注册会失败 因为该类已经存在。)因此,所有 16 位 Windows 如果 hPrevInstance 是,程序跳过类注册 非NULL。

设计 Win32 的人发现自己遇到了一些问题: 是时候移植 WinMain:hPrevInstance 要传递什么?这 毕竟,Win32 中不存在整个模块/实例的东西,而且 单独的地址空间意味着跳过的程序 在第二种情况下重新初始化将不再起作用。所以Win32 总是传递 NULL,使所有程序都认为它们是 第一个。

当然,现在hPrevInstance 与 Windows API 无关,除非出于兼容性原因,MSDN 建议您使用互斥体来检测应用程序的先前实例。

互斥体代表“互斥”。 CreateMutex() 可以参考the MSDN documentation。有很多使用互斥锁来检测以前的应用程序实例的例子,such as this one。基本思想是创建一个具有您想出的唯一名称的互斥体,然后尝试创建该命名的互斥体。如果CreateMutex()ERROR_ALREADY_EXISTS 失败,您就知道您的应用程序的一个实例已经启动。

【讨论】:

  • 我冒昧地总结了这篇博文,所以你的答案不仅仅是一个链接。
  • @Jon Purdy:我很欣赏编辑,但我已经在引用陈先生的整个解释,以免失去上下文。 :-)
  • 一切都好,我想。也许 SO 应该有一个当前正在编辑的答案的指示器。
  • 非常感谢您的链接!非常准确的答案!
  • Raymond Chen 的博客可能是“为什么 X 在 Windows 中是这样的?”的最佳来源,其中 X 是一种奇怪而奇怪的东西。那里解释了很多历史上的怪事,其中很多都很好阅读。
【解决方案2】:

prev 实例参数用于 16 位 Windows 兼容性。我认为 WinMain 的 MSDN 参考中已经说明了这一点,至少以前是这样。

【讨论】:

    猜你喜欢
    • 2010-12-20
    • 2016-11-19
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    相关资源
    最近更新 更多