GME
13
|
00001 // GMEOLEColl.cpp : implementation file 00002 // 00003 00004 #include "stdafx.h" 00005 #include "gme.h" 00006 #include "GMEOLEColl.h" 00007 #include "EnumVar.h" 00008 00009 #ifdef _DEBUG 00010 #define new DEBUG_NEW 00011 #undef THIS_FILE 00012 static char THIS_FILE[] = __FILE__; 00013 #endif 00014 00015 00017 // CStringCollect 00018 00019 IMPLEMENT_DYNCREATE(CGMEOLEColl, CCmdTarget) 00020 00021 CGMEOLEColl::CGMEOLEColl() 00022 { 00023 EnableAutomation(); 00024 00025 // To keep the application running as long as an OLE automation 00026 // object is active, the constructor calls AfxOleLockApp. 00027 00028 AfxOleLockApp(); 00029 } 00030 00031 CGMEOLEColl::~CGMEOLEColl() 00032 { 00033 // To terminate the application when all objects created with 00034 // with OLE automation, the destructor calls AfxOleUnlockApp. 00035 RemoveAll(); 00036 AfxOleUnlockApp(); 00037 } 00038 00039 void CGMEOLEColl::OnFinalRelease() 00040 { 00041 // When the last reference for an automation object is released 00042 // OnFinalRelease is called. This implementation deletes the 00043 // object. Add additional cleanup required for your object before 00044 // deleting it from memory. 00045 00046 delete this; 00047 } 00048 00049 BEGIN_MESSAGE_MAP(CGMEOLEColl, CCmdTarget) 00050 //{{AFX_MSG_MAP(CGMEOLEColl) 00051 // NOTE - the ClassWizard will add and remove mapping macros here. 00052 //}}AFX_MSG_MAP 00053 END_MESSAGE_MAP() 00054 00055 00056 BEGIN_DISPATCH_MAP(CGMEOLEColl, CCmdTarget) 00057 //{{AFX_DISPATCH_MAP(CGMEOLEColl) 00058 DISP_PROPERTY_EX(CGMEOLEColl, "Count", GetCount, SetNotSupported, VT_I4) 00059 DISP_FUNCTION(CGMEOLEColl, "Add", Add, VT_EMPTY, VTS_DISPATCH) 00060 DISP_FUNCTION(CGMEOLEColl, "Find", Find, VT_I4, VTS_DISPATCH) 00061 DISP_FUNCTION(CGMEOLEColl, "Remove", Remove, VT_EMPTY, VTS_VARIANT) 00062 DISP_FUNCTION(CGMEOLEColl, "RemoveAll", RemoveAll, VT_EMPTY, VTS_NONE) 00063 DISP_PROPERTY_PARAM(CGMEOLEColl, "Item", GetItem, SetItem, VT_DISPATCH, VTS_I4) 00064 //}}AFX_DISPATCH_MAP 00065 DISP_PROPERTY_EX_ID(CGMEOLEColl, "_NewEnum", DISPID_NEWENUM, GetNewEnum, SetNotSupported, VT_UNKNOWN) 00066 DISP_DEFVALUE(CGMEOLEColl, "Item") 00067 END_DISPATCH_MAP() 00068 00069 // {36C7B797-6BDE-46d0-8870-70189000EDF9} 00070 //static const IID IID_IGMEOLEColl = 00071 //{ 0x36c7b797, 0x6bde, 0x46d0, { 0x88, 0x70, 0x70, 0x18, 0x90, 0x0, 0xed, 0xf9 } }; 00072 00073 00074 00075 // Note: we add support for IID_IGMEOLEModels to support typesafe binding 00076 // from VBA. This IID must match the GUID that is attached to the 00077 // dispinterface in the .ODL file. 00078 00079 BEGIN_INTERFACE_MAP(CGMEOLEColl, CCmdTarget) 00080 INTERFACE_PART(CGMEOLEColl, __uuidof(IGMEOLEColl), Dual) 00081 DUAL_ERRORINFO_PART(CGMEOLEColl) 00082 END_INTERFACE_MAP() 00083 00085 // CStringCollect message handlers 00086 00087 void CGMEOLEColl::CheckIndex(long nIndex) 00088 { 00089 if (nIndex <= 0 || nIndex > m_ptrArray.GetSize()) 00090 AfxThrowOleException(E_INVALIDARG); 00091 } 00092 00093 LPUNKNOWN CGMEOLEColl::GetNewEnum() 00094 { 00095 std::unique_ptr<CEnumVariant> pEnum(new CEnumVariant); 00096 int nCount = m_ptrArray.GetSize(); 00097 std::unique_ptr<VARIANT[]> pContents(new VARIANT[nCount]); 00098 int i; 00099 00100 TRY 00101 { 00102 for (i = 0; i < nCount; ++i) 00103 { 00104 VariantInit(&pContents[i]); 00105 pContents[i].pdispVal = (LPDISPATCH)(m_ptrArray.ElementAt(i)); 00106 pContents[i].pdispVal->AddRef(); 00107 pContents[i].vt = VT_DISPATCH; 00108 } 00109 } 00110 CATCH_ALL(e) 00111 { 00112 while (--i >= 0) { 00113 pContents[i].pdispVal->Release(); 00114 VariantClear(&pContents[i]); 00115 } 00116 00117 THROW_LAST(); 00118 } 00119 END_CATCH_ALL 00120 pEnum->SetContents(pContents.release(), nCount); 00121 00122 return pEnum.release()->GetInterface(&IID_IUnknown); 00123 } 00124 00125 long CGMEOLEColl::GetCount() 00126 { 00127 return m_ptrArray.GetSize(); 00128 } 00129 00130 LPDISPATCH CGMEOLEColl::GetItem(long nIndex) 00131 { 00132 CheckIndex(nIndex); 00133 LPDISPATCH ret = (LPDISPATCH)(m_ptrArray.ElementAt((int)nIndex-1)); 00134 ret->AddRef(); 00135 return ret; 00136 } 00137 00138 void CGMEOLEColl::SetItem(long nIndex, LPDISPATCH newValue) 00139 { 00140 CheckIndex(nIndex); 00141 m_ptrArray.ElementAt((int)nIndex-1) = newValue; 00142 newValue->AddRef(); 00143 } 00144 00145 void CGMEOLEColl::Add(LPDISPATCH newValue) 00146 { 00147 m_ptrArray.Add(newValue); 00148 newValue->AddRef(); 00149 } 00150 00151 long CGMEOLEColl::Find(LPDISPATCH findValue) 00152 { 00153 int nCount = m_ptrArray.GetSize(); 00154 for (int i = 0; i < nCount; ++i) 00155 { 00156 if (m_ptrArray.ElementAt(i) == findValue) 00157 return i+1; 00158 } 00159 return -1; 00160 } 00161 00162 void CGMEOLEColl::Remove(const VARIANT FAR& removeValue) 00163 { 00164 int nIndex = -1; 00165 00166 VARIANT varTemp; 00167 VariantInit(&varTemp); 00168 const VARIANT* pvar = &removeValue; 00169 if (removeValue.vt != VT_DISPATCH) 00170 { 00171 if (VariantChangeType(&varTemp, (VARIANT*)&removeValue, 0, VT_I4) == NOERROR) 00172 pvar = &varTemp; 00173 else if (VariantChangeType(&varTemp, (VARIANT*)&removeValue, 0, VT_DISPATCH) == NOERROR) 00174 pvar = &varTemp; 00175 else 00176 AfxThrowOleException(DISP_E_TYPEMISMATCH); 00177 } 00178 if (pvar->vt == VT_DISPATCH) 00179 nIndex = (int)Find(pvar->pdispVal); 00180 else if (pvar->vt == VT_I4) 00181 nIndex = (int)pvar->lVal; 00182 VariantClear(&varTemp); 00183 00184 CheckIndex(nIndex); 00185 00186 LPDISPATCH ptr = (LPDISPATCH)(m_ptrArray.ElementAt(nIndex)); 00187 ptr->Release(); 00188 00189 m_ptrArray.RemoveAt(nIndex); 00190 } 00191 00192 void CGMEOLEColl::RemoveAll() 00193 { 00194 int nCount = m_ptrArray.GetSize(); 00195 for (int i = 0; i < nCount; ++i) 00196 { 00197 LPDISPATCH ptr = (LPDISPATCH)(m_ptrArray.ElementAt(i)); 00198 ptr->Release(); 00199 } 00200 m_ptrArray.RemoveAll(); 00201 } 00202 00203 00204 DELEGATE_DUAL_INTERFACE(CGMEOLEColl, Dual) 00205 00206 // Implement ISupportErrorInfo to indicate we support the 00207 // OLE Automation error handler. 00208 IMPLEMENT_DUAL_ERRORINFO(CGMEOLEColl, __uuidof(IGMEOLEColl)) 00209 00210 00211 STDMETHODIMP CGMEOLEColl::XDual::get_Count(long *cnt) 00212 { 00213 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00214 00215 TRY_DUAL(__uuidof(IGMEOLEColl)) 00216 { 00217 *cnt = pThis->GetCount(); 00218 return NOERROR; 00219 } 00220 CATCH_ALL_DUAL 00221 } 00222 00223 STDMETHODIMP CGMEOLEColl::XDual::Add(IDispatch* newValue) 00224 { 00225 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00226 00227 TRY_DUAL(__uuidof(IGMEOLEColl)) 00228 { 00229 pThis->Add(newValue); 00230 return NOERROR; 00231 } 00232 CATCH_ALL_DUAL 00233 } 00234 00235 STDMETHODIMP CGMEOLEColl::XDual::Find(IDispatch* findValue, long *cnt) 00236 { 00237 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00238 00239 TRY_DUAL(__uuidof(IGMEOLEColl)) 00240 { 00241 *cnt = pThis->Find(findValue); 00242 return NOERROR; 00243 } 00244 CATCH_ALL_DUAL 00245 } 00246 00247 STDMETHODIMP CGMEOLEColl::XDual::Remove(VARIANT removeValue) 00248 { 00249 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00250 00251 TRY_DUAL(__uuidof(IGMEOLEColl)) 00252 { 00253 pThis->Remove(removeValue); 00254 return NOERROR; 00255 } 00256 CATCH_ALL_DUAL 00257 } 00258 00259 STDMETHODIMP CGMEOLEColl::XDual::RemoveAll() 00260 { 00261 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00262 00263 TRY_DUAL(__uuidof(IGMEOLEColl)) 00264 { 00265 pThis->RemoveAll(); 00266 return NOERROR; 00267 } 00268 CATCH_ALL_DUAL 00269 } 00270 00271 STDMETHODIMP CGMEOLEColl::XDual::get_Item(long nIndex, IDispatch** val) 00272 { 00273 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00274 00275 TRY_DUAL(__uuidof(IGMEOLEColl)) 00276 { 00277 *val = pThis->GetItem(nIndex); 00278 return NOERROR; 00279 } 00280 CATCH_ALL_DUAL 00281 } 00282 00283 STDMETHODIMP CGMEOLEColl::XDual::put_Item(long nIndex, IDispatch* newValue) 00284 { 00285 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00286 00287 TRY_DUAL(__uuidof(IGMEOLEColl)) 00288 { 00289 pThis->SetItem(nIndex, newValue); 00290 return NOERROR; 00291 } 00292 CATCH_ALL_DUAL 00293 } 00294 00295 STDMETHODIMP CGMEOLEColl::XDual::get__NewEnum(IUnknown** e) 00296 { 00297 METHOD_PROLOGUE(CGMEOLEColl, Dual) 00298 00299 TRY_DUAL(__uuidof(IGMEOLEColl)) 00300 { 00301 *e = pThis->GetNewEnum(); 00302 return NOERROR; 00303 } 00304 CATCH_ALL_DUAL 00305 }