2016-08-24 19 views

回答

3

按照OPENFILENAME文檔:

lpstrCustomFilter
類型:LPTSTR
包含一對空終止過濾字符串的用於保存由用戶選擇的過濾器模式的靜態緩衝器。第一個字符串是描述自定義過濾器的顯示字符串,第二個字符串是用戶選擇的過濾器模式。第一次您的應用程序創建對話框時,您可以指定第一個字符串,該字符串可以是任何非空字符串。當用戶選擇一個文件時,對話框將當前的過濾器模式複製到第二個字符串。保存的過濾器模式可以是lpstrFilter緩衝器中指定的模式之一,也可以是用戶鍵入的過濾器模式。系統在下次創建對話框時使用字符串初始化用戶定義的文件過濾器。如果nFilterIndex成員爲零,則該對話框使用自定義過濾器。

如果此成員是NULL,對話框不會保留用戶定義的過濾器模式。

如果此部件是不NULL,所述nMaxCustFilter成員的值必須指定的大小,在字符,則lpstrCustomFilter緩衝液中。

nMaxCustFilter
類型:DWORD
大小,以字符,通過lpstrCustomFilter標識的緩衝液中。該緩衝區的長度至少應爲40個字符。如果lpstrCustomFilterNULL或指向NULL字符串,則忽略此成員。

例如:

TCHAR szfilter[256] = TEXT("custom filter\0*.ext\0"); 

... 

m_ofn.lpstrCustomFilter = szFilter; 
m_ofn.nMaxCustFilter = 256; 
m_ofn.nFilterIndex = 0; 

的文檔意味着當首先所示的對話框和nFilterIndex是0時,由lpstrCustomFilter是活性指定的初始過濾器,即使它比由指定的過濾器不同的lpstrFilter。如果用戶然後選擇/輸入不同的過濾器,則更新szfilter以包含用戶選擇的過濾器。這允許您保存szFilter,以便下次顯示對話框時,如果需要,可以使用用戶上次選擇的過濾器初始化對話框。

實際上,這在XP和更早版本中可以正常工作。

在Windows 7中(也可能Vista的),後來,GetOpenFileName()這樣的表現了,不管OPENFILENAME的配置方式。 GetOpenFileName()只是忽略lpstrCustomFilter,絕不會應用初始自定義過濾器,也不會覆蓋szFilter緩衝區。這意味着lpstrCustomFilter現已被棄用且不再使用,並且設置nFilterIndex=0將默默提升爲nFilterIndex=1。這可能解釋了爲什麼所有示例只設置了lpstrCustomFilterNULL

這種行爲變化的原因是因爲GetOpenFileName()已被棄用,它現在是IFileOpenDialog的封裝器,用於向後兼容遺留代碼。 IFileOpenDialog不支持保留用戶指定的過濾器,它僅適用於應用程序定義的過濾器。在較新的對話框中沒有API用於設置或檢索用戶指定的過濾器,因此Microsoft顯然不會使GetOpenFileName()包裝嘗試在較新的對話框中模擬舊的lpstrCustomFilter功能。

您可以嘗試使用lpstrFilter來手動模擬舊的lpstrCustomFilter行爲。爲custom filter創建一個額外的條目。如果用戶先前選擇了一個文件,則使用所選文件的擴展名初始化該條目,並將nFilterIndex設置爲該條目的從1開始的索引。然後,在關閉對話框時,使用lpstrFilenFileExtension提取用戶實際選定的文件擴展名並將其保存,以便稍後可以初始化custom filter條目。

+0

你做了一個驚人的解釋。謝謝。 – basjak