Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, Esperar, Вы писали:
OE>>>Как в ATL клиенте подписываться на события надо объяснять?
E>>ДА!
OE>Ok, например в клиенте есть диалог, в котором нужно ловить события от COM-сервера:
если нет в клиенте диалога, если клиент — это плагин, то где там ловить события?
OE>OE>class CMainDlg : public CAxDialogImpl<CMainDlg>
OE> , public CDialogResize<CMainDlg>
OE>{
OE>
OE>добавляем туда следующие вещи (см. выделенное):
OE>OE>#import "MyCOM.dll" no_namespace, named_guids
OE>// произвольное число, удобно когда подключение идет к событиям сразу нескольких компонент
OE>#define IMYINTRFID 1
OE>class CMainDlg : public CAxDialogImpl<CMainDlg>
OE> , public CDialogResize<CMainDlg>
OE> , public IDispEventImpl<IMYINTRFID, CMainDlg, &DIID___IMyIntrfEvent, &LIBID_MYCOMLib, 1, 0>
OE>{
OE> IMyIntrfPtr pMyIntrfPtr;
OE> // номер метода-события (0x1) смотрим в idl сервера или в
OE> // mycom.tli, который создаст #import
OE> BEGIN_SINK_MAP( CMainDlg )
OE> SINK_ENTRY_EX( IMYINTRFID, DIID___IMyIntrfEvent, 0x1, OnFirstMethod )
OE> END_SINK_MAP()
OE> // этот метод будет вызван при возникновении события
OE> HRESULT __stdcall OnFirstMethod( BSTR str )
OE> {
OE> // получили строку str
OE> return S_OK;
OE> }
OE>
OE> // функция для подписки на события, вызывается где удобно, например
OE> // в OnInitDialog() после загрузки pMyIntrfPtr
OE> BOOL Advise2MyCOMEvent()
OE> {
OE> _ASSERTE( pMyIntrfPtr != NULL );
OE> if ( pMyIntrfPtr )
OE> {
OE> HRESULT hr = _IDispEventLocator<IMYINTRFID, &DIID___IMyIntrfEvent>::DispEventAdvise( pMyIntrfPtr, &DIID___IMyIntrfEvent );
OE> if ( FAILED( hr ) )
OE> {
OE> // ошибка, код в hr
OE> return FALSE;
OE> }
OE> else
OE> return TRUE;
OE> }
OE> else
OE> {
OE> // ошибка - компонент не загружен, подписка невозможна
OE> return FALSE;
OE> }
OE> }
OE>
OE> // функция для отписки от событий, вызывается где удобно,
OE> // например в OnDestroy()
OE> BOOL UnAdvise2MyCOMEvent()
OE> {
OE> if ( pMyIntrfPtr )
OE> {
OE> HRESULT hr = _IDispEventLocator<IMYINTRFID, &DIID___IMyIntrfEvent>::DispEventUnadvise( pMyIntrfPtr, &DIID___IMyIntrfEvent );
OE> if ( FAILED( hr ) )
OE> {
OE> // ошибка, код в hr
OE> return FALSE;
OE> }
OE> else
OE> return TRUE;
OE> }
OE> else
OE> return FALSE;
OE> }
OE>
OE> LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
OE> {
OE> ...
OE> HRESULT hr = pMyIntrfPtr.CreateInstance( "MyCom.MyIntrf" );
OE> if ( SUCCEEDED( hr ) )
OE> {
OE> Advise2MyCOMEvent();
OE> }
OE> else
OE> {
OE> // ошибка
OE> }
OE> ...
OE> }
OE> LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
OE> {
OE> ...
OE> UnAdvise2MyCOMEvent();
OE> pMyIntrfPtr = NULL;
OE> ...
OE> }
OE>};
OE>