#ifndef _COM_COMINIT_HPP_ #define _COM_COMINIT_HPP_ #ifndef _COM_OBJBASE_HPP_ #include #endif #ifndef _COM_OLE2_HPP_ #include #endif #ifndef __SGI_STL_MAP #include #endif enum ComModel{MultiThreaded=COINIT_MULTITHREADED,ApartmentThreaded=COINIT_APARTMENTTHREADED}; class Comparator { public: bool operator()(const DWORD h1,const DWORD h2)const{return (int)h1<(int)h2;} }; class ComInitializer { public: typedef map ThreadMap; typedef map ProcessMap; ComInitializer(ComModel comModel=MultiThreaded); virtual ~ComInitializer(); ComModel getThreadModel(void)const; private: ComInitializer(const ComInitializer &someComInitializer); ComInitializer &operator=(const ComInitializer &someComInitializer); void initialize(void); void uninitialize(void); static ThreadMap smThreadMap; static ProcessMap smProcessMap; ComModel mThreadModel; }; inline ComInitializer::ComInitializer(ComModel comModel) : mThreadModel(comModel) { initialize(); } inline ComInitializer::ComInitializer(const ComInitializer &/*someComInitializer*/) { // private implementation } inline ComInitializer::~ComInitializer() { uninitialize(); } inline ComInitializer &ComInitializer::operator=(const ComInitializer &/*someComInitializer*/) { // private implementation return *this; } inline void ComInitializer::initialize(void) { DWORD currentThread(::GetCurrentThreadId()); DWORD currentProcess(::GetCurrentProcessId()); switch(getThreadModel()) { case ApartmentThreaded : if(0==smThreadMap[currentThread]){smThreadMap[currentThread]=1;::CoInitializeEx(NULL,getThreadModel());} else{smThreadMap[currentThread]=smThreadMap[currentThread]+1;} break; case MultiThreaded : if(0==smProcessMap[currentProcess]){smProcessMap[currentProcess]=1;::CoInitializeEx(NULL,getThreadModel());} else{smProcessMap[currentProcess]=smProcessMap[currentProcess]+1;} break; } } inline void ComInitializer::uninitialize(void) { DWORD currentThread(::GetCurrentThreadId()); DWORD currentProcess(::GetCurrentProcessId()); switch(getThreadModel()) { case ApartmentThreaded : if(1==smThreadMap[currentThread]){smThreadMap[currentThread]=0;::CoUninitialize();} else smThreadMap[currentThread]=smThreadMap[currentThread]-1; break; case MultiThreaded : if(1==smProcessMap[currentProcess]){smProcessMap[currentProcess]=0;::CoUninitialize();} else smProcessMap[currentProcess]=smProcessMap[currentProcess]-1; break; } } inline ComModel ComInitializer::getThreadModel(void)const { return mThreadModel; } #endif