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

Windows编程

开发平台:

Visual C++

  1. // component.cpp
  2. #define _WIN32_DCOM    // For CoInitializeEx
  3. #include <iostream.h>  // For cout
  4. #include <comcat.h>    // For component category stuff
  5. #include "registry.h"  // Registry functions
  6. #include "Componentcomponent.h" // Generated by MIDL
  7. long g_cComponents = 0;
  8. long g_cServerLocks = 0;
  9. HANDLE g_hEvent;
  10. // Category identifier for Arithmetic objects
  11. CATID CATID_Math = {0x10000010,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}};
  12. class CInsideCOM : public ISum
  13. {
  14. public:
  15. // IUnknown
  16. ULONG __stdcall AddRef();
  17. ULONG __stdcall Release();
  18. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  19. // ISum
  20. HRESULT __stdcall Sum(int x, int y, int* retval);
  21. CInsideCOM() : m_cRef(0) { g_cComponents++; }
  22. ~CInsideCOM() { cout << "Component: CInsideCOM::~CInsideCOM()" << endl, g_cComponents--; }
  23. private:
  24. long m_cRef;
  25. };
  26. ULONG __stdcall CInsideCOM::AddRef()
  27. {
  28. cout << "Component: CInsideCOM::AddRef() m_cRef = " << m_cRef + 1 << endl;
  29. return ++m_cRef;
  30. }
  31. ULONG __stdcall CInsideCOM::Release()
  32. {
  33. cout << "Component: CInsideCOM::Release() m_cRef = " << m_cRef - 1 << endl;
  34. if(--m_cRef == 0)
  35. {
  36. SetEvent(g_hEvent); // ADD THIS!!!
  37. delete this;
  38. return 0;
  39. }
  40. return m_cRef;
  41. }
  42. HRESULT __stdcall CInsideCOM::QueryInterface(REFIID iid, void** ppv)
  43. {
  44. if(iid == IID_IUnknown)
  45. {
  46. cout << "Component: CInsideCOM::QueryInterface() for IUnknown returning " << this << endl;
  47. *ppv = reinterpret_cast<IUnknown*>(this);
  48. }
  49. else if(iid == IID_ISum)
  50. {
  51. cout << "Component: CInsideCOM::QueryInterface() for ISum returning " << this << endl;
  52. *ppv = (ISum*)this;
  53. }
  54. else 
  55. {
  56. *ppv = NULL;
  57. return E_NOINTERFACE;
  58. }
  59. AddRef();
  60. return S_OK;
  61. }
  62. HRESULT __stdcall CInsideCOM::Sum(int x, int y, int* retval)
  63. {
  64. cout << "Component: CInsideCOM::Sum() " << x << " + " << y << " = " << x + y << endl;
  65. *retval = x + y;
  66. return S_OK;
  67. }
  68. class CFactory : public IClassFactory
  69. {
  70. public:
  71. // IUnknown
  72. ULONG __stdcall AddRef();
  73. ULONG __stdcall Release();
  74. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  75. // IClassFactory
  76. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv);
  77. HRESULT __stdcall LockServer(BOOL bLock);
  78. CFactory() : m_cRef(0) { }
  79. ~CFactory() { }
  80. private:
  81. long m_cRef;
  82. };
  83. ULONG __stdcall CFactory::AddRef()
  84. {
  85. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  86. return ++m_cRef;
  87. }
  88. ULONG __stdcall CFactory::Release()
  89. {
  90. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  91. if(--m_cRef == 0)
  92. {
  93. delete this;
  94. return 0;
  95. }
  96. return m_cRef;
  97. }
  98. HRESULT __stdcall CFactory::QueryInterface(REFIID iid, void** ppv)
  99. {
  100. if((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  101. {
  102. cout << "Component: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  103. *ppv = (IClassFactory *)this;
  104. }
  105. else
  106. {
  107. *ppv = NULL;
  108. return E_NOINTERFACE;
  109. }
  110. AddRef();
  111. return S_OK;
  112. }
  113. HRESULT __stdcall CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv)
  114. {
  115. if(pUnknownOuter != NULL)
  116. return CLASS_E_NOAGGREGATION;
  117. CInsideCOM *pInsideCOM = new CInsideCOM;
  118. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  119. if(pInsideCOM == NULL)
  120. return E_OUTOFMEMORY;
  121. // QueryInterface probably for IID_IUNKNOWN
  122. return pInsideCOM->QueryInterface(iid, ppv);
  123. }
  124. HRESULT __stdcall CFactory::LockServer(BOOL bLock)
  125. {
  126. bLock ? g_cServerLocks++ : g_cServerLocks--;
  127. return S_OK;
  128. }
  129. void RegisterComponent()
  130. {
  131. ITypeLib* pTypeLib;
  132. LoadTypeLibEx(L"component.exe", REGKIND_DEFAULT, &pTypeLib);
  133. RegisterServer("component.exe", CLSID_InsideCOM, "Inside COM Sample #1", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  134. // Instantiate COM's implementation of component categories
  135. ICatRegister* pCatRegister;
  136. CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pCatRegister);
  137. // Set up the CATEGORYINFO structure
  138. CATEGORYINFO catinfo;
  139. catinfo.catid = CATID_Math;
  140. catinfo.lcid = 0x0409;
  141. wcsncpy(catinfo.szDescription, L"Arithmetic Objects", 128);
  142. // Install the component category
  143. pCatRegister->RegisterCategories(1, &catinfo);
  144. // Register InsideCOM as an Arithmetic object
  145. CATID rgcatid[1];
  146. rgcatid[0] = CATID_Math;
  147. pCatRegister->RegisterClassImplCategories(CLSID_InsideCOM, 1, rgcatid);
  148. // Release COM's implementation of component categories
  149. pCatRegister->Release();
  150. // Instantiate COM's implementation of component categories
  151. // This time ask for ICatInformation
  152. ICatInformation* pCatInformation;
  153. CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatInformation, (void**)&pCatInformation);
  154. // Get an enumerator for all CLSIDs that are Arithmetic objects
  155. IEnumCLSID* pEnumCLSID;
  156. pCatInformation->EnumClassesOfCategories(1, &CATID_Math, 0, NULL, &pEnumCLSID);
  157. // Release the ICatInformation interface pointer
  158. pCatInformation->Release();
  159. // Loop through the enumerator
  160. CLSID clsid = CLSID_NULL;
  161. DWORD fetched = 0;
  162. while(true)
  163. {
  164. // Get the next CLSID
  165. pEnumCLSID->Next(1, &clsid, &fetched);
  166. if(fetched == 0)
  167. break;
  168. // Convert the CLSID to a string for display
  169. char buffer[39];
  170. OLECHAR ppsz[39];
  171. StringFromGUID2(clsid, ppsz, 39);
  172. WideCharToMultiByte(CP_ACP, 0, ppsz, 39, buffer, 39, NULL, NULL);
  173. // Print out the CLSIDs of the objects found
  174. cout << "CLSID that supports the Arithmetic Object category is " << buffer << endl;
  175. }
  176. // Release the enumerator
  177. pEnumCLSID->Release();
  178. }
  179. void CommandLineParameters(int argc, char** argv)
  180. {
  181. RegisterComponent();
  182. if(argc < 2)
  183. {
  184. cout << "No parameter, but registered anyway" << endl;
  185. exit(false);
  186. }
  187. char* szToken = strtok(argv[1], "-/"); 
  188. if(_stricmp(szToken, "RegServer") == 0)
  189. {
  190. RegisterComponent();
  191. cout << "RegServer" << endl;
  192. exit(true);
  193. }
  194. if(_stricmp(szToken, "UnregServer") == 0)
  195. {
  196. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  197. UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  198. // Instantiate COM's implementation of component categories
  199. ICatRegister* pCatRegister;
  200. CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pCatRegister);
  201. // Delete the component category
  202. pCatRegister->UnRegisterCategories(1, &CATID_Math);
  203. // Unregister InsideCOM as no longer being an Arithmetic object
  204. CATID rgcatid[1];
  205. rgcatid[0] = CATID_Math;
  206. pCatRegister->UnRegisterClassImplCategories(CLSID_InsideCOM, 1, rgcatid);
  207. // Release COM's implementation of component categories
  208. pCatRegister->Release();
  209. cout << "UnregServer" << endl;
  210. exit(true);
  211. }
  212. if(_stricmp(szToken, "Embedding") != 0)
  213. {
  214. cout << "Invalid parameter" << endl;
  215. exit(false);
  216. }
  217. }
  218. void main(int argc, char** argv)
  219. {
  220. cout << "Component: CoInitializeEx()" << endl;
  221. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  222. CommandLineParameters(argc, argv);
  223. IClassFactory *pClassFactory = new CFactory();
  224. cout << "Component: CoRegisterClassObject()" << endl;
  225. DWORD dwRegister;
  226. CoRegisterClassObject(CLSID_InsideCOM, pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
  227. g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  228. WaitForSingleObject(g_hEvent, INFINITE);
  229. CoRevokeClassObject(dwRegister);
  230. pClassFactory->Release();
  231. CoUninitialize();
  232. }