diff --git a/harbour/ChangeLog b/harbour/ChangeLog index e2c05f14c8..c979c0d219 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,20 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-05-26 11:19 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/contrib/hbwin/hbwinole.h + ! fixed typo in added extern declarations + + * harbour/contrib/hbwin/hbwinole.h + * harbour/contrib/hbwin/axcore.c + * harbour/contrib/hbwin/olecore.c + * harbour/contrib/hbwin/hbolesrv.c + + added support for automatic conversion of HVM objects returned by + Harbour OLE server methods to OLE objects. + Please test. I cannot make any tests now. + ; TODO: if it works then update this code to create some more general + version. + 2010-05-26 11:08 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbwin/hbwinole.h + Added missing 'extern' to HB_EXPORT declarations. diff --git a/harbour/contrib/hbwin/axcore.c b/harbour/contrib/hbwin/axcore.c index 72ed736550..55e97b6a56 100644 --- a/harbour/contrib/hbwin/axcore.c +++ b/harbour/contrib/hbwin/axcore.c @@ -347,7 +347,7 @@ static HRESULT STDMETHODCALLTYPE Invoke( IDispatch* lpThis, DISPID dispid, REFII pAction = hb_hashGetItemPtr( pAction, pKey, 0 ); if( pAction && hb_oleDispInvoke( NULL, pAction, pKey, - pParams, pVarResult ) ) + pParams, pVarResult, NULL ) ) hr = S_OK; hb_stackPop(); diff --git a/harbour/contrib/hbwin/hbolesrv.c b/harbour/contrib/hbwin/hbolesrv.c index 693acd3198..446956d5db 100644 --- a/harbour/contrib/hbwin/hbolesrv.c +++ b/harbour/contrib/hbwin/hbolesrv.c @@ -86,6 +86,8 @@ static PHB_ITEM s_pMsgArray = NULL; static HINSTANCE s_hInstDll; +static HB_BOOL s_objItemToVariant( VARIANT * pVariant, PHB_ITEM pItem ); + /* helper functions */ static DISPID hb_dynsymToDispId( PHB_DYNS pDynSym ) @@ -398,7 +400,7 @@ static HRESULT STDMETHODCALLTYPE Invoke( IDispatch* lpThis, DISPID dispid, REFII { fResult = hb_oleDispInvoke( NULL, pAction, hb_arrayGetItemPtr( s_pMsgArray, ( HB_SIZE ) dispid ), - pParams, pVarResult ); + pParams, pVarResult, s_objItemToVariant ); } } else if( HB_IS_HASH( pAction ) ) @@ -424,7 +426,7 @@ static HRESULT STDMETHODCALLTYPE Invoke( IDispatch* lpThis, DISPID dispid, REFII { PHB_SYMB pSym = hb_itemGetSymbol( pItem ); fResult = hb_oleDispInvoke( pSym, pSym ? pAction : pItem, pKey, - pParams, pVarResult ); + pParams, pVarResult, s_objItemToVariant ); } } else if( ( wFlags & DISPATCH_PROPERTYGET ) != 0 && @@ -462,7 +464,7 @@ static HRESULT STDMETHODCALLTYPE Invoke( IDispatch* lpThis, DISPID dispid, REFII if( pDynSym && hb_objHasMessage( pAction, pDynSym ) ) { fResult = hb_oleDispInvoke( hb_dynsymSymbol( pDynSym ), pAction, NULL, - pParams, pVarResult ); + pParams, pVarResult, s_objItemToVariant ); } } if( !fResult ) @@ -504,7 +506,7 @@ static HRESULT STDMETHODCALLTYPE Invoke( IDispatch* lpThis, DISPID dispid, REFII !hb_dynsymIsFunction( pDynSym ) ) return DISP_E_MEMBERNOTFOUND; else if( !hb_oleDispInvoke( hb_dynsymSymbol( pDynSym ), NULL, NULL, - pParams, pVarResult ) ) + pParams, pVarResult, s_objItemToVariant ) ) return DISP_E_MEMBERNOTFOUND; } @@ -572,6 +574,47 @@ static ULONG STDMETHODCALLTYPE classRelease( IClassFactory* lpThis ) return InterlockedDecrement( &s_lObjectCount ); } +static HRESULT s_createHbOleObject( REFIID riid, void** ppvObj, + PHB_ITEM pAction, HB_BOOL fGuids ) +{ + HRESULT hr; + IHbOleServer * thisobj = ( IHbOleServer * ) hb_xalloc( sizeof( IHbOleServer ) ); + + if( !thisobj ) + { + if( pAction ) + hb_itemRelease( pAction ); + hr = E_OUTOFMEMORY; + } + else + { + thisobj->lpVtbl = &IHbOleServer_Vtbl; + thisobj->count = 1; + thisobj->pAction = pAction; + thisobj->fGuids = fGuids; + hr = IHbOleServer_Vtbl.QueryInterface( ( IDispatch* ) thisobj, riid, ppvObj ); + IHbOleServer_Vtbl.Release( ( IDispatch* ) thisobj ); + if( hr == S_OK ) + InterlockedIncrement( &s_lObjectCount ); + } + return hr; +} + +static HB_BOOL s_objItemToVariant( VARIANT * pVariant, PHB_ITEM pItem ) +{ + void * pvObj; + + VariantClear( pVariant ); + + if( s_createHbOleObject( HB_ID_REF( IID_IDispatch ), &pvObj, + hb_itemNew( pItem ), HB_FALSE ) == S_OK ) + { + pVariant->n1.n2.vt = VT_DISPATCH; + pVariant->n1.n2.n3.pdispVal = ( IDispatch * ) pvObj; + } + return HB_FALSE; +} + static HRESULT STDMETHODCALLTYPE classCreateInstance( IClassFactory* lpThis, IUnknown* punkOuter, REFIID riid, @@ -587,42 +630,31 @@ static HRESULT STDMETHODCALLTYPE classCreateInstance( IClassFactory* lpThis, hr = CLASS_E_NOAGGREGATION; else { - IHbOleServer * thisobj = ( IHbOleServer * ) hb_xalloc( sizeof( IHbOleServer ) ); + PHB_ITEM pAction = NULL; + HB_BOOL fGuids = HB_FALSE; - if( !thisobj ) - hr = E_OUTOFMEMORY; - else + if( s_pAction ) { - thisobj->lpVtbl = &IHbOleServer_Vtbl; - thisobj->count = 1; - thisobj->pAction = NULL; - thisobj->fGuids = HB_FALSE; - if( s_pAction ) + if( HB_IS_EVALITEM( s_pAction ) ) { - if( HB_IS_EVALITEM( s_pAction ) ) + if( hb_vmRequestReenter() ) { - if( hb_vmRequestReenter() ) - { - hb_vmPushEvalSym(); - hb_vmPush( s_pAction ); - hb_vmProc( 0 ); - thisobj->pAction = hb_itemNew( hb_stackReturnItem() ); - hb_vmRequestRestore(); - } - } - else if( HB_IS_HASH( s_pAction ) ) - { - if( s_fHashClone ) - thisobj->pAction = hb_itemClone( s_pAction ); - else if( !s_pMsgHash && s_hashWithNumKeys( s_pAction ) ) - thisobj->fGuids = HB_TRUE; + hb_vmPushEvalSym(); + hb_vmPush( s_pAction ); + hb_vmProc( 0 ); + pAction = hb_itemNew( hb_stackReturnItem() ); + hb_vmRequestRestore(); } } - hr = IHbOleServer_Vtbl.QueryInterface( ( IDispatch* ) thisobj, riid, ppvObj ); - IHbOleServer_Vtbl.Release( ( IDispatch* ) thisobj ); - if( hr == S_OK ) - InterlockedIncrement( &s_lObjectCount ); + else if( HB_IS_HASH( s_pAction ) ) + { + if( s_fHashClone ) + pAction = hb_itemClone( s_pAction ); + else if( !s_pMsgHash && s_hashWithNumKeys( s_pAction ) ) + fGuids = HB_TRUE; + } } + hr = s_createHbOleObject( riid, ppvObj, pAction, fGuids ); } return hr; } diff --git a/harbour/contrib/hbwin/hbwinole.h b/harbour/contrib/hbwin/hbwinole.h index 35c4b586a7..e42265fc0c 100644 --- a/harbour/contrib/hbwin/hbwinole.h +++ b/harbour/contrib/hbwin/hbwinole.h @@ -105,11 +105,14 @@ HB_EXTERN_BEGIN +typedef HB_BOOL ( * HB_OLEOBJ_FUNC )( VARIANT*, PHB_ITEM ); + extern HB_EXPORT HB_BOOL hb_oleInit( void ); extern HB_EXPORT HRESULT hb_oleGetError( void ); extern HB_EXPORT void hb_oleSetError( HRESULT lOleError ); extern HB_EXPORT void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT * pVariant ); extern HB_EXPORT void hb_oleItemToVariant( VARIANT * pVariant, PHB_ITEM pItem ); +extern HB_EXPORT void hb_oleItemToVariantEx( VARIANT* pVariant, PHB_ITEM pItem, HB_OLEOBJ_FUNC pObjFunc ); extern HB_EXPORT void hb_oleVariantUpdate( VARIANT * pVariant, PHB_ITEM pItem ); extern HB_EXPORT IDispatch* hb_oleParam( int iParam ); extern HB_EXPORT IDispatch* hb_oleItemGet( PHB_ITEM pItem ); @@ -117,7 +120,8 @@ extern HB_EXPORT PHB_ITEM hb_oleItemPut( PHB_ITEM pItem, IDispatch * pDisp ); extern HB_EXPORT PHB_ITEM hb_oleItemGetCallBack( PHB_ITEM pItem ); extern HB_EXPORT void hb_oleItemSetCallBack( PHB_ITEM pItem, PHB_ITEM * pCallBack ); extern HB_EXPORT HB_BOOL hb_oleDispInvoke( PHB_SYMB pSym, PHB_ITEM pObject, PHB_ITEM pParam, -extern DISPPARAMS * pParams, VARIANT* pVarResult ); + DISPPARAMS * pParams, VARIANT* pVarResult, + HB_OLEOBJ_FUNC pObjFunc ); /* 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 a8bbf0307e..2487365aaf 100644 --- a/harbour/contrib/hbwin/olecore.c +++ b/harbour/contrib/hbwin/olecore.c @@ -349,7 +349,7 @@ static void hb_oleDispatchToVariant( VARIANT* pVariant, IDispatch* pDisp, /* Item <-> Variant conversion */ static void hb_oleItemToVariantRef( VARIANT* pVariant, PHB_ITEM pItem, - VARIANT* pVarRef ) + VARIANT* pVarRef, HB_OLEOBJ_FUNC pObjFunc ) { VariantClear( pVariant ); /* pVariant->n1.n2.vt = VT_EMPTY; */ @@ -473,6 +473,8 @@ static void hb_oleItemToVariantRef( VARIANT* pVariant, PHB_ITEM pItem, if( pDisp ) hb_oleDispatchToVariant( pVariant, pDisp, pVarRef ); + else if( pObjFunc ) + pObjFunc( pVariant, pItem ); } else { @@ -500,7 +502,7 @@ static void hb_oleItemToVariantRef( VARIANT* pVariant, PHB_ITEM pItem, long lIndex[ 1 ]; VariantInit( &vItem ); - hb_oleItemToVariantRef( &vItem, hb_arrayGetItemPtr( pItem, ul + 1 ), NULL ); + hb_oleItemToVariantRef( &vItem, hb_arrayGetItemPtr( pItem, ul + 1 ), NULL, NULL ); lIndex[ 0 ] = ( long ) ul; SafeArrayPutElement( pSafeArray, lIndex, &vItem ); VariantClear( &vItem ); @@ -532,7 +534,14 @@ static void hb_oleItemToVariantRef( VARIANT* pVariant, PHB_ITEM pItem, void hb_oleItemToVariant( VARIANT* pVariant, PHB_ITEM pItem ) { - hb_oleItemToVariantRef( pVariant, pItem, NULL ); + hb_oleItemToVariantRef( pVariant, pItem, NULL, NULL ); +} + + +void hb_oleItemToVariantExt( VARIANT* pVariant, PHB_ITEM pItem, + HB_OLEOBJ_FUNC pObjFunc ) +{ + hb_oleItemToVariantRef( pVariant, pItem, NULL, pObjFunc ); } @@ -1032,7 +1041,7 @@ void hb_oleVariantUpdate( VARIANT* pVariant, PHB_ITEM pItem ) #endif case VT_BYREF | VT_VARIANT: - hb_oleItemToVariantRef( pVariant->n1.n2.n3.pvarVal, pItem, NULL ); + hb_oleItemToVariantRef( pVariant->n1.n2.n3.pvarVal, pItem, NULL, NULL ); break; case VT_VARIANT | VT_ARRAY | VT_BYREF: @@ -1052,7 +1061,8 @@ typedef struct HB_OLE_PARAM_REF; HB_BOOL hb_oleDispInvoke( PHB_SYMB pSym, PHB_ITEM pObject, PHB_ITEM pParam, - DISPPARAMS* pParams, VARIANT* pVarResult ) + DISPPARAMS* pParams, VARIANT* pVarResult, + HB_OLEOBJ_FUNC pObjFunc ) { if( !pSym && HB_IS_SYMBOL( pObject ) ) { @@ -1108,7 +1118,7 @@ HB_BOOL hb_oleDispInvoke( PHB_SYMB pSym, PHB_ITEM pObject, PHB_ITEM pParam, hb_vmProc( ( HB_USHORT ) iParams ); if( pVarResult ) - hb_oleItemToVariant( pVarResult, hb_stackReturnItem() ); + hb_oleItemToVariantRef( pVarResult, hb_stackReturnItem(), NULL, pObjFunc ); for( i = 0; i < iRefs; i++ ) hb_oleVariantUpdate( refArray[ i ].variant, refArray[ i ].item ); @@ -1151,11 +1161,11 @@ static void GetParams( DISPPARAMS * dispparam ) { VariantInit( pRefs ); hb_oleItemToVariantRef( pRefs, hb_param( uiArgCount - uiArg, HB_IT_ANY ), - &pArgs[ uiArg ] ); + &pArgs[ uiArg ], NULL ); ++pRefs; } else - hb_oleItemToVariantRef( &pArgs[ uiArg ], hb_param( uiArgCount - uiArg, HB_IT_ANY ), NULL ); + hb_oleItemToVariantRef( &pArgs[ uiArg ], hb_param( uiArgCount - uiArg, HB_IT_ANY ), NULL, NULL ); } }