我仍然在 C++ 方面摸索,并且是一个完全的 ATL 新手,所以如果这是一个基本问题,我很抱歉。 我从现有的 VC++ 可执行项目开始,该项目具有我希望作为 ActiveX 对象公开的功能(同时在两个项目之间共享尽可能多的源代码)。
我通过向相关解决方案添加 ATL 项目来解决此问题,并在该项目中引用了可执行项目中的所有 .h 和 .cpp 文件,添加了所有适当的引用,并定义了所有预处理器宏。 到目前为止,一切都很好。 但我在一个文件(HideDesktop.cpp)中遇到编译器错误。 相关部分如下所示:
#include "stdafx.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WinInet.h> // Shell object uses INTERNET_MAX_URL_LENGTH (go figure)
#if _MSC_VER < 1400
#define _WIN32_IE 0x0400
#endif
#include <atlbase.h> // ATL smart pointers
#include <shlguid.h> // shell GUIDs
#include <shlobj.h> // IActiveDesktop
#include "stdhdrs.h"
struct __declspec(uuid("F490EB00-1240-11D1-9888-006097DEACF9")) IActiveDesktop;
#define PACKVERSION(major,minor) MAKELONG(minor,major)
static HRESULT EnableActiveDesktop(bool enable)
{
CoInitialize(NULL);
HRESULT hr;
CComQIPtr<IActiveDesktop, &IID_IActiveDesktop> pIActiveDesktop; // <- Problematic line (throws errors 2065 and 2275)
hr = pIActiveDesktop.CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER);
if (!SUCCEEDED(hr))
{
return hr;
}
COMPONENTSOPT opt;
opt.dwSize = sizeof(opt);
opt.fActiveDesktop = opt.fEnableComponents = enable;
hr = pIActiveDesktop->SetDesktopItemOptions(&opt, 0);
if (!SUCCEEDED(hr))
{
CoUninitialize();
// pIActiveDesktop->Release();
return hr;
}
hr = pIActiveDesktop->ApplyChanges(AD_APPLY_REFRESH);
CoUninitialize();
// pIActiveDesktop->Release();
return hr;
}
此代码引发以下编译器错误:
错误 C2065:“CComQIPtr”:未声明的标识符
错误 C2275:“IActiveDesktop”:非法使用此类型作为表达式
错误 C2065:“pIActiveDesktop”:未声明的标识符
两个奇怪的地方:(1)CComQIPtr 定义在 atlcomcli.h 中,atlcomcli.h 包含在 atlbase.h 中,atlbase.h 包含在 HideDesktop.cpp 中; (2) 该文件仅在我的新 ATL/AX 项目中引用时抛出这些错误:它不会将它们抛出到原始可执行项目中,即使它们具有基本相同的预处理器定义。 (ATL AX 项目自然地定义了 _ATL_DLL,但我看不出这会产生什么影响。)
我当前的解决方法是使用普通的“哑”指针,如下所示:
IActiveDesktop *pIActiveDesktop;
HRESULT hr = ::CoCreateInstance(CLSID_ActiveDesktop,
NULL, // no outer unknown
CLSCTX_INPROC_SERVER,
IID_IActiveDesktop,
(void**)&pIActiveDesktop);
只要我记得释放它,那就行得通。 但我宁愿使用 ATL 智能的东西。
有什么想法吗?
你可能忘记了命名空间ATL
ATL::CComQIPtr