COM (Component Object Model,元件物件模型)是Microsoft建立的一種二進位和網路標準,也是Microsoft大力推廣並已取得廣泛認可的一種組件標準。在COM標準中,COM對象被很好的封裝起來,客戶無法訪問對象的實現細節,提供給使用者的唯一的訪問途徑是通過COM介面來訪問。對於COM介面有兩方面的含義:首先它是一組可供調用的函數,由此客戶可以讓該對象做某些事情;其次,也是更為重要的,介面是組件及其客戶程式之間的協議。也就是說介面不但定義了可用什麼函數,也定義了當調用這些函數時對象要做什麼。Windows作業系統本身作為一個大的COM組件對象,也提供了一些必要的COM介面給客戶程式,因此我們可以通過這些COM介面來直接對Windows外殼進行編程。
在程式進行正式編寫設計之前有一點是肯定的:程式裡需要用到COM介面,要對COM對象進行操作。因此首先要加入初始化COM和終止COM的代碼。一般是在應用程式類的InitInstance()函數的開始處和返回前添加初始化COM和終止COM代碼的:
…… CoInitialize(NULL); //初始化COM …… CoUninitialize(); //終止COM代碼 …… |
以上兩個函數在MFC程式和非MFC程式中都可以很好的使用。另外,如果程式架構是以MFC為基礎的,那麼只需簡單的調用AfxOleInit()函數就可以達到同樣的目的。而且不必顯式調用終止COM的代碼。在COM標準中,訪問COM對象的唯一途徑是COM介面,因此在編寫操縱Windows 系統外殼程式首先要得到其提供的COM介面。所用的COM介面是IShellDispatch,它是從IDispatch介面派生來的,在VC安裝目錄的VC98/Include/Exdisp.h標頭檔中有定義,下面節選了一些將要用到的介面定義:
…… EXTERN_C const IID IID_IShellDispatch; #if defined(__cplusplus) && !defined(CINTERFACE) interface DECLSPEC_UUID("D8F015C0-C278-11CE-A49E-444553540000") IShellDispatch : public IDispatch { public: …… virtual HRESULT STDMETHODCALLTYPE MinimizeAll( void) = 0; virtual HRESULT STDMETHODCALLTYPE UndoMinimizeALL( void) = 0; virtual HRESULT STDMETHODCALLTYPE FileRun( void) = 0; virtual HRESULT STDMETHODCALLTYPE CascadeWindows( void) = 0; virtual HRESULT STDMETHODCALLTYPE TileVertically( void) = 0; virtual HRESULT STDMETHODCALLTYPE TileHorizontally( void) = 0; virtual HRESULT STDMETHODCALLTYPE ShutdownWindows( void) = 0; virtual HRESULT STDMETHODCALLTYPE Suspend( void) = 0; virtual HRESULT STDMETHODCALLTYPE SetTime( void) = 0; virtual HRESULT STDMETHODCALLTYPE TrayProperties( void) = 0; virtual HRESULT STDMETHODCALLTYPE Help( void) = 0; virtual HRESULT STDMETHODCALLTYPE FindFiles( void) = 0; virtual HRESULT STDMETHODCALLTYPE FindComputer( void) = 0; }; …… |
該介面在CoCreateInstance()函數建立COM對象時將會得到指向其的指標,通過這個函數客戶程式可以避免顯式同類廠打交道,其實該函數內部也調用了CoGetClassObject()函數來擷取COM對象的類廠,只不過它把通過類廠建立對象的過程封裝起來了,只需使用者指定對象類的CLSID和待輸出的介面指標及介面ID,顯然這樣直接建立COM對象是非常便捷的,在擷取到COM對象指標之後就可以通過這個指標去訪問調用COM對象裡的方法來實現Windows 外殼的種種功能調用了,下面是實現該功能的部分關鍵代碼:
…… HRESULT sc;//返回結果 IShellDispatch *pShellDisp = NULL; //初始化介面指標 //直接建立COM對象 sc = CoCreateInstance( CLSID_Shell,//指定待建立的COM物件識別碼 NULL, //指定被彙總時的外部對象的介面指標 CLSCTX_SERVER, //指定組件類別,可以指定進程內組件進程外組件或者進程內控制對象。 IID_IDispatch, //指定介面ID,需要注意的是這裡指的是待 //建立的COM對象的介面ID,而非類廠對象的介面標識符 (LPVOID *) &pShellDisp );//存放函數返回的對象的介面指標/* 在上述代碼中,CoCreateInstance首先調用CoGetClassObject函數建立類廠對象,然後用得到的類廠對象的介面指標建立真正的COM對象,最後把類廠對象釋放並返回,這樣就很好的把類廠屏蔽起來,使使用者用起來更為簡單。*/ if( FAILED(sc) )//必須用FAILED 或SUCCECCED來判斷COM對象是否建立成功 return; pShellDisp->FindFiles(); //調用COM對象裡的方法 pShellDisp->Release(); //釋放申請到的介面指標 …… |
在這裡通過pShellDisp介面指標調用了COM對象的FindFiles()方法去進行尋找檔案的系統外殼操作。同樣,可以根據實際需要靈活調用響應的方法來執行相應的外殼操作,主要有以下幾個方法:
MinimizeAll 所有視窗最小化
UndoMinimizeALL 恢複視窗最小化
FileRun 開始菜單的"運行…"
CascadeWindows 層疊視窗
TileVertically 垂直平鋪
TileHorizontally 水平平鋪
ShutdownWindows 關閉Windows
Suspend 掛起電腦
SetTime 設定時間
TrayProperties 工作列屬性
Help Windows協助
FindFiles 尋找檔案
FindComputer 尋找電腦
……
這些介面均在VC安裝目錄的VC98/Include/Exdisp.h標頭檔中有定義,可以通過對該檔案的查看來編寫響應的外殼作業碼。