diff --git a/harbour/ChangeLog b/harbour/ChangeLog index ab6bb7de44..81dfad626d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,17 @@ The license applies to all entries newer than 2009-04-28. */ +2010-10-14 16:45 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) + * harbour/contrib/hbwin/axcore.c + ! fixed CPP compilation by using compiler macros in method calls + * harbour/contrib/hbwin/hbwinole.h + * harbour/contrib/hbwin/axcore.c + * harbour/contrib/hbwin/olecore.c + + implemented additional OLE destructors. Added Undavise() call + to :__hSink destructor. This fixes unresponsive OLE server app + behaviour after corresponding Harbour object is freed + ; Code proposed by Przemek, some fixes applied + 2010-10-14 08:45 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/rtl/gtstd/gtstd.c * updated to compile with WinCE @@ -46,7 +57,7 @@ value for cIID. To force the previous behaviour, you should use __AxRegisterHandler(,, "{00020420-0000-0000-C000-000000000046}"), but I guess this should never be required. - ; Don't ask me how I've wrote this code :) + ; Don't ask me how I've written this code :) * harbour/contrib/hbwin/tests/pdfcreat.prg * changed to sync with new __AxRegisterHandler() behaviour * harbour/contrib/hbwin/tests/testole.prg diff --git a/harbour/contrib/hbwin/axcore.c b/harbour/contrib/hbwin/axcore.c index 582d3b4e81..90b87b909e 100644 --- a/harbour/contrib/hbwin/axcore.c +++ b/harbour/contrib/hbwin/axcore.c @@ -407,12 +407,12 @@ static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * /* Method 1: using IProvideClassInfo2 */ - hr = iDisp->lpVtbl->QueryInterface( iDisp, &IID_IProvideClassInfo2, ( void** ) ( void* ) &iPCI2 ); + hr = HB_VTBL( iDisp )->QueryInterface( HB_THIS_( iDisp ) HB_ID_REF( IID_IProvideClassInfo2 ), ( void** ) ( void* ) &iPCI2 ); if( hr == 0 ) { HB_TRACE( HB_TR_DEBUG, ("_get_default_sink IProvideClassInfo2 OK") ); - hr = iPCI2->lpVtbl->GetGUID( iPCI2, GUIDKIND_DEFAULT_SOURCE_DISP_IID, piid ); - iPCI2->lpVtbl->Release( iPCI2 ); + hr = HB_VTBL( iPCI2 )->GetGUID( HB_THIS_( iPCI2 ) GUIDKIND_DEFAULT_SOURCE_DISP_IID, piid ); + HB_VTBL( iPCI2 )->Release( HB_THIS( iPCI2 ) ); if( hr == 0 ) return 0; @@ -425,44 +425,44 @@ static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * /* Method 2: using IProvideClassInfo and searching for default source in ITypeInfo */ - hr = iDisp->lpVtbl->QueryInterface( iDisp, &IID_IProvideClassInfo, ( void** ) ( void* ) &iPCI ); + hr = HB_VTBL( iDisp )->QueryInterface( HB_THIS_( iDisp ) HB_ID_REF( IID_IProvideClassInfo ), ( void** ) ( void* ) &iPCI ); if( hr == 0 ) { HB_TRACE( HB_TR_DEBUG, ("_get_default_sink IProvideClassInfo OK") ); - hr = iPCI->lpVtbl->GetClassInfo( iPCI, &iTI ); + hr = HB_VTBL( iPCI )->GetClassInfo( HB_THIS_( iPCI ) &iTI ); if( hr == 0 ) { - hr = iTI->lpVtbl->GetTypeAttr( iTI, &pTypeAttr ); + hr = HB_VTBL( iTI )->GetTypeAttr( HB_THIS_( iTI ) &pTypeAttr ); if( hr == 0 ) { for( i = 0; i < pTypeAttr->cImplTypes; i++ ) { - hr = iTI->lpVtbl->GetImplTypeFlags( iTI, i, &iFlags ); + hr = HB_VTBL( iTI )->GetImplTypeFlags( HB_THIS_( iTI ) i, &iFlags ); if( hr == 0 && ( iFlags & IMPLTYPEFLAG_FDEFAULT ) && ( iFlags & IMPLTYPEFLAG_FSOURCE ) ) { - if( iTI->lpVtbl->GetRefTypeOfImplType( iTI, i, &hRefType ) == S_OK && - iTI->lpVtbl->GetRefTypeInfo( iTI, hRefType, &iTISink ) == S_OK ) + 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 = iTISink->lpVtbl->GetTypeAttr( iTISink, &pTypeAttr ); + hr = HB_VTBL( iTISink )->GetTypeAttr( HB_THIS_( iTISink ) &pTypeAttr ); if( hr == 0 ) { * piid = pTypeAttr->guid; - iTISink->lpVtbl->ReleaseTypeAttr( iTISink, pTypeAttr ); + HB_VTBL( iTISink )->ReleaseTypeAttr( HB_THIS_( iTISink ) pTypeAttr ); - iTI->lpVtbl->ReleaseTypeAttr( iTI, pTypeAttr ); - iPCI->lpVtbl->Release( iPCI ); + HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); + HB_VTBL( iPCI )->Release( HB_THIS( iPCI ) ); return 0; } } } } - iTI->lpVtbl->ReleaseTypeAttr( iTI, pTypeAttr ); + HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); } } - iPCI->lpVtbl->Release( iPCI ); + HB_VTBL( iPCI )->Release( HB_THIS( iPCI ) ); } else { @@ -473,24 +473,24 @@ static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * /* Method 3: using CoClass */ - hr = iDisp->lpVtbl->GetTypeInfo( iDisp, 0, LOCALE_SYSTEM_DEFAULT, &iTI ); + hr = HB_VTBL( iDisp )->GetTypeInfo( HB_THIS_( iDisp ) 0, LOCALE_SYSTEM_DEFAULT, &iTI ); if( hr == 0 ) { ITypeLib * iTL; TYPEATTR * pTypeAttr2; - hr = iTI->lpVtbl->GetContainingTypeLib( iTI, &iTL, NULL ); - iTI->lpVtbl->Release( iTI ); + hr = HB_VTBL( iTI )->GetContainingTypeLib( HB_THIS_( iTI ) &iTL, NULL ); + HB_VTBL( iTI )->Release( HB_THIS( iTI ) ); if( hr == 0 ) { - int iCount = iTL->lpVtbl->GetTypeInfoCount( iTL ); + int iCount = HB_VTBL( iTL )->GetTypeInfoCount( HB_THIS( iTL ) ); for( i = 0; i < iCount; i++ ) { - hr = iTL->lpVtbl->GetTypeInfo( iTL, i, &iTI ); + hr = HB_VTBL( iTL )->GetTypeInfo( HB_THIS_( iTL ) i, &iTI ); if( hr == S_OK ) { - hr = iTI->lpVtbl->GetTypeAttr( iTI, &pTypeAttr ); + hr = HB_VTBL( iTI )->GetTypeAttr( HB_THIS_( iTI ) &pTypeAttr ); if( hr == S_OK ) { if( pTypeAttr->typekind == TKIND_COCLASS ) @@ -499,12 +499,12 @@ static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * { if( szEvent ) { - if( iTI->lpVtbl->GetRefTypeOfImplType( iTI, j, &hRefType ) == S_OK && - iTI->lpVtbl->GetRefTypeInfo( iTI, hRefType, &iTISink ) == S_OK ) + 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 = iTISink->lpVtbl->GetDocumentation( iTISink, -1, &bstr, NULL, NULL, NULL ); + hr = HB_VTBL( iTISink )->GetDocumentation( HB_THIS_( iTISink ) -1, &bstr, NULL, NULL, NULL ); if( hr == S_OK ) { char str[ 256 ]; @@ -514,33 +514,33 @@ static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * str[ iLen - 1 ] = '\0'; if( ! strcmp( szEvent, str ) ) { - hr = iTISink->lpVtbl->GetTypeAttr( iTISink, &pTypeAttr2 ); + hr = HB_VTBL( iTISink )->GetTypeAttr( HB_THIS_( iTISink ) &pTypeAttr2 ); if( hr == S_OK ) { * piid = pTypeAttr2->guid; - iTISink->lpVtbl->ReleaseTypeAttr( iTISink, pTypeAttr2 ); + HB_VTBL( iTISink )->ReleaseTypeAttr( HB_THIS_( iTISink ) pTypeAttr2 ); - iTISink->lpVtbl->Release( iTISink ); - iTI->lpVtbl->ReleaseTypeAttr( iTI, pTypeAttr ); - iTI->lpVtbl->Release( iTI ); - iTL->lpVtbl->Release( iTL ); + 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 0; } } } - iTISink->lpVtbl->Release( iTISink ); + HB_VTBL( iTISink )->Release( HB_THIS( iTISink ) ); } } else /* szEvent == NULL */ { - hr = iTI->lpVtbl->GetImplTypeFlags( iTI, j, &iFlags ); + hr = HB_VTBL( iTI )->GetImplTypeFlags( HB_THIS_( iTI ) j, &iFlags ); if( hr == S_OK && ( iFlags & IMPLTYPEFLAG_FDEFAULT ) && ( iFlags & IMPLTYPEFLAG_FSOURCE ) ) { - if( iTI->lpVtbl->GetRefTypeOfImplType( iTI, j, &hRefType ) == S_OK && - iTI->lpVtbl->GetRefTypeInfo( iTI, hRefType, &iTISink ) == S_OK ) + if( HB_VTBL( iTI )->GetRefTypeOfImplType( HB_THIS_( iTI ) j, &hRefType ) == S_OK && + HB_VTBL( iTI )->GetRefTypeInfo( HB_THIS_( iTI ) hRefType, &iTISink ) == S_OK ) { - hr = iTISink->lpVtbl->GetTypeAttr( iTISink, &pTypeAttr2 ); + hr = HB_VTBL( iTISink )->GetTypeAttr( HB_THIS_( iTISink ) &pTypeAttr2 ); if( hr == S_OK ) { #if 0 @@ -549,17 +549,17 @@ static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * char str[ 256 ]; int iLen; - iTISink->lpVtbl->GetDocumentation( iTISink, -1, &bstr, NULL, NULL, NULL ); + 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; - iTISink->lpVtbl->ReleaseTypeAttr( iTISink, pTypeAttr2 ); + HB_VTBL( iTISink )->ReleaseTypeAttr( HB_THIS_( iTISink ) pTypeAttr2 ); - iTI->lpVtbl->ReleaseTypeAttr( iTI, pTypeAttr ); - iTI->lpVtbl->Release( iTI ); - iTL->lpVtbl->Release( iTL ); + HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); + HB_VTBL( iTI )->Release( HB_THIS( iTI ) ); + HB_VTBL( iTL )->Release( HB_THIS( iTL ) ); return 0; } } @@ -567,18 +567,39 @@ static HRESULT _get_default_sink( IDispatch * iDisp, const char * szEvent, IID * } } } - iTI->lpVtbl->ReleaseTypeAttr( iTI, pTypeAttr ); + HB_VTBL( iTI )->ReleaseTypeAttr( HB_THIS_( iTI ) pTypeAttr ); } - iTI->lpVtbl->Release( iTI ); + HB_VTBL( iTI )->Release( HB_THIS( iTI ) ); } } - iTL->lpVtbl->Release( iTL ); + HB_VTBL( iTL )->Release( HB_THIS( iTL ) ); } } return E_NOINTERFACE; } +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 ) ); + } +} + + HB_FUNC( __AXREGISTERHANDLER ) /* ( pDisp, bHandler [, cIID] ) --> pSink */ { IDispatch * pDisp = hb_oleParam( 1 ); @@ -619,6 +640,7 @@ HB_FUNC( __AXREGISTERHANDLER ) /* ( pDisp, bHandler [, cIID] ) --> pSink */ if( lOleError == S_OK ) { + PHB_ITEM pOleItem; DWORD dwCookie = 0; ISink * pSink; @@ -635,7 +657,11 @@ HB_FUNC( __AXREGISTERHANDLER ) /* ( pDisp, bHandler [, cIID] ) --> pSink */ pSink->pConnectionPoint = pCP; pSink->dwCookie = dwCookie; - hb_oleItemPut( hb_stackReturnItem(), ( IDispatch* ) pDisp ); + pOleItem = hb_oleItemPut( hb_stackReturnItem(), ( IDispatch* ) pDisp ); + /* bind call back handler item with returned object */ + hb_oleItemSetCallBack( pOleItem, &pSink->pItemHandler ); + /* add additional destructor */ + hb_oleItemSetDestructor( pOleItem, hb_sink_destruct, ( void * ) pSink ); } HB_VTBL( pCPC )->Release( HB_THIS( pCPC ) ); } diff --git a/harbour/contrib/hbwin/hbwinole.h b/harbour/contrib/hbwin/hbwinole.h index c4b5295638..218c872385 100644 --- a/harbour/contrib/hbwin/hbwinole.h +++ b/harbour/contrib/hbwin/hbwinole.h @@ -142,6 +142,7 @@ HB_EXTERN_BEGIN typedef HB_BOOL ( * HB_OLEOBJ_FUNC )( VARIANT*, PHB_ITEM ); +typedef void ( * HB_OLE_DESTRUCTOR_FUNC )( void * ); extern HB_EXPORT HB_BOOL hb_oleInit( void ); extern HB_EXPORT HRESULT hb_oleGetError( void ); @@ -161,6 +162,7 @@ extern HB_EXPORT void hb_oleItemSetCallBack( PHB_ITEM pItem, PHB_ITEM * pC extern HB_EXPORT HB_BOOL hb_oleDispInvoke( PHB_SYMB pSym, PHB_ITEM pObject, PHB_ITEM pParam, DISPPARAMS * pParams, VARIANT* pVarResult, HB_OLEOBJ_FUNC pObjFunc, HB_USHORT uiClass ); +extern HB_EXPORT void hb_oleItemSetDestructor( PHB_ITEM pItem, HB_OLE_DESTRUCTOR_FUNC pFunc, void * cargo ); /* activex control */ extern HB_EXPORT HB_BOOL hb_oleAxInit( void ); diff --git a/harbour/contrib/hbwin/olecore.c b/harbour/contrib/hbwin/olecore.c index 8e10661a07..e33ad0ccc4 100644 --- a/harbour/contrib/hbwin/olecore.c +++ b/harbour/contrib/hbwin/olecore.c @@ -82,6 +82,8 @@ typedef struct { IDispatch* pDisp; PHB_ITEM* pCallBack; + HB_OLE_DESTRUCTOR_FUNC pDestructorFunc; + void * cargo; } HB_OLE; typedef struct @@ -141,6 +143,11 @@ static HB_GARBAGE_FUNC( hb_ole_destructor ) pOle->pCallBack = NULL; hb_itemRelease( pCallBack ); } + if( pOle->pDestructorFunc ) + { + pOle->pDestructorFunc( pOle->cargo ); + pOle->pDestructorFunc = NULL; + } HB_VTBL( pDisp )->Release( HB_THIS( pDisp ) ); } } @@ -221,7 +228,8 @@ PHB_ITEM hb_oleItemPut( PHB_ITEM pItem, IDispatch* pDisp ) pOle->pDisp = pDisp; pOle->pCallBack = NULL; - + pOle->pDestructorFunc = NULL; + pOle->cargo = NULL; return hb_itemPutPtrGC( pItem, pOle ); } @@ -255,6 +263,18 @@ void hb_oleItemSetCallBack( PHB_ITEM pItem, PHB_ITEM* pCallBack ) } +void hb_oleItemSetDestructor( PHB_ITEM pItem, HB_OLE_DESTRUCTOR_FUNC pFunc, void * cargo ) +{ + HB_OLE * pOle = ( HB_OLE * ) hb_itemGetPtrGC( pItem, &s_gcOleFuncs ); + + if( pOle ) + { + pOle->pDestructorFunc = pFunc; + pOle->cargo = cargo; + } +} + + static IEnumVARIANT* hb_oleenumParam( int iParam ) { IEnumVARIANT** ppEnum = ( IEnumVARIANT** ) hb_parptrGC( &s_gcOleenumFuncs, iParam );