久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

com技術(shù)內(nèi)幕

 uqt123 2012-07-25

com技術(shù)內(nèi)幕--讀書筆記(7)

分類: com 66人閱讀 評(píng)論(0) 收藏 舉報(bào)

第7章

相信有了前六章的知識(shí)積累,學(xué)些以后的章節(jié)將會(huì)很順利,。本章實(shí)現(xiàn)了一個(gè)真正的COM組件,并通過client客戶端來使用這個(gè)組件,。

本章將介紹類廠,,類廠是能夠創(chuàng)建其他組件的組件,CoCreateInstance函數(shù)也是按照一定方法通過類廠來創(chuàng)建組件的,。

CoCreateInstance

CoCreateInstance函數(shù)是COM庫(kù)的函數(shù),,函數(shù)原型如下

  1. HRESULT __stdcall CoCreateInstance(const CLSID &clsid,   
  2.                            IUnknown *pIUnkownOuter, //Outer Component   
  3.                                DWORD dwClsContext,      //Server Context   
  4.                                    const IID &iid,  
  5.                            void **ppv);  

其中前四個(gè)是輸入?yún)?shù),最后一個(gè)是輸出參數(shù),。第一個(gè)參數(shù)clsid是所創(chuàng)建組件的CLSID,,第二個(gè)參數(shù)pIUnkownOuter是聚合組件需要用的,將在第8章介紹,,第三個(gè)參數(shù)dwClsContext是限定所創(chuàng)建組件的執(zhí)行上下文,,第四個(gè)參數(shù)iid是所創(chuàng)建組件的接口的IID,第五個(gè)參數(shù)ppv將返回該接口的指針,。

dwClsContext

dwClsContext可以控制所創(chuàng)建是與客戶在相同的進(jìn)程中運(yùn)行,,還是在不同的進(jìn)程中運(yùn)行,或者是在另外一臺(tái)機(jī)器上運(yùn)行,。此參數(shù)可以是如下值的組合

CLSCTX_INPROC_SERVER         客戶希望創(chuàng)建在同一進(jìn)程中運(yùn)行的組件,,因此組件必須是在DLL中實(shí)現(xiàn)。

CLSCTX_INPROC_HANDLER      客戶希望創(chuàng)建進(jìn)程中處理器,。

CLSCTX_LOCAL_SERVER           客戶希望創(chuàng)建一個(gè)在同一機(jī)器上的另外一個(gè)進(jìn)程中運(yùn)行的組件,。組件是由EXE實(shí)現(xiàn)的。

CLSCTX_REMOTE_SERVER       客戶希望創(chuàng)建一個(gè)在遠(yuǎn)程機(jī)器上運(yùn)行的組件,。分布式COM組件。

在OBJBASE.H中定義了一些上述值的組合,。


CoCreateInstance的具有一定的不靈活性,,解決問題的辦法是使用專門用于創(chuàng)建所需組件的組件,這個(gè)組件就是類廠,。

類廠

某個(gè)特定的類廠可以創(chuàng)建某個(gè)特定CLSID相對(duì)應(yīng)的組件,,客戶可以通過類廠提供的接口來對(duì)組件的創(chuàng)建過程進(jìn)行控制,。客戶使用CoCreateInstance所創(chuàng)建的組件實(shí)際上是通過類廠的IClassFactory創(chuàng)建的,,使用類廠創(chuàng)建組件的步驟是首先創(chuàng)建類廠,,然后使用IClassFactory創(chuàng)建所需的組件。

創(chuàng)建類廠

COM庫(kù)函數(shù)CoGetClassObject創(chuàng)建同某個(gè)CLSID相應(yīng)的類廠,。函數(shù)原型如下

  1. HRESULT __stdcall CoGetClassObject(const CLSID &clsid,  
  2.                            DWORD dwClsContext,  
  3.                                    COSERVERINFO *pServerInfo,  
  4.                                    const IID &iid,  
  5.                                    void **ppv);  

同CoCreateInstance非常相似,。第一個(gè)參數(shù)const CLSID&待創(chuàng)建組件的CLSID,第二個(gè)參數(shù)DWORD dwClsContext是待創(chuàng)建組件的執(zhí)行上下文,,第三個(gè)參數(shù)COSERVERINFO*用于遠(yuǎn)程組件的訪問,,將在第10章討論,第四個(gè)參數(shù)const IID&是IClassFactory接口的IID,,第五個(gè)參數(shù)返回IClassFactory接口的指針,。

創(chuàng)建組件

IClassFactory

大多數(shù)組件是使用IClassFactory來創(chuàng)建的,原型如下

  1. interface IClassFactory:IUnknown  
  2. {  
  3.     HRESULT __stdcall CreateInstance(IUnkown *pUnknownOuter, const IID &id, void **ppv);  
  4.     HRESULT __stdcall LockServer(BOOL bLock);  
  5. };  

IClassFactory::CreateInstance函數(shù)的第一個(gè)參數(shù)IUnknown*是組件聚合使用的,,將在第8章介紹,,后兩個(gè)參數(shù)跟CoCreateInstance后兩個(gè)參數(shù)作用相同,將在創(chuàng)建組件的

同時(shí)返回此組件的某個(gè)接口指針,??梢钥吹絀ClassFactory::CreateInstance并沒有接收一個(gè)CLSID參數(shù),這意味著此函數(shù)將只能創(chuàng)建同某個(gè)CLSID——即傳給CoGetClassObject的參數(shù)CLSID相應(yīng)的組件,。

在兩種情況下使用創(chuàng)建類廠再創(chuàng)建組件的方法,,而不是直接使用CoCreateInstance的方法直接創(chuàng)建組件

(1)想使用IClassFactory2來創(chuàng)建組件。IClassFactory2是Microsoft定義的另外一個(gè)接口,,此接口在IClassFactory的基礎(chǔ)上增加了獲取組件接口的許可權(quán)限功能,。

(2)需要?jiǎng)?chuàng)建一個(gè)組件的多個(gè)實(shí)例。這樣只需創(chuàng)建相應(yīng)的類廠一次,,而CoCreateInstance需要為每一個(gè)組件實(shí)例分別創(chuàng)建并釋放相應(yīng)的類廠,。

類廠的特性

(1)類廠將只能給你創(chuàng)建同某個(gè)CLSID相應(yīng)的組件。

(2)與某個(gè)特定CLSID相應(yīng)的類廠是由組件開發(fā)人員來實(shí)現(xiàn)的,。大多數(shù)情況下,,類廠組件包含在它所創(chuàng)建的組件的相同的DLL中。

類廠的創(chuàng)建

客戶通過CoGetClassObject來創(chuàng)建類廠,,這就需要在DLL中實(shí)現(xiàn)一個(gè)特定的函數(shù),,此函數(shù)名為DllGetClassObject,函數(shù)原型如下

  1. STDAPI DllGetClassObject(const CLSID &clsid, const IID &iid, void **ppv);  
函數(shù)的三個(gè)參數(shù)同CoGetClassObject中參數(shù)的意義相同,。

通過類廠來創(chuàng)建組件的示意圖如下,,COM庫(kù)函數(shù)CoGetClassObject將根據(jù)傳入?yún)?shù)CLSID查詢注冊(cè)表,裝載組件所在的DLL庫(kù)。

CFactory只不過是另外一個(gè)組件而已,,它也跟其他組件一樣實(shí)現(xiàn)了IUnknown接口,。

IClassFactory::CreateInstance和DllGetClassObject的實(shí)現(xiàn)是相同的,這兩個(gè)函數(shù)都將創(chuàng)建一個(gè)組件然后向它查詢某個(gè)接口,。


組件的注冊(cè)

實(shí)現(xiàn)組件的DLL中輸出四個(gè)函數(shù),,除了DllGetClassObject外,DllRegisterServer和DllUnregisterServer將用于組件在注冊(cè)表中注冊(cè)和取消注冊(cè)(鏈接的時(shí)候需要鏈接Advapi32.lib),,調(diào)用regsvr32來完成注冊(cè)和取消,。

類廠的復(fù)用

在設(shè)計(jì)類廠和組件的時(shí)候,可以做到只用一個(gè)類廠的實(shí)現(xiàn)來完成所有組件的創(chuàng)建,。將在第9章中實(shí)現(xiàn),。但即使是這樣,類廠CFactory的一個(gè)實(shí)例也僅能創(chuàng)建一個(gè)同某個(gè)CLSID相應(yīng)的組件,。


DLL的卸載

COM庫(kù)中實(shí)現(xiàn)了一個(gè)CoFreeUnusedLibraries的函數(shù),,以釋放那些不再需要使用的DLL庫(kù)所占用的內(nèi)存,由組件的客戶進(jìn)行調(diào)用,。

DllCanUnloadNow函數(shù)

也是在實(shí)現(xiàn)組件的DLL中的輸出函數(shù),,CoFreeUnusedLibraries函數(shù)將調(diào)用DllCanUnloadNow函數(shù),以詢問Dll是否可以被卸載,。代碼中g(shù)_lComponents的作用就是這個(gè),,可以看到IClassFactory::CreateInstance也就是說在創(chuàng)建組件的時(shí)候,組件的構(gòu)造函數(shù)都可以將g_lComponents增大,,組件的析構(gòu)函數(shù)可以將g_lComponents的值減小,。若g_lComponets值為0,CoFreeUnusedLibraries可以將組件的DLL卸載掉,。

LockServer函數(shù)

使用g_lComponents只是對(duì)DLL中的組件進(jìn)行了記數(shù),,另外一個(gè)組件CFactory并沒有記數(shù)。對(duì)類廠的記數(shù)使用了IFactory::LockServer函數(shù),,組件Server內(nèi)部設(shè)置了另外一個(gè)與g_IComponents不同的計(jì)數(shù)值進(jìn)行計(jì)數(shù),。(將在第10章進(jìn)行討論,主要原因是因?yàn)榈?0章將會(huì)講到的進(jìn)程外組件(exe實(shí)現(xiàn)的)的類廠無法像進(jìn)程中的組件(dll實(shí)現(xiàn)的)一樣方便的進(jìn)行記數(shù),。)


本章代碼

組件端:

cmpnt.cpp

  1. //   
  2. //cmpnt.cpp   
  3. //use: cl /LD cmpnt.cpp guids.cpp registry.cpp cmpnt.def uuid.lib ole32.lib Advapi32.lib    
  4. //     regsvr32 -s cmpnt.dll   
  5.   
  6. #include <objbase.h>   
  7. #include "iface.h"    //interface declarations   
  8. #include "Registry.h"  //Registry helper function   
  9. #include <iostream>   
  10. #include <string>   
  11. using namespace std;  
  12.   
  13. //trace function   
  14. void trace(string msg)  
  15. {  
  16.     cout<<msg<<endl;  
  17. }   
  18.   
  19. //global variable   
  20. //   
  21. static HMODULE g_hModule = NULL;        //DLL Module handle   
  22. static long    g_lComponent = 0;        //Count of active component   
  23. static long    g_lServerLocks = 0;      //Count of locks   
  24.   
  25. //Friendly name of component   
  26. const char g_szFriendlyName[] = "InsideCOM Chapter 7 Example";  
  27.   
  28. //Version independent ProgID   
  29. const char g_szVerIndProgID[] = "InsideCOM.Chap07";  
  30.   
  31. //ProgID   
  32. const char g_szProgID[] = "InsideCOM.Chap07.1";  
  33.   
  34. //Component   
  35. class CA:public IX, public IY  
  36. {  
  37. public:  
  38.     //IUnknown   
  39.     virtual HRESULT __stdcall QueryInterface(const IID &iid, void **ppv);  
  40.     virtual ULONG   __stdcall AddRef();  
  41.     virtual ULONG   __stdcall Release();  
  42.     virtual void    __stdcall Fx() {cout<<"Fx"<<endl;}  
  43.     virtual void    __stdcall Fy() {cout<<"Fy"<<endl;}  
  44.     CA();  
  45.     ~CA();  
  46. protected:  
  47.     long m_cRef;  
  48. };  
  49.   
  50. CA::CA()  
  51. {  
  52.     m_cRef = 1;   //注意這里與前幾章不一樣,,m_cRef=1意味著只要CA組件被創(chuàng)建就計(jì)數(shù)為1,這樣IFactory::CreateInstance創(chuàng)建CA組   
  53.                   //件時(shí),,就不用調(diào)用AddRef()了   
  54.     InterlockedIncrement(&g_lComponent);  
  55. }  
  56.   
  57. CA::~CA()  
  58. {  
  59.     InterlockedDecrement(&g_lComponent);  
  60.     trace("Component:destroy self");  
  61. }  
  62.   
  63. //IUnknown implement   
  64. HRESULT __stdcall CA::QueryInterface(const IID &iid, void **ppv)  
  65. {  
  66.     if(iid == IID_IUnknown)  
  67.     {  
  68.         *ppv = static_cast<IX*>(this);  
  69.     }  
  70.     else if(iid == IID_IX)  
  71.     {  
  72.         *ppv = static_cast<IX*>(this);  
  73.         trace("component: return pointer to ix");  
  74.     }  
  75.     else if(iid == IID_IY)  
  76.     {  
  77.         *ppv = static_cast<IY*>(this);  
  78.         trace("component: return pointer to iy");  
  79.     }  
  80.     else  
  81.     {  
  82.         *ppv = NULL;  
  83.         return E_NOINTERFACE;  
  84.     }  
  85.     reinterpret_cast<IUnknown*>(*ppv)->AddRef();  
  86.     return S_OK;  
  87. }  
  88.   
  89. ULONG __stdcall CA::AddRef()  
  90. {  
  91.     return InterlockedIncrement(&m_cRef);  
  92. }  
  93.   
  94. ULONG __stdcall CA::Release()  
  95. {  
  96.     if(InterlockedDecrement(&m_cRef)== 0)  
  97.     {  
  98.         delete this;  
  99.         return 0;  
  100.     }  
  101.     return m_cRef;  
  102. }  
  103.   
  104. ///////////////////////////////////////////   
  105. //class factory   
  106. //   
  107. class CFactory:public IClassFactory  
  108. {  
  109. public:  
  110.     //iunknown   
  111.     virtual HRESULT __stdcall QueryInterface(const IID &iid, void **ppv);  
  112.     virtual ULONG   __stdcall AddRef();  
  113.     virtual ULONG   __stdcall Release();  
  114.     //interface IClassFactory   
  115.     virtual HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, const IID &iid, void **ppv);  
  116.     virtual HRESULT __stdcall LockServer(BOOL bLock);  
  117.     //constructor   
  118.     CFactory():m_cRef(1){}  
  119.     //destructor   
  120.     ~CFactory()  
  121.     {  
  122.         trace("class factory :destory self");  
  123.     }  
  124. private:  
  125.     long m_cRef;  
  126. };  
  127.   
  128. //   
  129. //class factory IUnknown implementation   
  130. //   
  131. HRESULT __stdcall CFactory::QueryInterface(const IID &iid, void **ppv)  
  132. {  
  133.     if((iid == IID_IUnknown) || (iid == IID_IClassFactory))  
  134.     {  
  135.         *ppv = static_cast<IClassFactory*>(this);  
  136.     }  
  137.     else  
  138.     {  
  139.         *ppv = NULL;  
  140.         return E_NOINTERFACE;  
  141.     }  
  142.     reinterpret_cast<IUnknown*>(*ppv)->AddRef();  
  143.     return S_OK;  
  144. }  
  145.   
  146. ULONG __stdcall CFactory::AddRef()  
  147. {  
  148.     return InterlockedIncrement(&m_cRef);  
  149. }  
  150.   
  151. ULONG __stdcall CFactory::Release()  
  152. {  
  153.     if(InterlockedDecrement(&m_cRef) == 0)  
  154.     {  
  155.         delete this;  
  156.         return 0;  
  157.     }  
  158.     return m_cRef;  
  159. }  
  160.   
  161. //   
  162. //IClassFactory implementation   
  163. //   
  164. HRESULT __stdcall CFactory::CreateInstance(IUnknown *pUnknownOuter, const IID &iid, void **ppv)  
  165. {  
  166.     trace("class factory : create component");  
  167.     //Can not aggregate   
  168.     if(pUnknownOuter != NULL)  
  169.     {  
  170.         return CLASS_E_NOAGGREGATION;  
  171.     }  
  172.     //create component   
  173.     CA *pA = new CA();  
  174.     if(pA == NULL)  
  175.     {  
  176.         return E_OUTOFMEMORY;  
  177.     }  
  178.     //Get requested interface   
  179.     HRESULT hr = pA->QueryInterface(iid, ppv);  
  180.   
  181.     //Release the IUnknown pointer   
  182.     pA->Release();  
  183.     return hr;  
  184. }  
  185.   
  186. //lock server   
  187. HRESULT __stdcall CFactory::LockServer(BOOL bLock)  
  188. {  
  189.     if(bLock)  
  190.     {  
  191.         InterlockedIncrement(&g_lServerLocks);  
  192.     }  
  193.     else  
  194.     {  
  195.         InterlockedDecrement(&g_lServerLocks);  
  196.     }  
  197.     return S_OK;  
  198. }  
  199.   
  200. /////////////////////////////////////////////   
  201. //export function   
  202. //   
  203. //get class factory   
  204. STDAPI DllGetClassObject(const CLSID &clsid, const IID &iid, void **ppv)  
  205. {  
  206.     trace("DllGetClassObeject: create class factory");  
  207.     if(clsid != CLSID_Component1)  
  208.     {  
  209.         return CLASS_E_CLASSNOTAVAILABLE;  
  210.     }  
  211.     //create class factory   
  212.     CFactory *pFactory = new CFactory;  
  213.     if(pFactory == NULL)  
  214.     {  
  215.         return E_OUTOFMEMORY;  
  216.     }  
  217.     HRESULT hr = pFactory->QueryInterface(iid, ppv);  
  218.     pFactory->Release();  
  219.     return hr;  
  220. }  
  221.   
  222. STDAPI DllCanUnloadNow()  
  223. {  
  224.     if((g_lComponent == 0) && (g_lServerLocks == 0))  
  225.     {  
  226.         return S_OK;  
  227.     }  
  228.     else  
  229.     {  
  230.         return S_FALSE;  
  231.     }  
  232. }  
  233.   
  234. //server registration   
  235. STDAPI DllRegisterServer()  
  236. {  
  237.     return RegisterServer(g_hModule,  
  238.                           CLSID_Component1,  
  239.                           g_szFriendlyName,  
  240.                           g_szVerIndProgID,  
  241.                           g_szProgID);  
  242. }  
  243.   
  244. //server unregistration   
  245. STDAPI DllUnregisterServer()  
  246. {  
  247.     return UnregisterServer(CLSID_Component1,  
  248.                             g_szVerIndProgID,  
  249.                             g_szProgID);  
  250. }  
  251.   
  252. BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, void *lpReserved)  
  253. {  
  254.     if(dwReason == DLL_PROCESS_ATTACH)  
  255.     {  
  256.         g_hModule = hModule;  
  257.     }  
  258.     return TRUE;  
  259. }  
  260.   
  261.    

cmpnt.def

  1. LIBRARY         Cmpnt.dll  
  2. DESCRIPTION     'Chapter 7 Example COM Component'  
  3.   
  4. EXPORTS         DllGetClassObject   @2  PRIVATE  
  5.                 DllRegisterServer   @3  PRIVATE  
  6.                 DllUnregisterServer @4  PRIVATE  
  7.                 DllCanUnloadNow     @5  PRIVATE  

registry.h

  1. #ifndef _REGISTRY_H_   
  2. #define _REGISTRY_H_   
  3.   
  4. HRESULT RegisterServer(HMODULE hModule,   
  5.                        const CLSID &clsid,  
  6.                        const char *szFriendlyName,  
  7.                        const char *szVerIndProgID,  
  8.                        const char *szProgID);  
  9. HRESULT UnregisterServer(const CLSID &clsid,  
  10.                          const char *szVerIndProgID,  
  11.                          const char *szProgID);  
  12. #endif  

registry.cpp

  1. //   
  2. //registry.cpp   
  3. //   
  4. #include <objbase.h>   
  5. #include <cassert>   
  6. #include "registry.h"   
  7.   
  8. //   
  9. //Internal functions    
  10.   
  11. //Set the key and its value   
  12. BOOL SetKeyAndValue(const char *szKey, const char *szSubKey, const char *szValue);  
  13.   
  14. //Convert a clsid to a char string   
  15. void CLSIDtochar(const CLSID &clsid, char *szClsID, int nLength);  
  16.   
  17. //Delete szKeyChild and all its child   
  18. LONG RecursiveDeleteKey(HKEY hKeyParent, const char *szKeyChild);  
  19.   
  20. const int CLSID_STRING_SIZE = 39 ;  
  21.   
  22. //   
  23. // Register the component in the registry.   
  24. //   
  25. HRESULT RegisterServer(HMODULE hModule,            // DLL module handle   
  26.                        const CLSID& clsid,         // Class ID   
  27.                        const char* szFriendlyName, // Friendly Name   
  28.                        const char* szVerIndProgID, // Programmatic   
  29.                        const char* szProgID)       //   IDs   
  30. {  
  31.     char szModule[512] ;  
  32.     DWORD dwResult =::GetModuleFileName(hModule, szModule, sizeof(szModule)/sizeof(char));  
  33.   
  34.     assert(dwResult != 0) ;  
  35.   
  36.     // Convert the CLSID into a char.   
  37.     char szCLSID[CLSID_STRING_SIZE] ;  
  38.     CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;  
  39.   
  40.     // Build the key CLSID\\{...}   
  41.     char szKey[64] ;  
  42.     strcpy(szKey, "CLSID\\") ;  
  43.     strcat(szKey, szCLSID) ;  
  44.     
  45.     // Add the CLSID to the registry.   
  46.     SetKeyAndValue(szKey, NULL, szFriendlyName) ;  
  47.   
  48.     // Add the server filename subkey under the CLSID key.   
  49.     SetKeyAndValue(szKey, "InprocServer32", szModule) ;  
  50.   
  51.     // Add the ProgID subkey under the CLSID key.   
  52.     SetKeyAndValue(szKey, "ProgID", szProgID) ;  
  53.   
  54.     // Add the version-independent ProgID subkey under CLSID key.   
  55.     SetKeyAndValue(szKey, "VersionIndependentProgID",  
  56.                    szVerIndProgID) ;  
  57.   
  58.     // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.   
  59.     SetKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ;   
  60.     SetKeyAndValue(szVerIndProgID, "CLSID", szCLSID) ;  
  61.     SetKeyAndValue(szVerIndProgID, "CurVer", szProgID) ;  
  62.   
  63.     // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.   
  64.     SetKeyAndValue(szProgID, NULL, szFriendlyName) ;   
  65.     SetKeyAndValue(szProgID, "CLSID", szCLSID) ;  
  66.   
  67.     return S_OK ;  
  68. }  
  69.   
  70. //   
  71. // Remove the component from the registry.   
  72. //   
  73. LONG UnregisterServer(const CLSID& clsid,         // Class ID   
  74.                       const char* szVerIndProgID, // Programmatic   
  75.                       const char* szProgID)       //   IDs   
  76. {  
  77.     // Convert the CLSID into a char.   
  78.     char szCLSID[CLSID_STRING_SIZE] ;  
  79.     CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;  
  80.   
  81.     // Build the key CLSID\\{...}   
  82.     char szKey[64] ;  
  83.     strcpy(szKey, "CLSID\\") ;  
  84.     strcat(szKey, szCLSID) ;  
  85.   
  86.     // Delete the CLSID Key - CLSID\{...}   
  87.     LONG lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;  
  88.     assert( (lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND) ) ; // Subkey may not exist.   
  89.   
  90.     // Delete the version-independent ProgID Key.   
  91.     lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;  
  92.     assert((lResult == ERROR_SUCCESS) ||  
  93.            (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.   
  94.   
  95.     // Delete the ProgID key.   
  96.     lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;  
  97.     assert((lResult == ERROR_SUCCESS) ||  
  98.            (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.   
  99.   
  100.     return S_OK ;  
  101. }  
  102.   
  103.   
  104. BOOL SetKeyAndValue(const char *szKey, const char *szSubKey, const char *szValue)  
  105. {  
  106.     HKEY hKey;  
  107.     char szKeyBuf[1024] ;  
  108.   
  109.     // Copy keyname into buffer.   
  110.     strcpy(szKeyBuf, szKey) ;  
  111.   
  112.     // Add subkey name to buffer.   
  113.     if (szSubKey != NULL)  
  114.     {  
  115.         strcat(szKeyBuf, "\\") ;  
  116.         strcat(szKeyBuf, szSubKey ) ;  
  117.     }  
  118.   
  119.     // Create and open key and subkey.   
  120.     long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,  
  121.                                   szKeyBuf,   
  122.                                   0, NULL, REG_OPTION_NON_VOLATILE,  
  123.                                   KEY_ALL_ACCESS, NULL,   
  124.                                   &hKey, NULL) ;  
  125.     if (lResult != ERROR_SUCCESS)  
  126.     {  
  127.         return FALSE ;  
  128.     }  
  129.   
  130.     // Set the Value.   
  131.     if (szValue != NULL)  
  132.     {  
  133.         RegSetValueEx(hKey, NULL, 0, REG_SZ,   
  134.                       (BYTE *)szValue,   
  135.                       strlen(szValue)+1) ;  
  136.     }  
  137.   
  138.     RegCloseKey(hKey) ;  
  139.     return TRUE ;  
  140.       
  141. }  
  142.   
  143.   
  144. LONG RecursiveDeleteKey(HKEY hKeyParent, const char *szKeyChild)  
  145. {  
  146.     // Open the child.   
  147.     HKEY hKeyChild ;  
  148.     LONG lRes = RegOpenKeyEx(hKeyParent, szKeyChild, 0,  
  149.                              KEY_ALL_ACCESS, &hKeyChild) ;  
  150.     if (lRes != ERROR_SUCCESS)  
  151.     {  
  152.         return lRes ;  
  153.     }  
  154.   
  155.     // Enumerate all of the decendents of this child.   
  156.     FILETIME time ;  
  157.     char szBuffer[256] ;  
  158.     DWORD dwSize = 256 ;  
  159.     while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,  
  160.                         NULL, NULL, &time) == S_OK)  
  161.     {  
  162.         // Delete the decendents of this child.   
  163.         lRes = RecursiveDeleteKey(hKeyChild, szBuffer) ;  
  164.         if (lRes != ERROR_SUCCESS)  
  165.         {  
  166.             // Cleanup before exiting.   
  167.             RegCloseKey(hKeyChild) ;  
  168.             return lRes;  
  169.         }  
  170.         dwSize = 256 ;  
  171.     }  
  172.   
  173.     // Close the child.   
  174.     RegCloseKey(hKeyChild) ;  
  175.   
  176.     // Delete this child.   
  177.     return RegDeleteKey(hKeyParent, szKeyChild) ;  
  178. }  
  179.   
  180. void CLSIDtochar(const CLSID &clsid, char *szClSID, int nLength)  
  181. {  
  182.     assert(nLength >= CLSID_STRING_SIZE) ;  
  183.     // Get CLSID   
  184.     LPOLESTR wszCLSID = NULL ;  
  185.     HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;  
  186.     assert(SUCCEEDED(hr)) ;  
  187.   
  188.     // Covert from wide characters to non-wide.   
  189.     wcstombs(szClSID, wszCLSID, nLength);  
  190.   
  191.     // Free memory.   
  192.     CoTaskMemFree(wszCLSID) ;  
  193. }  

iface.h

  1. //iface.h   
  2. //   
  3. #include <objbase.h>   
  4. interface IX:IUnknown  
  5. {  
  6.     virtual void __stdcall Fx() = 0;  
  7. };  
  8.   
  9. interface IY:IUnknown  
  10. {  
  11.     virtual void __stdcall Fy() = 0;  
  12. };  
  13.   
  14. interface IZ:IUnknown  
  15. {  
  16.     virtual void __stdcall Fz() = 0;  
  17. };  
  18.   
  19. extern const IID   IID_IX;  
  20. extern const IID   IID_IY;  
  21. extern const IID   IID_IZ;  
  22. extern const CLSID CLSID_Component1;  
  23.    

guids.cpp

  1. //   
  2. // GUIDs.cpp   
  3. //    
  4. #include <objbase.h>   
  5.   
  6. // {32bb8320-b41b-11cf-a6bb-0080c7b2d682}   
  7. extern const IID IID_IX =   
  8.     {0x32bb8320, 0xb41b, 0x11cf,  
  9.     {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;  
  10.   
  11. // {32bb8321-b41b-11cf-a6bb-0080c7b2d682}   
  12. extern const IID IID_IY =   
  13.     {0x32bb8321, 0xb41b, 0x11cf,  
  14.     {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;  
  15.   
  16. // {32bb8322-b41b-11cf-a6bb-0080c7b2d682}   
  17. extern const IID IID_IZ =   
  18.     {0x32bb8322, 0xb41b, 0x11cf,  
  19.     {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;  
  20.   
  21. // {0c092c21-882c-11cf-a6bb-0080c7b2d682}   
  22. extern const CLSID CLSID_Component1 =  
  23.     {0x0c092c21, 0x882c, 0x11cf,  
  24.     {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;  
  25.   
  26.    

客戶端

clients.cpp

  1. //   
  2. //Client.cpp - client implementation   
  3. //use:cl client.cpp guids.cpp uuid.lib ole32.lib   
  4. //   
  5. #include <objbase.h>   
  6. #include "iface.h"   
  7. #include <iostream>   
  8. #include <string>   
  9. using namespace std;  
  10.   
  11. void trace(string msg)  
  12. {  
  13.     cout<<msg<<endl;  
  14. }  
  15.   
  16. int main(void)  
  17. {  
  18.     CoInitialize(NULL);  
  19.     trace("client:call CoCreateInstance to create component and get interface ix");  
  20.     IX *pIx = NULL;  
  21.     HRESULT hr = ::CoCreateInstance(CLSID_Component1, NULL, CLSCTX_INPROC_SERVER, IID_IX, (void**)&pIx);  
  22.     if(SUCCEEDED(hr))  
  23.     {  
  24.         trace("client:Succeeded getting IX");  
  25.         pIx->Fx();  
  26.         trace("client:Ask for interface IY");  
  27.         IY *pIy = NULL;  
  28.         hr = pIx->QueryInterface(IID_IY, (void**)&pIy);  
  29.         if(SUCCEEDED(hr))  
  30.         {  
  31.             trace("client:Succeeded getting IY");  
  32.             pIy->Fy();  
  33.             pIy->Release();  
  34.             trace("client:Release IY interface");  
  35.         }  
  36.         else  
  37.         {  
  38.             trace("client:Could not get interface IY");  
  39.         }  
  40.         trace("client:Ask for interface IZ");  
  41.         IZ *pIz = NULL;  
  42.         hr = pIx->QueryInterface(IID_IZ, (void**)&pIz);  
  43.         if(SUCCEEDED(hr))  
  44.         {  
  45.             trace("client:Succeeded getting IZ");  
  46.             pIz->Fz();  
  47.             pIz->Release();  
  48.             trace("client:Release IZ interface");  
  49.         }  
  50.         else  
  51.         {  
  52.             trace("client:Could not get interface IZ");  
  53.         }  
  54.         trace("client:Release IX interface");  
  55.         pIx->Release();  
  56.     }  
  57.     else  
  58.     {  
  59.         cout<<"Client: Could not create component.hr ="<<hex<<hr<<endl;  
  60.     }  
  61.     CoUninitialize();  
  62.     return 0;  
  63. }  


運(yùn)行結(jié)果


分享到:

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多