2012-04-25 58 views
10

definition of WinMain的宗旨是:什麼是hPrevInstance在WinMain函數

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

我的理解是:

然而,從來有我遇到任何使用的hPrevInstance,甚至在書從晚20世紀90年代。那麼,如果有的話,是使用hPrevInstance,而究竟是什麼呢?

回答

14

這是一個遺留問題。 Raymond Chen對The Old New Thing(日期爲15   June   2004)提供了很好的解釋。在這裏它是(與更正的鏈接):

一旦您的平均GUI程序自己離開地面,控制開始在您的WinMain function。第二個參數hPrevInstance在Win32程序中始終爲零。當然,它在某種程度上有意義?

當然是的。

在16位Windows中有一個名爲GetInstanceData的函數。這個函數接受了一個HINSTANCE,一個指針和一個長度,並將該實例中的內存複製到當前實例中。 (這是16位等同於ReadProcessMemory的16位,限制第二和第三個參數必須相同。)

(由於16位Windows有一個公共地址空間,因此GetInstanceData函數真的沒有不僅僅是一個hmemcpy,許多程序依賴於這個,只是使用原始的hmemcpy而不是使用記錄的API。Win16實際上設計爲可以在未來的版本中加入獨立的地址空間 - 觀察像GMEM_SHARED這樣的標誌 - 但是技巧的流行就像你以前的例子一樣,將這種潛能降低到未實現的夢想中。)

這就是WinMain的hPrevInstance參數的原因。如果hPrevInstance非空,那麼它就是已經運行的程序副本的實例句柄。您可以使用GetInstanceData從它複製數據,讓自己更快地離開地面。例如,您可能希望將主窗口句柄複製出以前的實例,以便與之通信。

hPrevInstance是否爲空或不告訴您是否您是該程序的第一個副本。在16位Windows下,只有程序的第一個實例註冊了它的類;第二個和以後的實例繼續使用第一個實例註冊的類。 (事實上​​,如果他們嘗試過,註冊將失敗,因爲該類已經存在)。因此,如果hPrevInstance非NULL,則所有16位Windows程序都會跳過類註冊。

設計Win32的人在端口WinMain時發現他們自己有點修復:爲hPrevInstance傳遞什麼?畢竟,Win32中並不存在整個模塊/實例的東西,而單獨的地址空間意味着在第二個實例中跳過重新初始化的程序將不再起作用。所以Win32總是傳遞NULL,讓所有程序都相信它們是第一個。

令人驚訝的是,它確實有效。