diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d4d7d8ca0a..b62041bbcf 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,64 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-08-21 13:34 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/bin/hb-func.sh + ! do not strip system libraries in windows shared linking - unused + ones are not attached to harbour*.dll + + * harbour/contrib/hbwin/hbwinole.h + * harbour/contrib/hbwin/olecore.c + + added support to pass strings with embedded chr(0) characters + + added new public C function: + IDispatch* hb_oleItemGet( PHB_ITEM pItem ); + it extracts IDispatch* pointer from Harbour OLE pointer item. + + added new public C function: + void hb_oleVariantUpdate( VARIANT* pVariant, PHB_ITEM pItem ); + it updates pVariant structure using values from given pointer item + (used to update parameter passed by reference to activex event handler) + % optimized some code + + * harbour/contrib/hbwin/hbwinole.h + * harbour/contrib/hbwin/axcore.c + + added new public C function: + BOOL hb_oleAxInit( void ); + + added new public C function: + PHB_ITEM hb_oleAxControlNew( PHB_ITEM pItem, HWND hWnd ); + It's C function with the same functionality as __AXGETCONTROL() + ! allocate ISink structure using hb_xgrab() not hb_gcAlloc() + ! initialize ISink reference counter to 0 + ! fixed Release() method to free all allocated resources when + reference counter reach 0 + * return new Active-X control as Harbour OLE item pointer. + Warning !!! hb_parptr() and hb_itemGetPtr() do not return valid + pointer for controls created by hb_oleAxControlNew()/__AXGETCONTROL() + Use hb_oleItemGet() and hb_oleParam() to extract pointer to IDispatch + Please update existing code which used __AXGETCONTROL() pointers + at C level. + - removed not longer used hb_sink_destructor + ! removed WIN_AXRELEASEOBJECT() - this function breaks reference counters + used by OLE object which needs strict updating to avoid memory leaks + (not freed OLE object) or GPF traps (accessing freed object) + + extended Invoke() method to update OLE parameters passed by reference. + + accept as event handler hash arrays indexed by event numbers and + values with codeblocks or function pointers. Similar functionality + exists in HWGUI when it's compiled with __USEHASHEVENTS macro and + it's much better then passing two arrays. + % optimized some code + + Please test above Active-X modifications. I'm not MS-Windows user so + they have to be verified by real MS-Windows developers. + They should fix problems with memory leaks (OLE objects where never + freed) or GPF traps in C code which tired to strictly manage reference + counters. + To C programmers: if you increase reference counter to activex control + (AddRef()) then you have to release it (Release()) or activex control + will never be freed even after clearing all .prg references. It's + released only when last reference owner calls Release() method so now + valid code can keep references to IDispatch at C level without any + problem but it also means that this code can exploit problems in + existing wrong code. + 2009-08-21 12:48 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * config/win/mingw.mk * config/win/msvc.mk diff --git a/harbour/bin/hb-func.sh b/harbour/bin/hb-func.sh index d51fa5a943..5a6e991aa8 100755 --- a/harbour/bin/hb-func.sh +++ b/harbour/bin/hb-func.sh @@ -519,7 +519,9 @@ fi [ -n "\${HB_GPM_LIB}" ] && SYSTEM_LIBS="-l\${HB_GPM_LIB} \${SYSTEM_LIBS}" -if [ "\${HB_STATIC}" = "no" ]; then +if [ "\${HB_STATIC}" = "no" ] && \ + [ "\${HB_ARCHITECTURE}" != "win" ] && \ + [ "\${HB_ARCHITECTURE}" != "wce" ]; then SYSTEM_LIBS="" fi diff --git a/harbour/contrib/hbwin/axcore.c b/harbour/contrib/hbwin/axcore.c index 6cecfea527..8555c59c20 100644 --- a/harbour/contrib/hbwin/axcore.c +++ b/harbour/contrib/hbwin/axcore.c @@ -67,7 +67,7 @@ static HMODULE s_hLib = NULL; static PHB_AX_GETCTRL s_pAtlAxGetControl = NULL; -static void hb_ax_exit( void* cargo ) +static void hb_oleAxExit( void* cargo ) { HB_SYMBOL_UNUSED( cargo ); @@ -81,8 +81,7 @@ static void hb_ax_exit( void* cargo ) } } - -static int hb_ax_init( void ) +BOOL hb_oleAxInit( void ) { if( s_hLib == NULL ) { @@ -100,7 +99,7 @@ static int hb_ax_init( void ) if( pAtlAxWinInit ) ( *pAtlAxWinInit )(); - hb_vmAtQuit( hb_ax_exit, NULL ); + hb_vmAtQuit( hb_oleAxExit, NULL ); } return 1; } @@ -108,47 +107,72 @@ static int hb_ax_init( void ) HB_FUNC( WIN_AXINIT ) { - hb_retl( hb_ax_init() ); + hb_retl( hb_oleAxInit() ); +} + + +PHB_ITEM hb_oleAxControlNew( PHB_ITEM pItem, HWND hWnd ) +{ + PHB_ITEM pSubst = NULL; + IUnknown* pUnk = NULL; + IDispatch* pDisp = NULL; + HRESULT lOleError; + + if( pItem ) + hb_itemClear( pItem ); + + if( ! hb_oleAxInit() || ! s_pAtlAxGetControl ) + { + hb_oleSetError( S_OK ); + pSubst = hb_errRT_BASE_Subst( EG_UNSUPPORTED, 3012, "ActiveX not initialized", HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); + } + else + { + 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 ); + HB_VTBL( pUnk )->Release( HB_THIS( pUnk ) ); + } + + hb_oleSetError( lOleError ); + + if( lOleError == S_OK ) + pItem = hb_oleItemPut( pItem, pDisp ); + else + pSubst = hb_errRT_BASE_Subst( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); + } + + if( pSubst ) + { + if( pItem ) + { + hb_itemMove( pItem, pSubst ); + hb_itemRelease( pSubst ); + } + else + pItem = pSubst; + } + + return pItem; } HB_FUNC( __AXGETCONTROL ) /* ( hWnd ) --> pDisp */ { - IUnknown* pUnk = NULL; - IDispatch* pDisp = NULL; - HRESULT lOleError; + HWND hWnd = ( HWND ) hb_parptr( 1 ); - if( ! s_pAtlAxGetControl ) - { - hb_oleSetError( S_OK ); + if( ! hWnd ) hb_errRT_BASE_SubstR( EG_UNSUPPORTED, 3012, "ActiveX not initialized", HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); - return; - } - - lOleError = ( *s_pAtlAxGetControl )( ( HWND ) hb_parptr( 1 ), &pUnk ); - - if( lOleError == S_OK ) - { - lOleError = HB_VTBL( pUnk )->QueryInterface( HB_THIS_( pUnk ) HB_ID_REF( IID_IDispatch ), ( void** ) ( void * ) &pDisp ); - HB_VTBL( pUnk )->Release( HB_THIS( pUnk ) ); - } - - hb_oleSetError( lOleError ); - - if( lOleError == S_OK ) - hb_itemReturnRelease( hb_oleItemPut( NULL, pDisp ) ); else - hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); + hb_oleAxControlNew( hb_stackReturnItem(), hWnd ); } -HB_FUNC( WIN_AXRELEASEOBJECT ) -{ - IDispatch * pDisp = hb_oleParam( 1 ); - HB_VTBL( pDisp )->Release( HB_THIS( pDisp ) ); -} /* ======================== Event handler support ======================== */ + #if !defined( HB_OLE_C_API ) typedef struct { @@ -172,26 +196,6 @@ typedef struct { } ISink; -static HB_GARBAGE_FUNC( hb_sink_destructor ) -{ - ISink * pSink = ( ISink * ) Cargo; - - 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_VTBL( ( IDispatch* ) pSink )->Release( HB_THIS( ( IDispatch* ) pSink ) ); -} - - 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 ) ) ) @@ -213,12 +217,26 @@ static ULONG STDMETHODCALLTYPE AddRef( IDispatch* lpThis ) static ULONG STDMETHODCALLTYPE Release( IDispatch* lpThis ) { - if( --( ( ISink* ) lpThis )->count == 0 ) + ISink* pSink = ( ISink* ) lpThis; + + if( --pSink->count == 0 ) { - hb_xfree( lpThis ); + 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 ( ( ISink* ) lpThis )->count; + return pSink->count; } @@ -251,17 +269,22 @@ static HRESULT STDMETHODCALLTYPE GetIDsOfNames( IDispatch* lpThis, REFIID riid, return E_NOTIMPL; } +typedef struct +{ + PHB_ITEM item; + VARIANT* variant; +} +HB_OLE_PARAM_REF; static HRESULT STDMETHODCALLTYPE Invoke( IDispatch* lpThis, DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr ) { - PHB_ITEM pItem; - int i, iCount; + int i, iCount, ii, iRefs; + PHB_ITEM pAction; HB_SYMBOL_UNUSED( lcid ); HB_SYMBOL_UNUSED( wFlags ); - HB_SYMBOL_UNUSED( pVarResult ); HB_SYMBOL_UNUSED( pExcepInfo ); HB_SYMBOL_UNUSED( puArgErr ); @@ -271,26 +294,58 @@ static HRESULT STDMETHODCALLTYPE Invoke( IDispatch* lpThis, DISPID dispid, REFII if( ! ( ( ISink* ) lpThis)->pItemHandler ) return S_OK; - hb_vmPushState(); - hb_vmPushSymbol( &hb_symEval ); - hb_vmPush( ( ( ISink* ) lpThis )->pItemHandler ); - hb_vmPushLong( dispid ); + pAction = ( ( ISink* ) lpThis )->pItemHandler; - iCount = pParams->cArgs; - for( i = 1; i <= iCount; i++ ) + if( HB_IS_HASH( pAction ) ) { - pItem = hb_itemNew( NULL ); - hb_oleVariantToItem( pItem, &( pParams->rgvarg[ iCount - i ] ) ); - hb_vmPush( pItem ); - hb_itemRelease( pItem ); + PHB_ITEM pKey = hb_itemPutNL( NULL, ( LONG ) dispid ); + pAction = hb_hashGetItemPtr( pAction, pKey, 0 ); + hb_itemRelease( pKey ); } - hb_vmDo( ( USHORT ) iCount + 1 ); + if( pAction && hb_vmRequestReenter() ) + { + HB_OLE_PARAM_REF refArray[ 32 ]; - if( pVarResult ) - hb_oleItemToVariant( pVarResult, hb_stackReturnItem() ); + iCount = pParams->cArgs; + + for( i = iRefs = 0; i < iCount && iRefs < 32; i++ ) + { + if( pParams->rgvarg[ i ].n1.n2.vt & VT_BYREF ) + refArray[ iRefs++ ].item = hb_stackAllocItem(); + } + + hb_vmPushEvalSym(); + hb_vmPush( pAction ); + hb_vmPushLong( ( LONG ) dispid ); + + for( i = 1, ii = 0; i <= iCount; i++ ) + { + if( pParams->rgvarg[ iCount - i ].n1.n2.vt & VT_BYREF ) + { + refArray[ ii ].variant = &pParams->rgvarg[ iCount - i ]; + hb_oleVariantToItem( refArray[ ii ].item, refArray[ ii ].variant ); + hb_vmPushItemRef( refArray[ ii++ ].item ); + } + else + hb_oleVariantToItem( hb_stackAllocItem(), + &pParams->rgvarg[ iCount - i ] ); + } + + hb_vmSend( ( USHORT ) iCount + 1 ); + + if( pVarResult ) + hb_oleItemToVariant( pVarResult, hb_stackReturnItem() ); + + for( i = 0; i < iRefs; i++ ) + hb_oleVariantUpdate( refArray[ i ].variant, refArray[ i ].item ); + + for( i = 0; i < iRefs; i++ ) + hb_stackPop(); + + hb_vmRequestRestore(); + } - hb_vmPopState(); return S_OK; } @@ -312,7 +367,7 @@ HB_FUNC( __AXREGISTERHANDLER ) /* ( pDisp, bHandler ) --> pSink */ if( pDisp ) { - PHB_ITEM pItemBlock = hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL ); + PHB_ITEM pItemBlock = hb_param( 2, HB_IT_BLOCK | HB_IT_SYMBOL | HB_IT_HASH ); if( pItemBlock ) { @@ -327,16 +382,18 @@ HB_FUNC( __AXREGISTERHANDLER ) /* ( pDisp, bHandler ) --> pSink */ if( lOleError == S_OK ) { DWORD dwCookie = 0; - ISink * pSink = ( ISink* ) hb_gcAlloc( sizeof( ISink ), hb_sink_destructor ); /* TODO: GlobalAlloc GMEM_FIXED ??? */ - pSink->lpVtbl = ( IDispatchVtbl * ) &ISink_Vtbl; - pSink->count = 2; /* 1 for pCP->Advice() param and 1 for Harbour collectible pointer [Mindaugas] */ - pSink->pItemHandler = hb_itemNew( pItemBlock ); + ISink * pSink; + pSink = ( ISink* ) hb_xgrab( sizeof( ISink ) ); /* TODO: GlobalAlloc/Free GMEM_FIXED ??? */ + + pSink->lpVtbl = ( IDispatchVtbl * ) &ISink_Vtbl; + pSink->count = 1; /* 1 for Harbour collectible pointer [Mindaugas] */ + pSink->pItemHandler = hb_itemNew( pItemBlock ); lOleError = HB_VTBL( pCP )->Advise( HB_THIS_( pCP ) ( IUnknown* ) pSink, &dwCookie ); pSink->pConnectionPoint = pCP; pSink->dwCookie = dwCookie; - hb_retptrGC( pSink ); + hb_oleItemPut( hb_stackReturnItem(), ( IDispatch* ) pDisp ); } HB_VTBL( pCPC )->Release( HB_THIS( pCPC ) ); } diff --git a/harbour/contrib/hbwin/hbwinole.h b/harbour/contrib/hbwin/hbwinole.h index 2ee9690f46..2c864c62ff 100644 --- a/harbour/contrib/hbwin/hbwinole.h +++ b/harbour/contrib/hbwin/hbwinole.h @@ -103,9 +103,15 @@ HB_EXTERN_BEGIN HB_EXPORT void hb_oleInit( void ); HB_EXPORT HRESULT hb_oleGetError( void ); HB_EXPORT void hb_oleSetError( HRESULT lOleError ); -HB_EXPORT void hb_oleItemToVariant( VARIANT* pVariant, PHB_ITEM pItem ); HB_EXPORT void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT* pVariant ); +HB_EXPORT void hb_oleItemToVariant( VARIANT* pVariant, PHB_ITEM pItem ); +HB_EXPORT void hb_oleVariantUpdate( VARIANT* pVariant, PHB_ITEM pItem ); HB_EXPORT IDispatch* hb_oleParam( int iParam ); +HB_EXPORT IDispatch* hb_oleItemGet( PHB_ITEM pItem ); HB_EXPORT PHB_ITEM hb_oleItemPut( PHB_ITEM pItem, IDispatch* pDisp ); +/* activex control */ +HB_EXPORT BOOL hb_oleAxInit( void ); +HB_EXPORT PHB_ITEM hb_oleAxControlNew( PHB_ITEM pItem, HWND hWnd ); + HB_EXTERN_END diff --git a/harbour/contrib/hbwin/olecore.c b/harbour/contrib/hbwin/olecore.c index 956a66f530..0457f81f47 100644 --- a/harbour/contrib/hbwin/olecore.c +++ b/harbour/contrib/hbwin/olecore.c @@ -152,6 +152,23 @@ IDispatch* hb_oleParam( int iParam ) } +IDispatch* hb_oleItemGet( PHB_ITEM pItem ) +{ + return ( IDispatch* ) hb_itemGetPtrGC( pItem, hb_ole_destructor ); +} + + +PHB_ITEM hb_oleItemPut( PHB_ITEM pItem, IDispatch* pDisp ) +{ + IDispatch** ppDisp; + + ppDisp = ( IDispatch** ) hb_gcAlloc( sizeof( IDispatch* ), hb_ole_destructor ); + *ppDisp = pDisp; + + return hb_itemPutPtrGC( pItem, ppDisp ); +} + + static IEnumVARIANT* hb_oleenumParam( int iParam ) { IEnumVARIANT** ppEnum = ( IEnumVARIANT** ) hb_parptrGC( hb_oleenum_destructor, iParam ); @@ -178,15 +195,33 @@ static wchar_t* AnsiToWide( const char* szString ) } -static char* WideToAnsi( const wchar_t* szWide ) -{ - int iLen; - char* szString; - iLen = WideCharToMultiByte( CP_ACP, 0, szWide, -1, NULL, 0, NULL, NULL ); + +static BSTR hb_oleItemToString( PHB_ITEM pItem ) +{ + const char* szString; + BSTR strVal; + int iLen, iStrLen; + + szString = hb_itemGetCPtr( pItem ); + iLen = ( int ) hb_itemGetCLen( pItem ); + iStrLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szString, iLen, NULL, 0 ); + strVal = SysAllocStringLen( NULL, iStrLen ); + MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szString, iLen, strVal, iStrLen + 1 ); + return strVal; +} + + +static void hb_oleStringToItem( BSTR strVal, PHB_ITEM pItem ) +{ + char* szString; + int iLen, iStrLen; + + iStrLen = ( int ) SysStringLen( strVal ); + iLen = WideCharToMultiByte( CP_ACP, 0, strVal, iStrLen, NULL, 0, NULL, NULL ); szString = ( char* ) hb_xgrab( ( iLen + 1 ) * sizeof( char ) ); - WideCharToMultiByte( CP_ACP, 0, szWide, -1, szString, iLen, NULL, NULL ); - return szString; + WideCharToMultiByte( CP_ACP, 0, strVal, iStrLen, szString, iLen + 1, NULL, NULL ); + hb_itemPutCLPtr( pItem, szString, iLen ); } @@ -201,18 +236,15 @@ static void hb_oleItemToVariantRef( VARIANT* pVariant, PHB_ITEM pItem, { case HB_IT_STRING: case HB_IT_MEMO: - { - wchar_t* szString = AnsiToWide( hb_itemGetCPtr( pItem ) ); pVariant->n1.n2.vt = VT_BSTR; - pVariant->n1.n2.n3.bstrVal = SysAllocString( szString ); - hb_xfree( szString ); + pVariant->n1.n2.n3.bstrVal = hb_oleItemToString( pItem ); if( pVarRef ) { pVarRef->n1.n2.vt = VT_BSTR | VT_BYREF; pVarRef->n1.n2.n3.pbstrVal = &pVariant->n1.n2.n3.bstrVal; } break; - } + case HB_IT_LOGICAL: pVariant->n1.n2.vt = VT_BOOL; pVariant->n1.n2.n3.boolVal = hb_itemGetL( pItem ) ? VARIANT_TRUE : VARIANT_FALSE; @@ -383,22 +415,13 @@ static void hb_oleItemToVariantRef( VARIANT* pVariant, PHB_ITEM pItem, #endif } + void hb_oleItemToVariant( VARIANT* pVariant, PHB_ITEM pItem ) { hb_oleItemToVariantRef( pVariant, pItem, NULL ); } -PHB_ITEM hb_oleItemPut( PHB_ITEM pItem, IDispatch* pDisp ) -{ - IDispatch** ppDisp; - - ppDisp = ( IDispatch** ) hb_gcAlloc( sizeof( IDispatch* ), hb_ole_destructor ); - *ppDisp = pDisp; - - return hb_itemPutPtrGC( pItem, ppDisp ); -} - void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT* pVariant ) { if( pVariant->n1.n2.vt == ( VT_VARIANT | VT_BYREF ) ) @@ -451,18 +474,12 @@ void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT* pVariant ) } case VT_BSTR: - { - char* szString = WideToAnsi( pVariant->n1.n2.n3.bstrVal ); - hb_itemPutCPtr( pItem, szString ); + hb_oleStringToItem( pVariant->n1.n2.n3.bstrVal, pItem ); break; - } case VT_BSTR | VT_BYREF: - { - char* szString = WideToAnsi( *pVariant->n1.n2.n3.pbstrVal ); - hb_itemPutCPtr( pItem, szString ); + hb_oleStringToItem( *pVariant->n1.n2.n3.pbstrVal, pItem ); break; - } case VT_BOOL: hb_itemPutL( pItem, pVariant->n1.n2.n3.boolVal ? TRUE : FALSE ); @@ -473,19 +490,19 @@ void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT* pVariant ) break; case VT_I1: - hb_itemPutNI( pItem, ( int ) pVariant->n1.n2.n3.cVal ); + hb_itemPutNI( pItem, ( signed char ) pVariant->n1.n2.n3.cVal ); break; case VT_I1 | VT_BYREF: - hb_itemPutNI( pItem, ( int ) *pVariant->n1.n2.n3.pcVal ); + hb_itemPutNI( pItem, ( signed char ) *pVariant->n1.n2.n3.pcVal ); break; case VT_I2: - hb_itemPutNI( pItem, ( int ) pVariant->n1.n2.n3.iVal ); + hb_itemPutNI( pItem, ( short ) pVariant->n1.n2.n3.iVal ); break; case VT_I2 | VT_BYREF: - hb_itemPutNI( pItem, ( int ) *pVariant->n1.n2.n3.piVal ); + hb_itemPutNI( pItem, ( short ) *pVariant->n1.n2.n3.piVal ); break; case VT_I4: @@ -519,27 +536,27 @@ void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT* pVariant ) break; case VT_UI1: - hb_itemPutNI( pItem, ( int ) pVariant->n1.n2.n3.bVal ); + hb_itemPutNI( pItem, ( unsigned char ) pVariant->n1.n2.n3.bVal ); break; case VT_UI1 | VT_BYREF: - hb_itemPutNI( pItem, ( int ) *pVariant->n1.n2.n3.pbVal ); + hb_itemPutNI( pItem, ( unsigned char ) *pVariant->n1.n2.n3.pbVal ); break; case VT_UI2: - hb_itemPutNI( pItem, ( int ) pVariant->n1.n2.n3.uiVal ); + hb_itemPutNI( pItem, ( unsigned short ) pVariant->n1.n2.n3.uiVal ); break; case VT_UI2 | VT_BYREF: - hb_itemPutNI( pItem, ( int ) *pVariant->n1.n2.n3.puiVal ); + hb_itemPutNI( pItem, ( unsigned short ) *pVariant->n1.n2.n3.puiVal ); break; case VT_UI4: - hb_itemPutNInt( pItem, ( HB_LONG ) pVariant->n1.n2.n3.ulVal ); + hb_itemPutNInt( pItem, pVariant->n1.n2.n3.ulVal ); break; case VT_UI4 | VT_BYREF: - hb_itemPutNInt( pItem, ( HB_LONG ) *pVariant->n1.n2.n3.pulVal ); + hb_itemPutNInt( pItem, *pVariant->n1.n2.n3.pulVal ); break; case VT_UI8: @@ -575,11 +592,11 @@ void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT* pVariant ) break; case VT_UINT: - hb_itemPutNInt( pItem, ( HB_LONG ) pVariant->n1.n2.n3.uintVal ); + hb_itemPutNInt( pItem, pVariant->n1.n2.n3.uintVal ); break; case VT_UINT | VT_BYREF: - hb_itemPutNInt( pItem, ( HB_LONG ) *pVariant->n1.n2.n3.puintVal ); + hb_itemPutNInt( pItem, *pVariant->n1.n2.n3.puintVal ); break; case VT_R4: @@ -682,6 +699,119 @@ void hb_oleVariantToItem( PHB_ITEM pItem, VARIANT* pVariant ) } +void hb_oleVariantUpdate( VARIANT* pVariant, PHB_ITEM pItem ) +{ + switch( pVariant->n1.n2.vt ) + { + case VT_DISPATCH | VT_BYREF: + { + IDispatch* pDisp = hb_oleItemGet( pItem ); + + if( pDisp ) + { + IDispatch* pdispVal = *pVariant->n1.n2.n3.ppdispVal; + HB_VTBL( pDisp )->AddRef( HB_THIS( pDisp ) ); + *pVariant->n1.n2.n3.ppdispVal = pDisp; + if( pdispVal ) + HB_VTBL( pdispVal )->Release( HB_THIS( pdispVal ) ); + } + break; + } + + case VT_BSTR | VT_BYREF: + SysFreeString( *pVariant->n1.n2.n3.pbstrVal ); + *pVariant->n1.n2.n3.pbstrVal = hb_oleItemToString( pItem ); + break; + + case VT_BOOL | VT_BYREF: + *pVariant->n1.n2.n3.pboolVal = hb_itemGetL( pItem ); + break; + + case VT_I1 | VT_BYREF: + *pVariant->n1.n2.n3.pcVal = ( signed char ) hb_itemGetNI( pItem ); + break; + + case VT_I2 | VT_BYREF: + *pVariant->n1.n2.n3.piVal = ( short ) hb_itemGetNI( pItem ); + break; + + case VT_I4 | VT_BYREF: + *pVariant->n1.n2.n3.plVal = hb_itemGetNL( pItem ); + break; + + case VT_I8 | VT_BYREF: +#if HB_LONG_MAX == INT32_MAX || defined( HB_LONG_LONG_OFF ) + *pVariant->n1.n2.n3.plVal = ( long ) hb_itemGetNInt( pItem ); +#elif defined( HB_OLE_NO_LLREF ) + /* workaround for wrong OLE variant structure definition */ + * ( LONGLONG * ) pVariant->n1.n2.n3.pdblVal = ( LONGLONG ) hb_itemGetNInt( pItem ); +#else + *pVariant->n1.n2.n3.pllVal = ( LONGLONG ) hb_itemGetNInt( pItem ); +#endif + break; + + case VT_UI1 | VT_BYREF: + *pVariant->n1.n2.n3.pbVal = ( unsigned char ) hb_itemGetNI( pItem ); + break; + + case VT_UI2 | VT_BYREF: + *pVariant->n1.n2.n3.puiVal = ( unsigned short ) hb_itemGetNI( pItem ); + break; + + case VT_UI4 | VT_BYREF: + *pVariant->n1.n2.n3.pulVal = ( unsigned long ) hb_itemGetNL( pItem ); + break; + + case VT_UI8 | VT_BYREF: +#if HB_LONG_MAX == INT32_MAX || defined( HB_LONG_LONG_OFF ) + *pVariant->n1.n2.n3.pulVal = ( unsigned long ) hb_itemGetNInt( pItem ); +#elif defined( HB_OLE_NO_LLREF ) + /* workaround for wrong OLE variant structure definition */ + * ( ULONGLONG * ) pVariant->n1.n2.n3.pdblVal = ( ULONGLONG ) hb_itemGetNInt( pItem ); +#else + *pVariant->n1.n2.n3.pullVal = ( ULONGLONG ) hb_itemGetNInt( pItem ); +#endif + break; + + case VT_INT | VT_BYREF: + *pVariant->n1.n2.n3.pintVal = hb_itemGetNI( pItem ); + break; + + case VT_UINT | VT_BYREF: + *pVariant->n1.n2.n3.puintVal = ( unsigned int ) hb_itemGetNI( pItem ); + break; + + case VT_R4 | VT_BYREF: + *pVariant->n1.n2.n3.pfltVal = ( float ) hb_itemGetND( pItem ); + break; + + case VT_R8 | VT_BYREF: + *pVariant->n1.n2.n3.pdblVal = hb_itemGetND( pItem ); + break; + + case VT_CY | VT_BYREF: + VarCyFromR8( hb_itemGetND( pItem ), pVariant->n1.n2.n3.pcyVal ); + break; + + case VT_DECIMAL | VT_BYREF: + VarDecFromR8( hb_itemGetND( pItem ), pVariant->n1.n2.n3.pdecVal ); + break; + + case VT_DATE | VT_BYREF: + *pVariant->n1.n2.n3.pdblVal = hb_itemGetTD( pItem ) - HB_OLE_DATE_BASE; + break; + + case VT_BYREF | VT_VARIANT: + hb_oleItemToVariantRef( pVariant->n1.n2.n3.pvarVal, pItem, NULL ); + break; + + case VT_VARIANT | VT_ARRAY | VT_BYREF: + /* TODO: */ + break; + } +} + + /* IDispatch parameters, return value handling */ static void GetParams( DISPPARAMS * dispparam )