2011-03-07 18 views
2

我正在查看MSDN文檔,說我可以CoCreateInstance a SENS object using its CLSID。但是,不清楚__uuidof(SENS)是否意味着什麼 - 因爲它只是Sensevts.h文件中的前向聲明。此外,SENS類只提供「傳出」接口,並被標記爲「不可創建」(通過MS Com Viewer查看),這使我不知道如何引用SENS對象本身的實例。如何爲SENS事件註冊接收對象

這與示例代碼用於獲取一個instance of IShellLink

HRESULT  hr; 
IShellLink* pISL; 

hr = CoCreateInstance (CLSID_ShellLink,   // CLSID of coclass 
        NULL,     // not used - aggregation 
        CLSCTX_INPROC_SERVER, // type of server 
        IID_IShellLink,   // IID of interface 
        (void**) &pISL);  // Pointer to our interface pointer 

這裏ShellLink被稱爲 「的IShellLink」。很公平。但是,我應該用什麼類型(除void *之外)來接收SENS的實例?除了CLSID問題,我想用於SENS的IID是什麼?最終,我想使用SENS的IID_ISensLogon接口,但因爲它是一個傳出接口,所以我無法想象在這裏使用它是有意義的。據推測,我需要與SENS的IConnectionPointContainer接口進行交談(確實它實現了這一點,對吧?),以便我可以進入ISensLogon。

總之,有人可以告訴我樣本代碼的樣子是什麼樣的,以便我可以調用「Advise()」並開始從SENS接收事件?

UPDATE我取得一些進展,讓我的代碼現在看起來像這樣:

#import <es.dll> 
#include <EventSys.h> 
using namespace EventSystemLib; 

//... 
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 
do { 

    IEventSystemPtr evSystem; 
    HRESULT hr = evSystem.CreateInstance(CLSID_CEventSystem); 
    if (!SUCCEEDED(hr)){ 
     break; 
    } 

    IEventSubscriptionPtr evSubscriber; 
    hr = evSystem.CreateInstance(CLSID_CEventSubscription); 
    if (!SUCCEEDED(hr)){ 
     break; 
    } 

}while (false); 

的問題是,CLSID_CEventSubscription的創建失敗HRESULT代碼E_NOINTERFACEOnline docs for that error建議我使用錯誤的線程模型。但我已經嘗試了COINIT_MULTITHREADEDCOINIT_APARTMENTTHREADED,但都沒有更改錯誤。有什麼想法嗎?

順便說一句,我見過的最接近的實例是given in this link

+0

你提到COINIT_APARTMENTTHREADED兩次,所以我不知道你的」實際上已經嘗試過對於它的價值,SensNetDemo使用COINIT_MULTITHREADED。 – Jon 2011-03-08 16:37:05

+0

@Jon:你是對的。我編輯了這篇文章。我確實嘗試過'COINIT_MULTITHREADED' – 2011-03-08 18:50:24

+0

爲我的答案添加了一些代碼以解決您的新問題。 – Jon 2011-03-08 19:13:26

回答

2

根據MSDN的其他部分,您不需要創建SENS對象。如果我正在閱讀此權限,則創建一個IEventSystem實例(CLSID_CEventSystem),查詢感興趣的SENS發佈者/事件類,並向他們註冊您的訂閱。

編輯: 爲了您的新的問題,我不能確定的根本原因,但是我發現,使用IEventSubscriptionPtr切換遠似乎工作:

// Works 
    CComPtr<::IEventSubscription> pSub2; 
    hr = pSub2.CoCreateInstance(CLSID_CEventSubscription); 

    // Doesn't work 
    IEventSubscriptionPtr evSubscriber; 
    hr = evSystem.CreateInstance(CLSID_CEventSubscription); 
+0

我嘗試了你的建議,並且它工作正常。作爲答案 - 即使它在技術上是「答案的前兆」 - 因爲我會支持這一努力,我一直在追求它,以支持Windows 2000的功能,並且現在對該產品的Windows 2000支持已經停止我正在嘗試。 – 2011-03-09 01:07:06

2

不可創建的對象不是爲調用者創建實例而設計的。通常這是因爲對象本身沒有意義。想象一下,例如,Excel電子表格的單元子對象。呼叫者無法在電子表格之外執行任何操作,因此不能在電話簿中使用CoCreateInstance。但是,調用者可以向電子表格詢問指向單元對象的指針。

我相信SENS是一樣的。 (非常差)文檔說明了通過事件系統對象CLSID_CEventSystem來訂閱事件。這是你需要開始尋找的地方。

+1

如果對'CoCreateInstance'沒有意義的SENS對象,那麼文檔比窮人差,它是錯誤的。它確實給出了'CoCreateInstance'作爲到達SENS對象的唯一選項。 :( – 2011-03-07 17:18:13

+0

是的,我注意到了,非常混亂,尤其是因爲他們不會談論CoCreateInstance,因爲這些對象是可創建的。 – thehouse 2011-03-07 21:54:45

2

很抱歉,這是一個答案,可以尚未發表評論。

你在你的代碼錯誤,這就是爲什麼你得到E_NOINTERFACE

// Doesn't work 
IEventSubscriptionPtr evSubscriber; 
hr = evSystem.CreateInstance(CLSID_CEventSubscription); 

應該是:

IEventSubscriptionPtr evSubscriber; 
hr = evSubscriber.CreateInstance(CLSID_CEventSubscription); //Wrong object previously