CE用の ATL ウィザードでハマッたときは

ATL/WTL AppWizard for Windows CE を使ってコード生成すると、こういうエラーが出る。

1>c:\wtl80\include\atlapp.h(154) : error C2084: 関数 'HRESULT ATL::CComModule::RegisterClassObjects(DWORD,DWORD) throw()' は既に本体を持っています。
1>        C:\Program Files\Microsoft Visual Studio 8\VC\ce\atlmfc\include\atlbase.h(4422) : 'RegisterClassObjects' の前の定義を確認してください
1>c:\wtl80\include\atlapp.h(156) : error C2084: 関数 'HRESULT ATL::CComModule::RevokeClassObjects(void) throw()' は既に本体を持っています。
1>        C:\Program Files\Microsoft Visual Studio 8\VC\ce\atlmfc\include\atlbase.h(4423) : 'RevokeClassObjects' の前の定義を確認してください

DCOM や HOSTING がいらなければ、#define で回避できる。stdafx.h でatlbase.h をインクルードしてる行の前に、以下のような設定をすればいい。

#define _ATL_NO_HOSTING 1
#include <atldefce.h>
#undef _CE_DCOM

ただしこの方法は、当然ながら atlcom.h や atlhost.h と共存できない。CHtmlView を使おうとウィザードに HTML Page を設定したから、どうしようもない。

仕方がないので atlapp.h の150〜156行めを、#ifndef ではさんだ。

#ifndef _WIN32_WCE // <-- この行を追加
namespace ATL
{
  inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw()
  { return E_NOTIMPL; }
  inline HRESULT CComModule::RevokeClassObjects() throw()
  { return E_NOTIMPL; }
}; // namespace ATL
#endif  // <-- この行を追加

とりあえず動いたけど、何か副作用があるかもしれないし、ATL のヘッダをいじっているからよそでコンパイルするときに問題になる。