【问题标题】:What is the purpose of hPrevInstance in WinMain [duplicate]WinMain中hPrevInstance的用途是什么[重复]
【发布时间】:2012-05-06 01:45:40
【问题描述】:

definition of WinMain 是:

int CALLBACK WinMain(
    _In_ HINSTANCE hInstance,
    _In_ HINSTANCE hPrevInstance,
    _In_ LPSTR     lpCmdLine,
    _In_ int       nCmdShow
);

我的理解是:

然而,我从未遇到过任何hPrevInstance的用法,即使是在1990年代后期的书中。那么,hPrevInstance 的用途是什么(如果有的话),它到底是什么

【问题讨论】:

    标签: c windows winapi hwnd hinstance


    【解决方案1】:

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

    一旦您的普通 GUI 程序自行启动,控制将从您的 WinMain function 开始。第二个参数 hPrevInstance 在 Win32 程序中始终为零。当然它在某些时候有意义吗?

    当然有。

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

    (由于 16 位 Windows 有一个公共地址空间,GetInstanceData 函数实际上只不过是一个 hmemcpy,许多程序都依赖于此,只是使用原始 hmemcpy 而不是使用文档化的 API。Win16 实际上是用在未来版本中强加单独地址空间的可能性 - 观察像 GMEM_SHARED 这样的标志 - 但是像 hmemcpy'ing 你以前的实例这样的技巧的流行将这种可能性降低到一个未实现的梦想。)

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-10-29
      • 2014-08-28
      • 2017-03-01
      • 2011-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多