使用COM介面:
當你建立COM對象的時候,建立COM對象的這個方法就返回一個介面的指標。然後你可以利用這個介面的指標訪問這個介面的其它的方法。指標的使用方法和在c++中的指標的使用方法是相同的。下面的程式碼片段擴充了上一篇文章中的那個程式碼片段。建立DirectPlay8對象後,利用CoCreateInstance函數建立了一個IDirectPlay8Peer介面指標,然後利用這個介面指標呼叫了IDirectPlay8Peer::Initialize方法從而進行初始化。下面的代碼, 我為了清潔,省略了錯誤碼的驗證。
IDirectPlay8Peer * g_pDP = NULL ;
...
CoInitialize( NULL ) ;
...
hr = CoCreateInstance( CLSID_DirectPlay8Peer, NULL, CLSCTX_INPROC_SERVER,
IID_IDirectPlay8Peer, (LPVOID *)&g_pDP ) ;
hr = g_pDP->Initialize( NULL,DirectPlayMessageHandler, 0 ) ;
申請附加的介面:
在很多情況下,你用建立對象時返回的那個介面指標可能就是你需要的那個指標。事實上,除了IUknown之外, 一個對象只能輸出一個介面也是很常見的。然而,還有很多的對象能夠輸出多個介面,你可以得到指向它們的指標。假如你需要對象的多個介面,你不需要建立新的對象,取而代之的是你可以呼叫對象的IUnkoown::QueryInterface方法來得到你所需要的其它的介面指標。
假如你使用CoCreateInstance建立了一個對象,你可以得到IUnkonw介面的指標,你可以通過調用IUnkonwn::QueryInterface來得到你所需要的每一個介面的指標。然而,如果你僅僅需要得到一個簡單的介面,這種方法是不方便的,並且如果你使用不允許你指定返回介面指標的那種方法建立COM對象,這種方法也是不行的。在實際應用中, 你通常不需要明確的得到IUnkonwn的指標,因為所有的COM對象都是從IUnknown介面繼承或擴充得到的。
擴充一個介面類似於c++中類的繼承。子介面能夠暴露父介面的所有方法,並且自己也能添加一個或更多的自己的方法。事實上,你會經常看到用“繼承”代替“擴充”.你需要記住的是繼承是相對於對象內部而言的。你的應用程式不能夠繼承或擴充一個對象介面。但是可以使用子介面的指標來訪問任何子介面或父介面的方法。
你可以通過調用QueryInterface來得到任何已經存在的介面指標,因為所有的介面都是從IUnknown介面中繼承而來的。當你這樣做的時候,你必須為它提供你所請求的介面的IID和一個指標變數pp的地址,當這個函數返回的時候,指向介面的指標就會被儲存在pp變數中。例如:下面的程式碼片段,通過調用IDirectSound8::CreateSoundBuffer來建立一個主聲音緩衝對象。這個對象暴露了幾個介面。調用CreateSoundBuffer方法可以得到一個IDirectSoundBuffer8的介面。隨後的代碼通過使用IDirectSoundBuffer8介面調用QueryInterface方法來得到IDirectSound3DListener8介面。
IDirectSoundBuffer8 *pDSNPrimary = NULL ;
IDirectSound3DListener8 *pDSListerner ;
...
if( FAILED( hr = g_pDS->CreateSoundBuffer( &dsbd, &pDSBSPrimary, NULL )))
return hr ;
if( FAILED( hr = pDSBPrimary->QueryInsterface( IDD_IDirectSound3DListener8,
(LPVOID*)&pDSListener)))
return hr ;
注: 由於翻譯水平有限,錯誤在所難免。如發現翻譯的不對的地方還請路上的朋友指正,謝謝
可以任意轉載。
譯者: closeall
2005.09.04 譯