component.cpp
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:9k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // component.cpp
  2. #include <iostream.h>
  3. #include <stdio.h>
  4. #include "Componentcomponent.h" // Generated by MIDL
  5. #include "registry.h"  // Need this
  6. HINSTANCE g_hInstance;
  7. long g_cComponents = 0;
  8. long g_cServerLocks = 0;
  9. class CInsideCOM : public ISum
  10. {
  11. public:
  12. // IUnknown
  13. ULONG __stdcall AddRef();
  14. ULONG __stdcall Release();
  15. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  16. // IDispatch
  17. HRESULT __stdcall GetTypeInfoCount(UINT* pCountTypeInfo);
  18. HRESULT __stdcall GetTypeInfo(UINT iTypeInfo, LCID lcid, ITypeInfo** ppITypeInfo);
  19. HRESULT __stdcall GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId);
  20. HRESULT __stdcall Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr);
  21. // IDispatchEx
  22.     HRESULT __stdcall GetDispID(BSTR bstrName, DWORD grfdex, DISPID* pid);
  23. HRESULT __stdcall InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarRes, EXCEPINFO* pei, IServiceProvider* pspCaller);
  24. HRESULT __stdcall DeleteMemberByName(BSTR bstrName, DWORD grfdex);        
  25.     HRESULT __stdcall DeleteMemberByDispID(DISPID id);
  26. HRESULT __stdcall GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD* pgrfdex);
  27. HRESULT __stdcall GetMemberName(DISPID id, BSTR* pbstrName);
  28. HRESULT __stdcall GetNextDispID(DWORD grfdex, DISPID id, DISPID* pid);
  29. HRESULT __stdcall GetNameSpaceParent(IUnknown** ppunk);
  30. // ISum
  31. HRESULT __stdcall Sum(int x, int y, int* retval);
  32. HRESULT __stdcall CreateNewSum(BSTR name);
  33. CInsideCOM() : m_cRef(1) { g_cComponents++; }
  34. ~CInsideCOM() { cout << "Component: CInsideCOM::~CInsideCOM()" << endl, g_cComponents--; }
  35. bool Init(void);
  36. private:
  37. ULONG m_cRef;
  38. ITypeInfo* m_pTypeInfo;
  39. BSTR newsum;
  40. };
  41. HRESULT CInsideCOM::CreateNewSum(BSTR name)
  42. {
  43. wprintf(L"COMPONENT: CreateNewSum, name = %sn", name);
  44. newsum = SysAllocString(name);
  45. return S_OK;
  46. }
  47. HRESULT CInsideCOM::GetDispID(BSTR bstrName, DWORD grfdex, DISPID* pid)
  48. {
  49. wprintf(L"COMPONENT: GetDispID, bstrName = %sn", bstrName);
  50. HRESULT hr = GetIDsOfNames(IID_NULL, &bstrName, 1, LOCALE_USER_DEFAULT, pid);
  51. if(hr == DISP_E_UNKNOWNNAME)
  52. {
  53. if(grfdex & fdexNameEnsure)
  54. newsum = SysAllocString(bstrName);
  55. if(wcscmp(bstrName, newsum) == 0)
  56. {
  57. *pid = 17;
  58. wprintf(L"COMPONENT: GetDispID, returning bstrName = %s, pid = %d, newsum = %dn", bstrName, *pid, newsum);
  59. return S_OK;
  60. }
  61. }
  62. return hr;
  63. }
  64. HRESULT CInsideCOM::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarRes, EXCEPINFO* pei, IServiceProvider* pspCaller)
  65. {
  66. cout << "COMPONENT: InvokeEx" << endl;
  67. HRESULT hr = DispInvoke(this, m_pTypeInfo, id, wFlags, pdp, pvarRes, pei, NULL);
  68. if(hr == DISP_E_MEMBERNOTFOUND)
  69. if(id == 17)
  70. {
  71. cout << "COMPONENT: DISPID == 17" << endl;
  72. HRESULT hr = DispInvoke(this, m_pTypeInfo, 1, wFlags, pdp, pvarRes, pei, NULL);
  73. printf("HRESULT = %0xn", hr);
  74. return hr;
  75. }
  76. return hr;
  77. }
  78. HRESULT CInsideCOM::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
  79. {
  80. cout << "COMPONENT: DeleteMemberByName" << endl;
  81. return E_NOTIMPL;
  82. }
  83. HRESULT CInsideCOM::DeleteMemberByDispID(DISPID id)
  84. {
  85. cout << "COMPONENT: DeleteMemberByDispID" << endl;
  86. return E_NOTIMPL;
  87. }
  88. HRESULT CInsideCOM::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD* pgrfdex)
  89. {
  90. cout << "COMPONENT: GetMemberProperties" << endl;
  91. return E_NOTIMPL;
  92. }
  93. HRESULT CInsideCOM::GetMemberName(DISPID id, BSTR* pbstrName)
  94. {
  95. cout << "COMPONENT: GetMemberName" << endl;
  96. return E_NOTIMPL;
  97. }
  98. HRESULT CInsideCOM::GetNextDispID(DWORD grfdex, DISPID id, DISPID* pid)
  99. {
  100. cout << "COMPONENT: GetNextDispID" << endl;
  101. return E_NOTIMPL;
  102. }
  103. HRESULT CInsideCOM::GetNameSpaceParent(IUnknown** ppunk)
  104. {
  105. cout << "COMPONENT: GetNameSpaceParent" << endl;
  106. return E_NOTIMPL;
  107. }
  108. HRESULT CInsideCOM::GetTypeInfoCount(UINT* pCountTypeInfo)
  109. {
  110. *pCountTypeInfo = 1;
  111. return S_OK;
  112. }
  113. HRESULT CInsideCOM::GetTypeInfo(UINT iTypeInfo, LCID lcid, ITypeInfo** ppITypeInfo)
  114. {
  115. *ppITypeInfo = NULL;
  116. if(iTypeInfo != 0)
  117. return DISP_E_BADINDEX;
  118. m_pTypeInfo->AddRef();
  119. *ppITypeInfo = m_pTypeInfo;
  120. return S_OK;
  121. }
  122. HRESULT CInsideCOM::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
  123. {
  124. if(riid != IID_NULL)
  125. return DISP_E_UNKNOWNINTERFACE;
  126. return DispGetIDsOfNames(m_pTypeInfo, rgszNames, cNames, rgDispId);
  127. }
  128. HRESULT CInsideCOM::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
  129. {
  130. if(riid != IID_NULL)
  131. return DISP_E_UNKNOWNINTERFACE;
  132. return DispInvoke(this, m_pTypeInfo, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 
  133. }
  134. bool CInsideCOM::Init(void)
  135. {
  136. ITypeLib* pTypeLib;
  137. if(FAILED(LoadRegTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, &pTypeLib)))
  138. return false;
  139. HRESULT hr = pTypeLib->GetTypeInfoOfGuid(IID_ISum, &m_pTypeInfo);
  140. pTypeLib->Release();
  141. if(FAILED(hr))
  142. return false;
  143. return true;
  144. }
  145. ULONG CInsideCOM::AddRef()
  146. {
  147. cout << "Component: CInsideCOM::AddRef() m_cRef = " << m_cRef + 1 << endl;
  148. return ++m_cRef;
  149. }
  150. ULONG CInsideCOM::Release()
  151. {
  152. cout << "Component: CInsideCOM::Release() m_cRef = " << m_cRef - 1 << endl;
  153. if(--m_cRef != 0)
  154. return m_cRef;
  155. m_pTypeInfo->Release();
  156. delete this;
  157. return 0;
  158. }
  159. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  160. {
  161. if(riid == IID_IUnknown)
  162. *ppv = (IUnknown*)this;
  163. else if(riid == IID_ISum)
  164. *ppv = (ISum*)this;
  165. else if(riid == IID_IDispatch)
  166. *ppv = (IDispatch*)this;
  167. else if(riid == IID_IDispatchEx)
  168. {
  169. cout << "COMPONENT: QueryInterface for IDispatchEx" << endl;
  170. *ppv = (IDispatchEx*)this;
  171. }
  172. else 
  173. {
  174. *ppv = NULL;
  175. return E_NOINTERFACE;
  176. }
  177. AddRef();
  178. return S_OK;
  179. }
  180. HRESULT CInsideCOM::Sum(int x, int y, int* retval)
  181. {
  182. *retval = x + y;
  183. return S_OK;
  184. }
  185. class CFactory : public IClassFactory
  186. {
  187. public:
  188. // IUnknown
  189. ULONG __stdcall AddRef();
  190. ULONG __stdcall Release();
  191. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  192. // IClassFactory
  193. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv);
  194. HRESULT __stdcall LockServer(BOOL bLock);
  195. CFactory() : m_cRef(1) { }
  196. ~CFactory() { }
  197. private:
  198. long m_cRef;
  199. };
  200. ULONG CFactory::AddRef()
  201. {
  202. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  203. return ++m_cRef;
  204. }
  205. ULONG CFactory::Release()
  206. {
  207. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  208. if(--m_cRef != 0)
  209. return m_cRef;
  210. delete this;
  211. return 0;
  212. }
  213. HRESULT CFactory::QueryInterface(REFIID iid, void** ppv)
  214. {
  215. if((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  216. {
  217. cout << "Component: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  218. *ppv = (IClassFactory *)this;
  219. }
  220. else
  221. {
  222. *ppv = NULL;
  223. return E_NOINTERFACE;
  224. }
  225. AddRef();
  226. return S_OK;
  227. }
  228. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv)
  229. {
  230. if(pUnknownOuter != NULL)
  231. return CLASS_E_NOAGGREGATION;
  232. CInsideCOM *pInsideCOM = new CInsideCOM;
  233. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  234. if(pInsideCOM == NULL)
  235. return E_OUTOFMEMORY;
  236. // Call the Init method to load the type information
  237. pInsideCOM->Init();
  238. HRESULT hr = pInsideCOM->QueryInterface(iid, ppv);
  239. pInsideCOM->Release();
  240. return hr;
  241. }
  242. HRESULT CFactory::LockServer(BOOL bLock)
  243. {
  244. if(bLock)
  245. g_cServerLocks++;
  246. else
  247. g_cServerLocks--;
  248. return S_OK;
  249. }
  250. HRESULT __stdcall DllCanUnloadNow()
  251. {
  252. cout << "Component: DllCanUnloadNow() " << (g_cServerLocks == 0 && g_cComponents == 0 ? "Yes" : "No") << endl;
  253. if(g_cServerLocks == 0 && g_cComponents == 0)
  254. return S_OK;
  255. else
  256. return S_FALSE;
  257. }
  258. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID iid, void** ppv)
  259. {
  260. cout << "Component: DllGetClassObject" << endl;
  261. if(clsid != CLSID_InsideCOM)
  262. return CLASS_E_CLASSNOTAVAILABLE;
  263. CFactory* pFactory = new CFactory;
  264. if(pFactory == NULL)
  265. return E_OUTOFMEMORY;
  266. // QueryInterface probably for IClassFactory
  267. HRESULT hr = pFactory->QueryInterface(iid, ppv);
  268. pFactory->Release();
  269. return hr;
  270. }
  271. HRESULT __stdcall DllRegisterServer()
  272. {
  273. char DllPath[256];
  274. OLECHAR wDllPath[256];
  275. GetModuleFileName(g_hInstance, DllPath, 256);
  276. mbstowcs(wDllPath, DllPath, 256);
  277. ITypeLib* pTypeLib;
  278. HRESULT hr = LoadTypeLibEx(wDllPath, REGKIND_REGISTER, &pTypeLib);
  279. if(FAILED(hr))
  280. return hr;
  281. pTypeLib->Release();
  282. return RegisterServer("component.dll", CLSID_InsideCOM, "Inside COM+ Sample", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  283. }
  284. HRESULT __stdcall DllUnregisterServer()
  285. {
  286. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  287. return UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  288. }
  289. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  290. {
  291. g_hInstance = hInstance;
  292. return TRUE;
  293. }