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

Windows编程

开发平台:

Visual C++

  1. // component.cpp
  2. #include <ocidl.h>
  3. #include <iostream.h>
  4. #include "Componentcomponent.h" // Generated by MIDL
  5. #include "registry.h"
  6. const REG_DATA g_regData[] = {
  7.     { "CLSID\{10000002-0000-0000-0000-000000000001}", 0, "Inside COM+: In Process Component" },
  8. { "CLSID\{10000002-0000-0000-0000-000000000001}\InprocServer32", 0, (const char*)-1 }, 
  9. { "CLSID\{10000002-0000-0000-0000-000000000001}\InprocServer32", "ThreadingModel", "Apartment" }, 
  10. { "CLSID\{10000002-0000-0000-0000-000000000001}\ProgID", 0, "Component.InsideCOM.1" },
  11. { "CLSID\{10000002-0000-0000-0000-000000000001}\VersionIndependentProgID", 0, "Component.InsideCOM" },
  12. { "Component.InsideCOM", 0, "Inside COM+: In Process Component" },
  13. { "Component.InsideCOM\CLSID", 0, "{10000002-0000-0000-0000-000000000001}" },
  14. { "Component.InsideCOM\CurVer", 0, "Component.InsideCOM.1" },
  15. { "Component.InsideCOM.1", 0, "Inside COM+: In Process Component" },
  16. { "Component.InsideCOM.1\CLSID", 0, "{10000002-0000-0000-0000-000000000001}" },
  17. { 0, 0, 0 }
  18. };
  19. // {10000001-1111-0000-0000-000000000001}
  20. const CLSID CLSID_MarshalByValue = {0x10000001,0x1111,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
  21. HINSTANCE g_hInstance;
  22. long g_cLocks = 0;
  23. class CInsideCOM : public ISum, public IPersistStream, public IPersistStreamInit
  24. {
  25. public:
  26. // IUnknown
  27. ULONG __stdcall AddRef();
  28. ULONG __stdcall Release();
  29. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  30. // ISum
  31. HRESULT __stdcall Initialize(int x, int y);
  32. HRESULT __stdcall GetSum(int* retval);
  33. // IPersistStream
  34.     HRESULT __stdcall IsDirty(void);
  35.     HRESULT __stdcall Load(IStream *pStm);
  36.     HRESULT __stdcall Save(IStream *pStm, BOOL fClearDirty);
  37.     HRESULT __stdcall GetSizeMax(ULARGE_INTEGER *pcbSize);
  38. // IPersistStreamInit
  39.     HRESULT __stdcall InitNew(void);
  40. // IPersist
  41. HRESULT __stdcall GetClassID(CLSID* pClassID);
  42. HRESULT Init();
  43. CInsideCOM() : m_cRef(1) { g_cLocks++; }
  44. ~CInsideCOM()
  45. {
  46. cout << "Component: CInsideCOM::~CInsideCOM()" << endl;
  47. g_cLocks--;
  48. if(m_pUnknownInner)
  49. {
  50. cout << "Going to Release" << endl;
  51. m_pUnknownInner->Release();
  52. cout << "Finished to Release" << endl;
  53. }
  54. }
  55. private:
  56. IUnknown* m_pUnknownInner;
  57. ULONG m_cRef;
  58. int m_x;
  59. int m_y;
  60. };
  61. // This code goes in an Init method because a constructor cannot return an error code
  62. HRESULT CInsideCOM::Init()
  63. {
  64. m_pUnknownInner = 0;
  65. return CoCreateInstance(CLSID_MarshalByValue, (ISum*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&m_pUnknownInner);
  66. }
  67. HRESULT CInsideCOM::InitNew(void)
  68. {
  69. cout << "InitNew" << endl;
  70. return S_OK;
  71. }
  72. HRESULT CInsideCOM::GetClassID(CLSID* pClassID)
  73. {
  74. cout << "GetClassID" << endl;
  75. *pClassID = CLSID_InsideCOM;
  76. return S_OK;
  77. }
  78. HRESULT CInsideCOM::IsDirty(void)
  79. {
  80. cout << "IsDirty" << endl;
  81. return S_OK;
  82. }
  83. HRESULT CInsideCOM::Load(IStream *pStm)
  84. {
  85. ULONG read = 0;
  86. int data[2] = { 0, 0 };
  87. pStm->Read(data, sizeof(data), &read);
  88. m_x = data[0];
  89. m_y = data[1];
  90. char say[255];
  91. wsprintf(say, "IPersistStream::Load read = %d, x = %d, y = %d, %0x", read, m_x, m_y, this);
  92. cout << say << endl;
  93. return S_OK;
  94. }
  95. HRESULT CInsideCOM::Save(IStream *pStm, BOOL fClearDirty)
  96. {
  97. ULONG written = 0;
  98. int data[2] = { m_x, m_y };
  99. HRESULT hr = pStm->Write(data, sizeof(data), &written);
  100. char say[255];
  101. wsprintf(say, "IPersistStream::Save written = %d, x = %d, y = %d", written, m_x, m_y);
  102. cout << say << endl;
  103. return S_OK;
  104. }
  105. HRESULT CInsideCOM::GetSizeMax(ULARGE_INTEGER *pcbSize)
  106. {
  107. cout << "IPersistStream::GetSizeMax" << endl;
  108. (*pcbSize).QuadPart = 2;
  109. return S_OK;
  110. }
  111. ULONG CInsideCOM::AddRef()
  112. {
  113. return ++m_cRef;
  114. }
  115. ULONG CInsideCOM::Release()
  116. {
  117. if(--m_cRef != 0)
  118. return m_cRef;
  119. delete this;
  120. return 0;
  121. }
  122. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  123. {
  124. if(riid == IID_IUnknown)
  125. *ppv = (ISum*)this;
  126. else if(riid == IID_ISum)
  127. *ppv = (ISum*)this;
  128. else if(riid == IID_IMarshal)
  129. {
  130. cout << "Outer object asking inner for IMarshal" << endl;
  131. return m_pUnknownInner->QueryInterface(riid, ppv);
  132. }
  133. else if(riid == IID_IPersistStream || riid == IID_IPersist)
  134. *ppv = (IPersistStream*)this;
  135. else if(riid == IID_IPersistStreamInit)
  136. *ppv = (IPersistStreamInit*)this;
  137. else
  138. {
  139. *ppv = NULL;
  140. return E_NOINTERFACE;
  141. }
  142. AddRef();
  143. return S_OK;
  144. }
  145. HRESULT CInsideCOM::GetSum(int* retval)
  146. {
  147. *retval = m_x + m_y;
  148. char say[255];
  149. wsprintf(say, "ISum::GetSum x = %d, y = %d, %0x", m_x, m_y, this);
  150. cout << say << endl;
  151. return S_OK;
  152. }
  153. HRESULT CInsideCOM::Initialize(int x, int y)
  154. {
  155. cout << "component: ISum::Initialize" << endl;
  156. // store values for GetSum
  157. m_x = x;
  158. m_y = y;
  159. return S_OK;
  160. }
  161. class CFactory : public IClassFactory
  162. {
  163. public:
  164. // IUnknown
  165. ULONG __stdcall AddRef();
  166. ULONG __stdcall Release();
  167. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  168. // IClassFactory
  169. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  170. HRESULT __stdcall LockServer(BOOL bLock);
  171. CFactory() : m_cRef(1) { g_cLocks++; }
  172. ~CFactory() { g_cLocks--; }
  173. private:
  174. ULONG m_cRef;
  175. };
  176. ULONG CFactory::AddRef()
  177. {
  178. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  179. return ++m_cRef;
  180. }
  181. ULONG CFactory::Release()
  182. {
  183. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  184. if(--m_cRef != 0)
  185. return m_cRef;
  186. delete this;
  187. return 0;
  188. }
  189. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  190. {
  191. if(riid == IID_IUnknown || riid == IID_IClassFactory)
  192. *ppv = (IClassFactory*)this;
  193. else
  194. {
  195. *ppv = NULL;
  196. return E_NOINTERFACE;
  197. }
  198. AddRef();
  199. return S_OK;
  200. }
  201. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
  202. {
  203. if(pUnknownOuter != NULL)
  204. return CLASS_E_NOAGGREGATION;
  205. CInsideCOM *pInsideCOM = new CInsideCOM;
  206. if(pInsideCOM == NULL)
  207. return E_OUTOFMEMORY;
  208. HRESULT hr = pInsideCOM->Init();
  209. if(FAILED(hr))
  210. {
  211. cout << "Init failed" << endl;
  212. return hr;
  213. }
  214. hr = pInsideCOM->QueryInterface(riid, ppv);
  215. pInsideCOM->Release();
  216. return hr;
  217. }
  218. HRESULT CFactory::LockServer(BOOL bLock)
  219. {
  220. if(bLock)
  221. g_cLocks++;
  222. else
  223. g_cLocks--;
  224. return S_OK;
  225. }
  226. HRESULT __stdcall DllCanUnloadNow()
  227. {
  228. cout << "Component: DllCanUnloadNow() " << (g_cLocks == 0 ? "Yes" : "No") << endl;
  229. if(g_cLocks == 0)
  230. return S_OK;
  231. else
  232.     return S_FALSE;
  233. }
  234. HRESULT __stdcall DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
  235. {
  236. if(clsid != CLSID_InsideCOM)
  237. return CLASS_E_CLASSNOTAVAILABLE;
  238. CFactory* pFactory = new CFactory;
  239. if(pFactory == NULL)
  240. return E_OUTOFMEMORY;
  241. HRESULT hr = pFactory->QueryInterface(riid, ppv);
  242. pFactory->Release();
  243. return hr;
  244. }
  245. HRESULT __stdcall DllRegisterServer()
  246. {
  247. char DllPath[MAX_PATH];
  248. GetModuleFileName(g_hInstance, DllPath, sizeof(DllPath));
  249. OLECHAR wDllPath[MAX_PATH];
  250. mbstowcs(wDllPath, DllPath, sizeof(wDllPath));
  251. ITypeLib* pTypeLib;
  252. HRESULT hr = LoadTypeLibEx(wDllPath, REGKIND_REGISTER, &pTypeLib);
  253. if(FAILED(hr))
  254. return hr;
  255. pTypeLib->Release();
  256. return RegisterServerEx(g_regData, DllPath);
  257. }
  258. HRESULT __stdcall DllUnregisterServer()
  259. {
  260. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  261. return UnregisterServerEx(g_regData);
  262. }
  263. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void* pv)
  264. {
  265. g_hInstance = hInstance;
  266. return TRUE;
  267. }