I'm still feeling my way around C++, and am a complete ATL newbie, so I apologize if this is a basic question. I'm starting with an existing VC++ executable project that has functionality I'd like to expose as an ActiveX object (while sharing as much of the source as possible between the two projects).
I've approached this by adding an ATL project to the solution in question, and in that project have referenced all the .h and .cpp files from the executable project, added all the appropriate references, and defined all the preprocessor macros. So far so good. But I'm getting a compiler error in one file (HideDesktop.cpp). The relevant parts look like this:
#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;
}
This code is throwing the following compiler errors:
error C2065: 'CComQIPtr' : undeclared identifier
error C2275: 'IActiveDesktop' : illegal use of this type as an expression
error C2065: 'pIActiveDesktop' : undeclared identifier
The two weird bits: (1) CComQIPtr is defined in atlcomcli.h, which is included in atlbase.h, which is included in HideDesktop.cpp; and (2) this file is only throwing these errors when it's referenced in my new ATL/AX project: it's not throwing them in the original executable project, even though they have basically the same preprocessor definitions. (The ATL AX project, naturally enough, defines _ATL_DLL, but I can't see where that would make a difference.)
My current workaround is to use a normal "dumb" pointer, like so:
IActiveDesktop *pIActiveDesktop;
HRESULT hr = ::CoCreateInstance(CLSID_ActiveDesktop,
NULL, // no outer unknown
CLSCTX_INPROC_SERVER,
IID_IActiveDesktop,
(void**)&pIActiveDesktop);
And that works, provided I remember to release it. But I'd rather be using the ATL smart stuff.
Any thoughts?