我目前在C ++应用程序中使用GetSaveFileName对话框。 (我知道这被IFileDialog interface取代了我选择不将此问题限制在已弃用的API中,但接受两种实现的解决方案。
挑战是对用户输入作出反应(即用户手动输入文件名输入)并相应地修改文件对话框。
作为一个具体示例,请考虑在用户手动输入支持的文件扩展名时自动更改文件类型下拉列表中的文件类型。
我原本希望OPENFILENAME结构的lpfnHook
成员可以为我做这件事,不幸的是,似乎没有为文件名输入中的类型字符触发事件。
答案 0 :(得分:0)
正确的解决方案是使用用户键入的任何文件名创建保存的文件,并根据所选的过滤器格式化文件的内容。在关闭对话框之前,用户可以根据需要自由更改过滤器。
无需对个别按键作出反应。但是,如果必须,那么在使用旧GetSaveFileName()
API时,唯一的选择是直接将文件名编辑字段子类化,例如使用SetWindowSubclass()
。您可以使用HWND
或GetDlgItem()
控件ID使用edt1
获取编辑字段的cmb13
。子类可以拦截按键消息,然后发送对话框CDM_GETFILEPATH
消息以获取当前键入的文件名,从中解析扩展名,并相应地手动更新过滤器组合框。您可以使用带有HWND
控件ID的GetDlgItem()
来获取组合框的cmb1
。
但是,在Vista及更高版本中,GetSaveFileName()
只是使用ComCtl32 v6时较新的IFileSaveDialog
API的包装器,因此不能保证上述功能不再适用。但你可以尝试一下。
如果您直接使用较新的IFileDialog
API,它允许您通过IFileDialogCustomize
使用新控件自定义对话框,但它不允许您子类化现有控件(它不提供访问权限)对话框的HWND
或其控件。您必须使用较低级别的钩子来访问它们。如果您确实设法将文件名编辑字段子类化,则可以使用IFileDialog::GetFileName()
检索当前键入的文件名,但无法直接更新过滤器组合框,因为IFileDialog::SetFilterTypeIndex()
无法调用将显示该对话框(除非您能找到获取其HWND
的方法)。仅在Vista上,您可以尝试根本不指定过滤器(或者至少是*.*
的过滤器),然后使用IFileDialogCustomize::AddComboBox()
和IFileDialogControlEvents::OnItemSelected
的组合来模拟手册过滤列表,IFileDialog::SetFilter()
根据所选过滤器指定对话框中显示的项目。但是,SetFilter()
已弃用,不再适用于Windows 7及更高版本。