Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » Problem with CExtPropertyValueCompound & unicode encoding Collapse All
Subject Author Date
a a Feb 19, 2006 - 11:26 PM

Hi.


I tested my code (started in multi-byte encoding) in Unicode encoding, and I realised the values in CExtPropertyValueCompound properties might not be parsed properly. (the ’,’ separator might have been considered as a value.)
I made a small sample to check if it is coming from my code, but I couldn’t figure out why. Here’s an excerpt of the test.
How to fix this problem?


  CExtPropertyStore &ps = *new CExtPropertyStore(L"test");
  CExtPropertyValueCompound &pvc = *new CExtPropertyValueCompound(L"test");
  pvc.ItemInsert(new CExtPropertyValue(L"test", new CExtGridCellString()));
  pvc.ItemInsert(new CExtPropertyValue(L"test", new CExtGridCellString()));
  ps.ItemInsert(&pvc);
  _grid.PropertyStoreSet(&ps);
  _grid.PropertyStoreSynchronize();

a a Feb 19, 2006 - 11:31 PM

Put "12, 12" in the CExtPropertyValueCompound, the value will become "12,, 12"


"12,12" becomes "12,1, 1,"


etc...

Technical Support Feb 20, 2006 - 9:42 AM

The property values inside the compound value in your code snippet are initialized incompletely. Here is how the two "test" property values with string grid cells can be initialized correctly:

CExtPropertyValue * pTest1 = new CExtPropertyValue( "test" );
    pTest1->ValueActiveGetByRTC( RUNTIME_CLASS(CExtGridCellString) );
    pTest1->ValueDefaultFromActive();
CExtPropertyValue * pTest2 = new CExtPropertyValue( "test" );
    pTest2->ValueActiveGetByRTC( RUNTIME_CLASS(CExtGridCellString) );
    pTest2->ValueDefaultFromActive();
CExtPropertyValueCompound &pvc = *new CExtPropertyValueCompound("test");
    pvc.ItemInsert( pTest1 );
    pvc.ItemInsert( pTest2 );
    m_pPS->ItemInsert(&pvc);


a a Feb 20, 2006 - 5:49 PM

I have the same problem with the following code. Did you check in Unicode?

  CExtPropertyValue * pTest1 = new CExtPropertyValue( L"test" );
  pTest1->ValueActiveGetByRTC( RUNTIME_CLASS(CExtGridCellString) );
  pTest1->ValueDefaultFromActive();


  CExtPropertyValue * pTest2 = new CExtPropertyValue( L"test" );
  pTest2->ValueActiveGetByRTC( RUNTIME_CLASS(CExtGridCellString) );
  pTest2->ValueDefaultFromActive();


  CExtPropertyValueCompound &pvc = *new CExtPropertyValueCompound(L"test");
  pvc.ItemInsert( pTest1 );
  pvc.ItemInsert( pTest2 );

  CExtPropertyStore &ps = *new CExtPropertyStore(L"test");
  ps.ItemInsert(&pvc);
  _grid.PropertyStoreSet(&ps);
  _grid.PropertyStoreSynchronize();

Technical Support Feb 21, 2006 - 6:12 AM

We have successfully reproduced the problem. To fix it, please update the source code of the CExtPropertyValueCompound::stat_ExpandListPart() method in the ExtPropertyGridWnd.cpp file:

__EXT_MFC_SAFE_LPCTSTR CExtPropertyValueCompound::stat_ExpandListPart(
    __EXT_MFC_SAFE_LPCTSTR strWalk,
    CExtSafeString & strOutListItem,
    __EXT_MFC_SAFE_LPCTSTR _strListSeparator, // = NULL
    __EXT_MFC_SAFE_LPCTSTR strTrimLeftRight // = NULL
    )
{
    ASSERT( strWalk != NULL );
    strOutListItem.Empty();
TCHAR strListSeparator[8];
    ::memset( strListSeparator, 0, sizeof(strListSeparator) );
    if( _strListSeparator == NULL )
    {
        if( g_ResourceManager->GetLocaleInfo(
                LOCALE_SLIST,
                strListSeparator,
                4
                ) <= 0
            )
            __EXT_MFC_STRCPY( 
                strListSeparator, 
                sizeof(strListSeparator)/sizeof(strListSeparator[0]),
                _T(";") 
                );
    } // if( _strListSeparator == NULL )
    else
    {
        ASSERT(
            _tcslen(_strListSeparator) <
                sizeof(strListSeparator)/sizeof(strListSeparator[0])
                );
        __EXT_MFC_STRNCPY(
            strListSeparator,
            sizeof(strListSeparator)/sizeof(strListSeparator[0]),
            _strListSeparator,
            sizeof(strListSeparator)/sizeof(strListSeparator[0])
            );
    } // else from if( _strListSeparator == NULL )
LPCTSTR strWalkOut = _tcsstr( strWalk, strListSeparator );
    if( strWalkOut == NULL )
    {
        if( strWalk[0] != _T(’\0’) )
        {
            strOutListItem = strWalk; // last item in list
            if( ! strOutListItem.IsEmpty() )
            {
                if( strTrimLeftRight == NULL )
                {
                    strOutListItem.TrimLeft(  _T(" \r\n\t") );
                    strOutListItem.TrimRight( _T(" \r\n\t") );
                } // if( strTrimLeftRight == NULL )
                else if( _tcslen(strTrimLeftRight) > 0 )
                {
                    strOutListItem.TrimLeft(  strTrimLeftRight );
                    strOutListItem.TrimRight( strTrimLeftRight );
                } // else if( _tcslen(strTrimLeftRight) > 0 )
            } // if( ! strOutListItem.IsEmpty() )
        } // if( strWalk[0] != _T(’\0’) )
        strWalkOut = strWalk;
        strWalkOut += _tcslen( strWalk );
        return strWalkOut;
    } // if( strWalkOut == NULL )
LONG nBufferLen = ( LONG(strWalkOut) - LONG(strWalk) ) / sizeof(TCHAR);
    ASSERT( nBufferLen >= 0 );
    if( nBufferLen > 0 )
    {
        LPTSTR strBuffer =
            strOutListItem.GetBuffer(
                nBufferLen + 1
                );
        if( strBuffer != NULL )
        {
            ::memset(
                strBuffer,
                0,
                (nBufferLen+1) * sizeof(TCHAR)
                );
            __EXT_MFC_STRNCPY(
                strBuffer,
                nBufferLen + 1,
                strWalk,
                nBufferLen
                );
            strOutListItem.ReleaseBuffer();
        } // if( strBuffer != NULL )
    } // if( nBufferLen > 0 )
    strWalkOut += _tcslen( strListSeparator );
    if( ! strOutListItem.IsEmpty() )
    {
        if( strTrimLeftRight == NULL )
        {
            strOutListItem.TrimLeft(  _T(" \r\n\t") );
            strOutListItem.TrimRight( _T(" \r\n\t") );
        } // if( strTrimLeftRight == NULL )
        else if( _tcslen(strTrimLeftRight) > 0 )
        {
            strOutListItem.TrimLeft(  strTrimLeftRight );
            strOutListItem.TrimRight( strTrimLeftRight );
        } // else if( _tcslen(strTrimLeftRight) > 0 )
        strOutListItem.TrimLeft( strListSeparator );
        strOutListItem.TrimRight( strListSeparator );
    } // if( ! strOutListItem.IsEmpty() )
    return strWalkOut;
}


a a Feb 21, 2006 - 7:38 PM

Thanks. I just downloaded and applied the patch on the last upgrade available on the FTP. It works perfectly now.


Just one question, will I have to apply this patch each time I download a new version or will this patch be present on futur releases?


< LONG nBufferLen =
< #if _MFC_VER >= 0x0800
<   ( INT_PTR(strWalkOut) - INT_PTR(strWalk) ) / sizeof(TCHAR);
< #else
<   ( LONG(strWalkOut) - LONG(strWalk) ) / sizeof(TCHAR);
< #endif
---
> LONG nBufferLen = ( LONG(strWalkOut) - LONG(strWalk) ) / sizeof(TCHAR);


 

Technical Support Feb 22, 2006 - 12:03 PM

This patch is persistent, so you don’t need to apply it each time.