PHB_ITEM hb_oleAxControlNew( PHB_ITEM pItem, HWND hWnd ) { IUnknown * pUnk = NULL; IDispatch * pDisp = NULL; if( pItem ) hb_itemClear( pItem ); if( ! hb_oleAxInit() || ! s_pAtlAxGetControl ) { hb_oleSetError( S_OK ); hb_errRT_OLE( EG_UNSUPPORTED, 1010, 0, "ActiveX not initialized", HB_ERR_FUNCNAME ); } else { HRESULT lOleError = ( *s_pAtlAxGetControl )( hWnd, &pUnk ); if( lOleError == S_OK ) { lOleError = HB_VTBL( pUnk )->QueryInterface( HB_THIS_( pUnk ) HB_ID_REF( IID_IDispatch ), ( void ** ) ( void * ) &pDisp ); if( lOleError == S_OK ) pItem = hb_oleItemPut( pItem, pDisp ); HB_VTBL( pUnk )->Release( HB_THIS( pUnk ) ); } hb_oleSetError( lOleError ); if( lOleError != S_OK ) hb_errRT_OLE( EG_ARG, 1011, ( HB_ERRCODE ) lOleError, NULL, HB_ERR_FUNCNAME ); } return pItem; }
static void hb_sink_destruct( void * cargo ) { ISink * pSink = ( ISink * ) cargo; if( pSink->pConnectionPoint ) { IConnectionPoint * pConnectionPoint = pSink->pConnectionPoint; DWORD dwCookie = pSink->dwCookie; /* Unadvise() may activate pSink destructor so clear these * items as protection against recursive Unadvise call. */ pSink->pConnectionPoint = NULL; pSink->dwCookie = 0; HB_VTBL( pConnectionPoint )->Unadvise( HB_THIS_( pConnectionPoint ) dwCookie ); HB_VTBL( pConnectionPoint )->Release( HB_THIS( pConnectionPoint ) ); } }
static HRESULT STDMETHODCALLTYPE QueryInterface( IDispatch * lpThis, REFIID riid, void ** ppRet ) { if( IsEqualIID( riid, HB_ID_REF( IID_IUnknown ) ) || IsEqualIID( riid, HB_ID_REF( IID_IDispatch ) ) ) { *ppRet = ( void * ) lpThis; HB_VTBL( lpThis )->AddRef( HB_THIS( lpThis ) ); return S_OK; } *ppRet = NULL; return E_NOINTERFACE; }
static ULONG STDMETHODCALLTYPE Release( IDispatch * lpThis ) { ISink * pSink = ( ISink * ) lpThis; if( --pSink->count == 0 ) { if( pSink->pItemHandler ) { hb_itemRelease( pSink->pItemHandler ); pSink->pItemHandler = NULL; } if( pSink->pConnectionPoint ) { HB_VTBL( pSink->pConnectionPoint )->Unadvise( HB_THIS_( pSink->pConnectionPoint ) pSink->dwCookie ); HB_VTBL( pSink->pConnectionPoint )->Release( HB_THIS( pSink->pConnectionPoint ) ); pSink->pConnectionPoint = NULL; pSink->dwCookie = 0; } hb_xfree( pSink ); /* TODO: GlobalAlloc/Free GMEM_FIXED ??? */ return 0; } return pSink->count; }
static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * piid ) { ITypeInfo * iTI; ITypeInfo * iTISink; TYPEATTR * pTypeAttr; HREFTYPE hRefType; HRESULT hr; int iFlags, i; if( ! szEvent ) { IProvideClassInfo2 * iPCI2; IProvideClassInfo * iPCI; /* Method 1: using IProvideClassInfo2 */ hr = HB_VTBL( iDisp )->QueryInterface( HB_THIS_( iDisp ) HB_ID_REF( IID_IProvideClassInfo2 ), ( void ** ) ( void * ) &iPCI2 ); if( hr == S_OK ) { HB_TRACE( HB_TR_DEBUG, ( "_get_default_sink IProvideClassInfo2 OK" ) ); hr = HB_VTBL( iPCI2 )->GetGUID( HB_THIS_( iPCI2 ) GUIDKIND_DEFAULT_SOURCE_DISP_IID, piid ); HB_VTBL( iPCI2 )->Release( HB_THIS( iPCI2 ) ); if( hr == S_OK ) return S_OK; } else HB_TRACE( HB_TR_DEBUG, ( "_get_default_sink IProvideClassInfo2 obtain error %08lX", hr ) ); /* Method 2: using IProvideClassInfo and searching for default source in ITypeInfo */ hr = HB_VTBL( iDisp )->QueryInterface( HB_THIS_( iDisp ) HB_ID_REF( IID_IProvideClassInfo ), ( void ** ) ( void * ) &iPCI ); if( hr == S_OK ) { HB_TRACE( HB_TR_DEBUG, ( "_get_default_sink IProvideClassInfo OK" ) ); iTI = NULL; hr = HB_VTBL( iPCI )->GetClassInfo( HB_THIS_( iPCI ) & iTI ); if( hr == S_OK ) { pTypeAttr = NULL; hr = HB_VTBL( iTI )->GetTypeAttr( HB_THIS_( iTI ) & pTypeAttr ); if( hr == S_OK ) { for( i = 0; i < pTypeAttr->cImplTypes; i++ ) { hr = HB_VTBL( iTI )->GetImplTypeFlags( HB_THIS_( iTI ) i, &iFlags ); if( hr == S_OK && ( iFlags & IMPLTYPEFLAG_FDEFAULT ) && ( iFlags & IMPLTYPEFLAG_FSOURCE ) ) { if( HB_VTBL( iTI )->GetRefTypeOfImplType( HB_THIS_( iTI ) i, &hRefType ) == S_OK && HB_VTBL( iTI )->GetRefTypeInfo( HB_THIS_( iTI ) hRefType, &iTISink ) == S_OK ) { HB_TRACE( HB_TR_DEBUG, ( "_get_default_sink Method 2: default source is found" ) ); hr = HB_VTBL( iTISink )->GetTypeAttr( HB_THIS_( iTISink ) & pTypeAttr ); if( hr == S_OK ) { *piid = pTypeAttr->guid; HB_VTBL( iTISink )->ReleaseTypeAttr( HB_THIS_( iTISink ) pTypeAttr ); HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); HB_VTBL( iPCI )->Release( HB_THIS( iPCI ) ); return S_OK; } } } } HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); } } HB_VTBL( iPCI )->Release( HB_THIS( iPCI ) ); } else HB_TRACE( HB_TR_DEBUG, ( "_get_default_sink IProvideClassInfo obtain error %08lX", hr ) ); } /* Method 3: using CoClass */ hr = HB_VTBL( iDisp )->GetTypeInfo( HB_THIS_( iDisp ) 0, LOCALE_SYSTEM_DEFAULT, &iTI ); if( hr == S_OK ) { ITypeLib * iTL = NULL; TYPEATTR * pTypeAttr2; hr = HB_VTBL( iTI )->GetContainingTypeLib( HB_THIS_( iTI ) & iTL, NULL ); HB_VTBL( iTI )->Release( HB_THIS( iTI ) ); if( hr == S_OK ) { int iCount = HB_VTBL( iTL )->GetTypeInfoCount( HB_THIS( iTL ) ); for( i = 0; i < iCount; i++ ) { hr = HB_VTBL( iTL )->GetTypeInfo( HB_THIS_( iTL ) i, &iTI ); if( hr == S_OK ) { hr = HB_VTBL( iTI )->GetTypeAttr( HB_THIS_( iTI ) & pTypeAttr ); if( hr == S_OK ) { if( pTypeAttr->typekind == TKIND_COCLASS ) { int j; for( j = 0; j < pTypeAttr->cImplTypes; j++ ) { if( szEvent ) { if( HB_VTBL( iTI )->GetRefTypeOfImplType( HB_THIS_( iTI ) j, &hRefType ) == S_OK && HB_VTBL( iTI )->GetRefTypeInfo( HB_THIS_( iTI ) hRefType, &iTISink ) == S_OK ) { BSTR bstr; hr = HB_VTBL( iTISink )->GetDocumentation( HB_THIS_( iTISink ) - 1, &bstr, NULL, NULL, NULL ); if( hr == S_OK ) { char str[ 256 ]; int iLen; iLen = WideCharToMultiByte( CP_ACP, 0, bstr, -1, str, sizeof( str ), NULL, NULL ); if( iLen > 0 ) { str[ iLen - 1 ] = '\0'; if( ! strcmp( szEvent, str ) ) { hr = HB_VTBL( iTISink )->GetTypeAttr( HB_THIS_( iTISink ) & pTypeAttr2 ); if( hr == S_OK ) { *piid = pTypeAttr2->guid; HB_VTBL( iTISink )->ReleaseTypeAttr( HB_THIS_( iTISink ) pTypeAttr2 ); HB_VTBL( iTISink )->Release( HB_THIS( iTISink ) ); HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); HB_VTBL( iTI )->Release( HB_THIS( iTI ) ); HB_VTBL( iTL )->Release( HB_THIS( iTL ) ); return S_OK; } } } } HB_VTBL( iTISink )->Release( HB_THIS( iTISink ) ); } } else /* szEvent == NULL */ { hr = HB_VTBL( iTI )->GetImplTypeFlags( HB_THIS_( iTI ) j, &iFlags ); if( hr == S_OK && ( iFlags & IMPLTYPEFLAG_FDEFAULT ) && ( iFlags & IMPLTYPEFLAG_FSOURCE ) ) { if( HB_VTBL( iTI )->GetRefTypeOfImplType( HB_THIS_( iTI ) j, &hRefType ) == S_OK && HB_VTBL( iTI )->GetRefTypeInfo( HB_THIS_( iTI ) hRefType, &iTISink ) == S_OK ) { hr = HB_VTBL( iTISink )->GetTypeAttr( HB_THIS_( iTISink ) & pTypeAttr2 ); if( hr == S_OK ) { #if 0 /* Debug code. You can also comment out iFlags condition, to list more interfaces [Mindaugas] */ BSTR bstr; char str[ 256 ]; int iLen; HB_VTBL( iTISink )->GetDocumentation( HB_THIS_( iTISink ) - 1, &bstr, NULL, NULL, NULL ); iLen = WideCharToMultiByte( CP_ACP, 0, bstr, -1, str, sizeof( str ), NULL, NULL ); str[ iLen - 1 ] = '\0'; HB_TRACE( HB_TR_DEBUG, ( "_get_default_sink Method 3: iFlags=%d guid=%s class=%s", iFlags, GUID2String( &( pTypeAttr2->guid ) ), str ) ); #endif *piid = pTypeAttr2->guid; HB_VTBL( iTISink )->ReleaseTypeAttr( HB_THIS_( iTISink ) pTypeAttr2 ); HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); HB_VTBL( iTI )->Release( HB_THIS( iTI ) ); HB_VTBL( iTL )->Release( HB_THIS( iTL ) ); return S_OK; } } } } } } HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); } HB_VTBL( iTI )->Release( HB_THIS( iTI ) ); } } HB_VTBL( iTL )->Release( HB_THIS( iTL ) ); } } return E_NOINTERFACE; }