GetSave文件名 / IFileSaveDialog - 用户输入的事件/对文件名更改做出反应?

GetSaveFileName / IFileSaveDialog - event on user input / react to file name change?

本文关键字:文件名 事件 IFileSaveDialog 用户 输入 GetSave      更新时间:2023-10-16

我目前正在C++应用程序中使用GetSave文件名对话框。(据我所知,这已被 IFileDialog 接口取代,我选择不将此问题限制为已弃用的 API,而是接受两种实现的解决方案)。

挑战在于对用户输入做出反应(即用户手动键入文件名输入)并相应地修改文件对话框。

作为具体示例,请考虑在用户手动输入支持的文件扩展名时自动更改文件类型下拉列表中的文件类型。


我曾希望 OPENFILENAME 结构的lpfnHook成员可以为我做到这一点,不幸的是,文件名输入中似乎没有为键入的字符触发事件。

正确的解决方案是使用用户键入的任何文件名创建保存的文件,并根据所选筛选器设置文件内容的格式。在关闭对话框之前,用户应该可以根据需要自由更改筛选器。

无需对单个按键做出反应。但是,如果必须,那么在使用旧版GetSaveFileName()API 时,唯一的选择是直接对文件名编辑字段进行子类化,例如使用SetWindowSubclass().可以使用具有edt1cmb13控件 ID 的GetDlgItem()获取编辑字段的HWND。子类可以截获按键消息,然后向对话框发送CDM_GETFILEPATH消息以获取当前键入的文件名,从中分析扩展名,并相应地手动更新筛选器组合框。可以使用具有cmb1控件 ID 的GetDlgItem()获取组合框的HWND

但是,在 Vista 及更高版本上,当使用 ComCtl32 v6 时,GetSaveFileName()只是较新的IFileSaveDialogAPI 的包装器,因此不能保证上述内容不再有效。但你可以尝试一下。

如果直接使用较新的IFileDialogAPI,它确实允许您通过IFileDialogCustomize使用新控件自定义对话框,但它不允许对现有控件进行子类化(它不提供对对话框或其控件的HWND的访问。您必须求助于较低级别的钩子才能访问它们)。如果您确实设法对文件名编辑字段进行子类化,则可以使用IFileDialog::GetFileName()来检索当前键入的文件名,但不能直接更新筛选器组合框,因为一旦显示对话框就无法调用IFileDialog::SetFilterTypeIndex()(除非您能找到一种方法来获取其HWND)。仅在 Vista 上,您可以尝试根本不指定过滤器(或者至少指定*.*过滤器),然后结合使用IFileDialogCustomize::AddComboBox()IFileDialogControlEvents::OnItemSelected来模拟手动过滤器列表,IFileDialog::SetFilter()根据所选过滤器指定对话框中显示哪些项目。但是,SetFilter()已被弃用,不再适用于 Windows 7 及更高版本。