我正在尝试使用 GetOpenFileName() 通用对话框调用来弹出打开对话框并允许用户选择多个文件。
我设置了 OFN_ALLOWMULTISELECT 标志,以及 OFN_EXPLORER 设置,因此我得到了“新样式”文件选择框。
当我设置 OPENFILENAME 结构时,我将 ofn.lpstrFile 指向分配用于保存结果的缓冲区,并将 ofn.nMaxFile 设置为其长度。
我遇到的问题是,如果用户选择了太多文件名,导致缓冲区溢出,则对 GetOpenFileName 的调用将返回 FALSE,然后 CommDlgExtendedError() 返回 FNERR_BUFFERTOOSMALL。
这对于错误检测来说很好,我可以增加缓冲区的大小来修复它,但用户迟早会选择足够的文件名来溢出该缓冲区。
我在 MSDN 中看到注释说,如果缓冲区太小,lpstrFile 缓冲区的前两个字节将包含所需的大小,但它返回的大小似乎太小(当 OFN_ALLOWMULTISELECT 不存在时,这可能是正确的)未设置)。另外,这需要我再次打开对话框!
我的另一个想法是创建一个对话框挂钩过程,然后在收到 CDN_SELCHANGE 通知消息时检测文件名的大小,并动态分配正确大小的缓冲区,但是虽然它将数据写入新缓冲区,但它似乎记得 ofn.nMaxFile 的原始值。
有谁知道动态分配缓冲区来保存 GetOpenFile 调用结果而不使对话框出现两次的正确方法?
所以,事实证明,Martlark 的文章是正确的。
我的两个错误是:
1)我忘记将 MAX_PATH 添加到要在钩子中应用的大小中,并且
2) 这仅适用于 GetOpenFileName 的 unicode 版本。 (我正在使用 UNICODE not 定义进行编译)
一个有趣的问题。 我猜你可以分配所有内存;万一! 但本文档建议使用 Hook 过程:
http://support.microsoft.com/kb/131462
所有这些都是令人愉快且易于理解的非 OO C!