在 VS Code 中使用 C++ COM/IFileDialog 时出错,而相同的代码在 Visual Studio 中工作。消息:'IID_IFileOpenDialog' 未在此范围内声明
Error using C++ COM/IFileDialog in VS Code while the same code works in Visual Studio. Message: 'IID_IFileOpenDialog' was not declared in this scope
我有 C++ 代码,我试图用组件对象模型的 IFileDialog 打开一个文件 select 对话框。该代码在 Visual Studio 中有效,但是当我在 VS Code 中键入完全相同的代码时,出现 2 个错误:
IID_IFileOpenDialog' was not declared in this scope
和
invalid use of incomplete type 'IFileDialog' {aka 'struct IFileDialog'}
这是在 Visual Studio 中成功加载文件 select 对话框的代码:
#include <iostream>
#include <objbase.h>
#include <ShObjIdl.h>
int main()
{
CoInitializeEx(nullptr, COINIT::COINIT_MULTITHREADED);
IFileDialog *fileDialog;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast<void**>(&fileDialog));
if (SUCCEEDED(hr)) {
fileDialog->AddRef();
fileDialog->Show(NULL);
}
else {
std::cout << "no" << std::endl;
}
CoUninitialize();
}
在 VS Code 中,我使用的是 MinGW/gcc/g++ 编译器(抱歉,我不太了解编译器,但我认为这三个编译器都构成了我的代码 运行),在 Visual Studio 中我不确定,在绿色播放按钮旁边它说本地 Windows 调试器。
是什么原因导致此错误仅出现在 VS Code 中?
默认情况下,MinGW 似乎将 NTDDI_VERSION 宏的值设置为 0x05020000 (NTDDI_WS03),这会禁用 shobjidl.h 中的 IFileDialog 定义。宏的值必须至少为 0x06000000 (NTDDI_VISTA) 才能启用定义。此处列出了这些宏的可能值及其含义:
https://docs.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers
将以下内容放在源文件的开头(包含之前)应该可以修复编译错误:
#define NTDDI_VERSION 0x0A000006 //NTDDI_WIN10_RS5
#define _WIN32_WINNT 0x0A00 // _WIN32_WINNT_WIN10, the _WIN32_WINNT macro must also be defined when defining NTDDI_VERSION
如果您没有 link 需要的库,可能仍然会出现 link 错误。您列出的程序需要 ole32.dll 和 uuid.dll,因此编译命令将如下所示:
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ program.cpp -lole32 -luuid
MSDN 并不总是记录需要 linked 哪些 DLL 才能访问哪些符号(或者至少,我在搜索信息时很难找到信息),但是快速和-肮脏的做法是在 MinGW 的 lib 目录中使用 grep。例如,查找提供符号“CLSID_FileOpenDialog”的库时:
$ grep -r CLSID_FileOpenDialog /usr/x86_64-w64-mingw32/lib
Binary file /usr/x86_64-w64-mingw32/lib/libuuid.a matches
所以我们知道在编译命令中添加“-luuid”
我有 C++ 代码,我试图用组件对象模型的 IFileDialog 打开一个文件 select 对话框。该代码在 Visual Studio 中有效,但是当我在 VS Code 中键入完全相同的代码时,出现 2 个错误:
IID_IFileOpenDialog' was not declared in this scope
和
invalid use of incomplete type 'IFileDialog' {aka 'struct IFileDialog'}
这是在 Visual Studio 中成功加载文件 select 对话框的代码:
#include <iostream>
#include <objbase.h>
#include <ShObjIdl.h>
int main()
{
CoInitializeEx(nullptr, COINIT::COINIT_MULTITHREADED);
IFileDialog *fileDialog;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast<void**>(&fileDialog));
if (SUCCEEDED(hr)) {
fileDialog->AddRef();
fileDialog->Show(NULL);
}
else {
std::cout << "no" << std::endl;
}
CoUninitialize();
}
在 VS Code 中,我使用的是 MinGW/gcc/g++ 编译器(抱歉,我不太了解编译器,但我认为这三个编译器都构成了我的代码 运行),在 Visual Studio 中我不确定,在绿色播放按钮旁边它说本地 Windows 调试器。
是什么原因导致此错误仅出现在 VS Code 中?
默认情况下,MinGW 似乎将 NTDDI_VERSION 宏的值设置为 0x05020000 (NTDDI_WS03),这会禁用 shobjidl.h 中的 IFileDialog 定义。宏的值必须至少为 0x06000000 (NTDDI_VISTA) 才能启用定义。此处列出了这些宏的可能值及其含义:
https://docs.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers
将以下内容放在源文件的开头(包含之前)应该可以修复编译错误:
#define NTDDI_VERSION 0x0A000006 //NTDDI_WIN10_RS5
#define _WIN32_WINNT 0x0A00 // _WIN32_WINNT_WIN10, the _WIN32_WINNT macro must also be defined when defining NTDDI_VERSION
如果您没有 link 需要的库,可能仍然会出现 link 错误。您列出的程序需要 ole32.dll 和 uuid.dll,因此编译命令将如下所示:
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ program.cpp -lole32 -luuid
MSDN 并不总是记录需要 linked 哪些 DLL 才能访问哪些符号(或者至少,我在搜索信息时很难找到信息),但是快速和-肮脏的做法是在 MinGW 的 lib 目录中使用 grep。例如,查找提供符号“CLSID_FileOpenDialog”的库时:
$ grep -r CLSID_FileOpenDialog /usr/x86_64-w64-mingw32/lib
Binary file /usr/x86_64-w64-mingw32/lib/libuuid.a matches
所以我们知道在编译命令中添加“-luuid”