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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user