【问题标题】:Whether to show Common Item Dialog or GetOpenFileName? (Win32 API)是否显示 Common Item Dialog 或 GetOpenFileName? (Win32 API)
【发布时间】:2014-12-20 17:56:22
【问题描述】:

我想知道我是否在这里重新发明轮子。

本质上,新的 Common Item Dialog 文件浏览器比旧的 GetOpenFileName() 版本要好得多。如果用户使用的是 Vista+ 操作系统,我想使用新对话框,但在 XP 等上仍有旧对话框的功能。

所以我想知道我是否应该创建一个这样的函数。

BOOL ShowOpenFileDialog(_Out_ LPTSTR szBuffer, _In_ UINT iBufferSize)
{
    static DWORD dwMajorVersion = 0;

    if (!dwMajorVersion)
        dwMajorVersion = (DWORD)(LOBYTE(LOWORD(GetVersion())));

    if (dwMajorVersion >= 6)    // Vista+
        return ShowNewOpenFileDialog(szBuffer, iBufferSize); // show common item

    return ShowOldOpenFileDialog(szBuffer, iBufferSize);  // fall back to old dialog
}

还有一个后续只有C++的通用项吗?

【问题讨论】:

  • 对于新代码,我不确定是否会担心与 XP 或更早版本的兼容性。
  • 我同意。唯一的问题是我将在客户端机器上使用这个工具,其中许多仍然有遗留系统。我可以在哪里使用新对话框,这将使我的生活整体幸福感大大提高。
  • 不要基于版本号。基于CoCreateInstance(CLSID_FileOpenDialog) 是否成功。版本检查很难做到正确。
  • 特别是考虑到GetVersion/Ex() 现在是deprecated in Windows 8.1 以后,因此没有适当的显化。 Raymond 是对的,您应该检查CLSID_IFileOpenDialog 是否可用,如果可用,请使用它,在需要时回退到GetOpenFileName()。
  • 调用 GetOpenFileName 并让系统将其映射到新的常用项对话框可能是最简单的方法。

标签: c++ c file winapi dialog


【解决方案1】:

正如 Raymond Chen 所说,您不应该依赖版本号,而应该依赖功能的可用性,例如:

BOOL ShowOpenFileDialog(_Out_ LPTSTR szBuffer, _In_ UINT iBufferSize)
{
    IFileDialog *pfd = NULL;
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_IFileDialog, (void**)&pfd);
    if (SUCCEEDED(hr))
    {
        // use IFileDialog as needed...
        pfd->Release();
    }
    else
    {
        // use GetOpenFileName() as needed...
    }
}

不,IFileDialog 不仅仅特定于 C++。任何支持COM的语言都可以使用,包括C、C++、Delphi、VisualBasic等。

【讨论】:

  • 值得注意的是,它并不是那么简单。如果您的构建以 XP 为目标,那么它将无法编译。如果它以 Vista 为目标,那么您的程序很可能在 Windows XP 上运行时出现问题。在以 XP 为目标时手动复制未来的定义是可靠但乏味的。可能有更巧妙的方法。
猜你喜欢
  • 2010-10-10
  • 2012-09-19
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 2012-01-23
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多