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

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. // ISum
  22. HRESULT __stdcall Sum(int x, int y, int* retval);
  23. CInsideCOM() : m_cRef(1) { g_cComponents++; }
  24. ~CInsideCOM() { cout << "Component: CInsideCOM::~CInsideCOM()" << endl, g_cComponents--; }
  25. bool Init(void);
  26. private:
  27. ULONG m_cRef;
  28. ITypeInfo* m_pTypeInfo;
  29. int m_x;
  30. int m_y;
  31. };
  32. HRESULT CInsideCOM::GetTypeInfoCount(UINT* pCountTypeInfo)
  33. {
  34. *pCountTypeInfo = 1;
  35. return S_OK;
  36. }
  37. HRESULT CInsideCOM::GetTypeInfo(UINT iTypeInfo, LCID lcid, ITypeInfo** ppITypeInfo)
  38. {
  39. *ppITypeInfo = NULL;
  40. if(iTypeInfo != 0)
  41. return DISP_E_BADINDEX;
  42. m_pTypeInfo->AddRef();
  43. *ppITypeInfo = m_pTypeInfo;
  44. return S_OK;
  45. }
  46. HRESULT CInsideCOM::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
  47. {
  48. if(riid != IID_NULL)
  49. return DISP_E_UNKNOWNINTERFACE;
  50. return DispGetIDsOfNames(m_pTypeInfo, rgszNames, cNames, rgDispId);
  51. }
  52. HRESULT CInsideCOM::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
  53. {
  54. if(riid != IID_NULL)
  55. return DISP_E_UNKNOWNINTERFACE;
  56. return DispInvoke(this, m_pTypeInfo, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 
  57. }
  58. bool CInsideCOM::Init(void)
  59. {
  60. ITypeLib* pTypeLib;
  61. if(FAILED(LoadRegTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, &pTypeLib)))
  62. return false;
  63. HRESULT hr = pTypeLib->GetTypeInfoOfGuid(IID_ISum, &m_pTypeInfo);
  64. pTypeLib->Release();
  65. if(FAILED(hr))
  66. return false;
  67. return true;
  68. }
  69. ULONG CInsideCOM::AddRef()
  70. {
  71. cout << "Component: CInsideCOM::AddRef() m_cRef = " << m_cRef + 1 << endl;
  72. return ++m_cRef;
  73. }
  74. ULONG CInsideCOM::Release()
  75. {
  76. cout << "Component: CInsideCOM::Release() m_cRef = " << m_cRef - 1 << endl;
  77. if(--m_cRef != 0)
  78. return m_cRef;
  79. m_pTypeInfo->Release();
  80. delete this;
  81. return 0;
  82. }
  83. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  84. {
  85. if(riid == IID_IUnknown)
  86. *ppv = (IUnknown*)this;
  87. else if(riid == IID_ISum)
  88. *ppv = (ISum*)this;
  89. else if(riid == IID_IDispatch)
  90. *ppv = (IDispatch*)this;
  91. else 
  92. {
  93. *ppv = NULL;
  94. return E_NOINTERFACE;
  95. }
  96. AddRef();
  97. return S_OK;
  98. }
  99. HRESULT CInsideCOM::Sum(int x, int y, int* retval)
  100. {
  101. cout << "Component: Sum(" << x << ", " << y << ");" << endl;
  102. *retval = x + y;
  103. return S_OK;
  104. }
  105. class CFactory : public IClassFactory
  106. {
  107. public:
  108. // IUnknown
  109. ULONG __stdcall AddRef();
  110. ULONG __stdcall Release();
  111. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  112. // IClassFactory
  113. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv);
  114. HRESULT __stdcall LockServer(BOOL bLock);
  115. CFactory() : m_cRef(1) { }
  116. ~CFactory() { }
  117. private:
  118. long m_cRef;
  119. };
  120. ULONG CFactory::AddRef()
  121. {
  122. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  123. return ++m_cRef;
  124. }
  125. ULONG CFactory::Release()
  126. {
  127. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  128. if(--m_cRef != 0)
  129. return m_cRef;
  130. delete this;
  131. return 0;
  132. }
  133. HRESULT CFactory::QueryInterface(REFIID iid, void** ppv)
  134. {
  135. if((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  136. {
  137. cout << "Component: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  138. *ppv = (IClassFactory *)this;
  139. }
  140. else
  141. {
  142. *ppv = NULL;
  143. return E_NOINTERFACE;
  144. }
  145. AddRef();
  146. return S_OK;
  147. }
  148. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv)
  149. {
  150. if(pUnknownOuter != NULL)
  151. return CLASS_E_NOAGGREGATION;
  152. CInsideCOM *pInsideCOM = new CInsideCOM;
  153. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  154. if(pInsideCOM == NULL)
  155. return E_OUTOFMEMORY;
  156. // Call the Init method to load the type information
  157. pInsideCOM->Init();
  158. HRESULT hr = pInsideCOM->QueryInterface(iid, ppv);
  159. pInsideCOM->Release();
  160. return hr;
  161. }
  162. HRESULT CFactory::LockServer(BOOL bLock)
  163. {
  164. if(bLock)
  165. g_cServerLocks++;
  166. else
  167. g_cServerLocks--;
  168. return S_OK;
  169. }
  170. HRESULT __stdcall DllCanUnloadNow()
  171. {
  172. cout << "Component: DllCanUnloadNow() " << (g_cServerLocks == 0 && g_cComponents == 0 ? "Yes" : "No") << endl;
  173. if(g_cServerLocks == 0 && g_cComponents == 0)
  174. return S_OK;
  175. else
  176. return S_FALSE;
  177. }
  178. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID iid, void** ppv)
  179. {
  180. cout << "Component: DllGetClassObject" << endl;
  181. if(clsid != CLSID_InsideCOM)
  182. return CLASS_E_CLASSNOTAVAILABLE;
  183. CFactory* pFactory = new CFactory;
  184. if(pFactory == NULL)
  185. return E_OUTOFMEMORY;
  186. // QueryInterface probably for IClassFactory
  187. HRESULT hr = pFactory->QueryInterface(iid, ppv);
  188. pFactory->Release();
  189. return hr;
  190. }
  191. HRESULT __stdcall DllRegisterServer()
  192. {
  193. char DllPath[256];
  194. OLECHAR wDllPath[256];
  195. GetModuleFileName(g_hInstance, DllPath, 256);
  196. mbstowcs(wDllPath, DllPath, 256);
  197. ITypeLib* pTypeLib;
  198. HRESULT hr = LoadTypeLibEx(wDllPath, REGKIND_REGISTER, &pTypeLib);
  199. if(FAILED(hr))
  200. return hr;
  201. pTypeLib->Release();
  202. return RegisterServer("component.dll", CLSID_InsideCOM, "Inside COM+ Sample", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  203. }
  204. HRESULT __stdcall DllUnregisterServer()
  205. {
  206. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  207. return UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  208. }
  209. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  210. {
  211. g_hInstance = hInstance;
  212. return TRUE;
  213. }