2008-09-14 23 views
8

のVBScriptのユーザーにイベントハンドラを公開します(特に2007 BCB)++もしそうなら、どのように私はCで私のタイプライブラリでこれを公開しない、は、私は、ユーザーがのようなコールを経由してアクセスすることができますCOMオブジェクトがあると、私のCOMオブジェクト

Function ServerEvent 

    MsgBox "Event handled" 

End Function 

s.OnDoSomething = ServerEvent 

はこれが可能であると:ユーザーがそうのように、オブジェクトのイベントハンドラを指定するには?

答えて

1

私は詳細にはほとんどかすんだけど、多分、下のリンクを助けるかもしれない:

http://msdn.microsoft.com/en-us/library/ms974564.aspx

サーバーオブジェクトがIProvideClassInfoを実装し、その後、あなたのVBScriptコードでConnectObjectを呼び出す必要があるように見えます。参照してください:私は最近、それをどうやったのか

http://blogs.msdn.com/ericlippert/archive/2005/02/15/373330.aspx

5

これがあります。 IDispatchを実装インターフェイスとあなたのIDLにそのインターフェイスのコクラスを追加します。

[ 
    object, 
    uuid(6EDA5438-0915-4183-841D-D3F0AEDFA466), 
    nonextensible, 
    oleautomation, 
    pointer_default(unique) 
] 
interface IServerEvents : IDispatch 
{ 
    [id(1)] 
    HRESULT OnServerEvent(); 
} 

//... 

[ 
    uuid(FA8F24B3-1751-4D44-8258-D649B6529494), 
] 
coclass ServerEvents 
{ 
    [default] interface IServerEvents; 
    [default, source] dispinterface IServerEvents; 
}; 

これはCServerEventsクラスの宣言です:

class ATL_NO_VTABLE CServerEvents : 
    public CComObjectRootEx<CComSingleThreadModel>, 
    public CComCoClass<CServerEvents, &CLSID_ServerEvents>, 
    public IDispatchImpl<IServerEvents, &IID_IServerEvents , &LIBID_YourLibrary, -1, -1>, 
    public IConnectionPointContainerImpl<CServerEvents>, 
    public IConnectionPointImpl<CServerEvents,&__uuidof(IServerEvents)> 
{ 
public: 
    CServerEvents() 
    { 
    } 

    // ... 

BEGIN_COM_MAP(CServerEvents) 
    COM_INTERFACE_ENTRY(IServerEvents) 
    COM_INTERFACE_ENTRY(IDispatch) 
    COM_INTERFACE_ENTRY(IConnectionPointContainer) 
END_COM_MAP() 

BEGIN_CONNECTION_POINT_MAP(CServerEvents) 
    CONNECTION_POINT_ENTRY(__uuidof(IServerEvents)) 
END_CONNECTION_POINT_MAP() 

    // .. 

    // IServerEvents 
    STDMETHOD(OnServerEvent)(); 

private: 
    CRITICAL_SECTION m_csLock;   
}; 

ここで重要なのは、IConnectionPointImplとIConnectionPointContainerImplの実装ですインターフェイスと接続ポイントマップを表示します。 OnServerEventメソッドの定義は次のようになります。あなたはあなたのクライアントはあなたのイベントのために彼らのハンドラを指定する方法を提供する必要が

STDMETHODIMP CServerEvents::OnServerEvent() 
{ 
    ::EnterCriticalSection(&m_csLock); 

    IUnknown* pUnknown; 

    for (unsigned i = 0; (pUnknown = m_vec.GetAt(i)) != NULL; ++i) 
    {  
     CComPtr<IDispatch> spDisp; 
     pUnknown->QueryInterface(&spDisp); 

     if (spDisp) 
     { 
      spDisp.Invoke0(CComBSTR(L"OnServerEvent")); 
     } 
    } 

    ::LeaveCriticalSection(&m_csLock); 

    return S_OK; 
} 

。これは "SetHandler"などの専用メソッドで行うことができますが、ハンドラを非同期に呼び出されるメソッドの引数にすることをお勧めします。その後、

STDMETHOD(DoSomethingAsynchronous)(IServerEvents *pCallback); 

ストアIServerEventsへのポインタ、そしてあなたがあなたのイベントを起動したい場合は、単にメソッドを呼び出します:については

m_pCallback->OnServerEvent(); 

この方法では、ユーザーが1つの方法だけを呼び出す必要がありますVBコードでは、イベントを処理するための構文は、あなたが示唆したものと少し異なります。

これは役に立ちます。

+1

提供したコードはVBの構文であり、VBScriptではありません。 "As"キーワードと "WithEvents"はVBScriptでは使用できません。 –

+0

@ 1800 INFORMATION、 そうです。私はVBとVBScriptの両方を使用していますが、VBScriptを使って何もしていないので、長い時間がかかりました。私はその特定の違いを忘れてしまった、あるいは認識していなかった。 –

+0

@JeffHillman、提供されるソリューションはC++用です。今私は同様の要件を持っていますが、C#経由で開発されたActiveX COM(そのためのソースコードがあります)です。 C#/ Netの世界に似たアプローチがあることはご存じですか? – user908645

2

私は、hereと記載された技術に従ってしまった。

+0

これはおそらくロットの最高の答えです –

関連する問題