这个问题已经有了答案:
Why does prevInstance exist in WinMain and wWinMain if it is always NULL
2个答案
definition of WinMain
是:
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
);
我的理解是:
hInstance
是应用程序实例的句柄,可以,when not a DLL, be retrieved with GetModuleHandle(NULL)
szCmdLine
是命令行参数,可以使用GetCommandLine()
重试nCmdShow
通常是SW_SHOW
然而,我从来没有遇到过
hPrevInstance
的任何用法,甚至在90年代末的书籍中也是如此。那么,如果有,什么是hPrevInstance
的用法,它到底是什么? 最佳答案
这是一个遗产。陈雷蒙对The Old New Thing(2004年6月15日)给出了很好的解释。这里是(有正确的链接):
一旦你的普通gui程序脱离地面,控制就从你的WinMain function开始。第二个参数hprevinstance在win32程序中始终为零。当然在某个时候它有意义吗?
当然了。
在16位窗口中有一个名为getInstanceData的函数。此函数采用hinstance、指针和长度,并将内存从该实例复制到当前实例中。(它相当于16位的ReadProcessMemory,但第二个和第三个参数必须相同。)
(由于16位windows有一个公共地址空间,getInstanceData函数实际上只不过是一个hmemcpy,许多程序依赖于此,只是使用原始hmemcpy而不是使用文档化的api。win16的设计实际上是为了在将来的版本中设置单独的地址空间——观察gmem_shared这样的标志——但是像hmemcpy'ing这样的技巧在你以前的实例中的流行将这种可能性降低到了一个未实现的梦想。)
这就是将hprevinstance参数设置为winmain的原因。如果hprevinstance为非空,则它是已在运行的程序副本的实例句柄。您可以使用getInstanceData从中复制数据,让自己更快地离开地面。例如,您可能希望将主窗口句柄从上一个实例中复制出来,以便与它通信。
hprevinstance是否为空会告诉您您是否是程序的第一个副本。在16位窗口下,只有程序的第一个实例注册了它的类;第二个实例和随后的实例继续使用第一个实例注册的类。(事实上,如果尝试,注册将失败,因为类已经存在。)因此,如果hprevinstance为非空,则所有16位windows程序都跳过类注册。
设计win32的人发现自己在移植winmain时遇到了一点麻烦:hprevinstance要传递什么?毕竟,整个模块/实例在win32中并不存在,单独的地址空间意味着在第二个实例中跳过重新初始化的程序将不再工作。所以win32总是传递空值,使所有程序都相信它们是第一个。
令人惊讶的是,它确实奏效了。