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
的任何用法,即使是在 1990年代的书籍中也是如此。那么,hPrevInstance
的用途是什么, 究竟是什么呢?
答案 0 :(得分:14)
这是遗产。 Raymond Chen对The Old New Thing(2004年6月15日)提供了很好的解释。这是(带有更正的链接):
一旦您的平均GUI程序自行启动,控制就从您的WinMain function开始。第二个参数hPrevInstance在Win32程序中始终为零。当然它在某个时候有意义吗?
当然有。
在16位Windows中有一个名为GetInstanceData的函数。此函数使用HINSTANCE,指针和长度,并将该实例的内存复制到当前实例中。 (这是16位等效于ReadProcessMemory,其限制是第二个和第三个参数必须相同。)
(由于16位Windows有一个共同的地址空间,GetInstanceData函数实际上只是一个hmemcpy,许多程序都依赖于此而只是使用原始的hmemcpy而不是使用记录的API.Win16实际上是用在未来的版本中强加单独的地址空间的可能性 - 观察像GMEM_SHARED这样的标志 - 但是像你以前的实例那样的诡计的普遍性将这种潜力降低到了一个未实现的梦想。)
这就是hPrevInstance参数为WinMain的原因。如果hPrevInstance为非NULL,则它是已运行的程序副本的实例句柄。您可以使用GetInstanceData从中复制数据,让您自己更快地开始工作。例如,您可能希望将主窗口句柄复制到上一个实例之外,以便与之通信。
hPrevInstance是否为NULL或者没有告诉您是否是该程序的第一个副本。在16位Windows下,只有程序的第一个实例注册了它的类;第二个和后续实例继续使用第一个实例注册的类。 (实际上,如果他们尝试过,那么注册就会失败,因为该类已经存在。)因此,如果hPrevInstance为非NULL,则所有16位Windows程序都会跳过类注册。
设计Win32的人在端口WinMain时遇到了一些修复:hPrevInstance要传递什么?毕竟,Win32中并不存在整个模块/实例的东西,并且单独的地址空间意味着在第二个实例中跳过重新初始化的程序将不再起作用。所以Win32总是传递NULL,使所有程序都相信它们是第一个。
令人惊讶的是,它确实有效。