由于我是初学者,这可能是一个非常基本的问题。我正在启动DirectX 11,在创建我的第一个应用程序时,使用了wWinMain,在搜索WinMain和wWinMain之间的区别时,我遇到了这个参数prevInstance。
根据MSDN,prevInstance始终为null,并且因为它始终为null,为什么它存在(因为认为创建者不会给出无用的参数是合乎逻辑的)。 (引自书中),
如果你需要一种方法来确定是否是以前的实例 应用程序已在运行,文档建议创建 使用CreateMutex的唯一命名的互斥锁。虽然互斥体会是 创建后,CreateMutex函数将返回ERROR_ALREADY_EXISTS。
什么是互斥锁,以及如何使用它(一个好的链接就足够了)。并且看起来需要一个方法来查找是否存在应用程序的另一个实例,prevInstance应该有一个指针或对它的引用,显然不是这种情况,因为它是null。为什么会这样,prevInstance的作用是什么?
答案 0 :(得分:15)
Raymond Chen's blog几乎完全致力于讨论Windows API的各个方面,这些方面对我们来说是“奇怪的”。幸运的是,他有一个blog post来回答这个问题:
在16位Windows中有一个名为GetInstanceData的函数。这个 函数获取了一个HINSTANCE,一个指针和一个长度,并复制了内存 从该实例到您当前的实例。 (有点像 16位相当于ReadProcessMemory,具有限制 第二和第三个参数必须相同。)
...
这就是hPrevInstance参数为WinMain的原因。如果 hPrevInstance是非NULL,然后它是副本的实例句柄 已经运行的程序。您可以使用GetInstanceData 从中复制数据,让自己更快地离开地面。例如, 您可能希望将主窗口句柄复制出来 实例,所以你可以与它沟通。
hPrevInstance是否为NULL或者没有告诉你是否是 该计划的第一份副本。在16位Windows下,只有第一个 一个程序的实例注册了它的类;第二次及以后 实例继续使用由注册的类 第一个例子。 (的确,如果他们尝试过,注册就会失败 因为该类已经存在。)因此,所有16位Windows 如果hPrevInstance是,则跳过类注册的程序 非空。
设计Win32的人发现自己有点修复 是时候移植WinMain:为hPrevInstance传递什么?该 毕竟,整个模块/实例的东西在Win32中都不存在 单独的地址空间意味着跳过的程序 第二种情况下的重新初始化将不再有效。所以Win32 总是传递NULL,使所有程序都相信它们是 第一个。
当然,现在hPrevInstance
与Windows API无关,除了兼容性原因,MSDN建议您使用互斥锁来检测应用程序的先前实例。
互斥体代表“互斥”。您可以CreateMutex()
参考CreateMutex()
。有很多使用互斥锁来检测以前的应用程序实例the MSDN documentation的例子。基本思想是创建一个具有您提出的唯一名称的互斥锁,然后尝试创建该命名互斥锁。如果ERROR_ALREADY_EXISTS
与{{1}}失败,您就知道您的应用程序实例已经启动。
答案 1 :(得分:1)
prev instance参数用于16位Windows兼容性。我认为在WinMain的MSDN参考中已经说明了这一点,至少它曾经是。