在WinMain中hPrevInstance的目的是什么?

App*_*ker 11 c windows winapi hwnd hinstance

的定义WinMain为:

int CALLBACK WinMain(
    _In_ HINSTANCE hInstance,
    _In_ HINSTANCE hPrevInstance,
    _In_ LPSTR     lpCmdLine,
    _In_ int       nCmdShow
);
Run Code Online (Sandbox Code Playgroud)

我的理解是:

然而,即使是在20 世纪90年代后期的书中,也从来没有遇到任何用法.那么,使用什么,究竟什么呢?hPrevInstancehPrevInstance

Ant*_*ula 15

这是遗产.Raymond Chen对The Old New Thing(2004年6月15日)提供了一个很好的解释.这是(带有更正的链接):

一旦你的普通GUI程序自行启动,控制就从你的WinMain函数开始.第二个参数hPrevInstance在Win32程序中始终为零.当然它在某些方面有意义吗?

当然有.

在16位Windows中有一个名为GetInstanceData的函数.此函数使用HINSTANCE,指针和长度,并将该实例的内存复制到当前实例中.(这是与ReadProcessMemory等效的16位,其限制是第二个和第三个参数必须相同.)

(由于16位Windows有一个共同的地址空间,GetInstanceData函数实际上只是一个hmemcpy,许多程序依赖于此而只是使用原始hmemcpy而不是使用记录的API.实际上Win16设计有可能强加在未来的版本中单独的地址空间 - 观察像GMEM_SHARED这样的标志 - 但是像hmemcpy这样的技巧在你之前的实例中的流行将这种潜力降低到了一个未实现的梦想.)

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

hPrevInstance是否为NULL或者没有告诉您是否是该程序的第一个副本.在16位Windows下,只有程序的第一个实例注册了它的类; 第二个和后续实例继续使用第一个实例注册的类.(实际上,如果他们尝试过,那么注册就会失败,因为该类已经存在.)因此,如果hPrevInstance为非NULL,则所有16位Windows程序都会跳过类注册.

设计Win32的人在端口WinMain时遇到了一些修复:hPrevInstance要传递什么?毕竟,Win32中并不存在整个模块/实例的东西,并且单独的地址空间意味着在第二个实例中跳过重新初始化的程序将不再起作用.所以Win32总是传递NULL,使所有程序都相信它们是第一个.

令人惊讶的是,它确实奏效了.