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 » How Can I change PropertyStore at runtime? Collapse All
Subject Author Date
Constantine Zzz Sep 18, 2007 - 3:23 AM

Example:
In the PropertyStore there GridCellUpDown, it’s value I use for number of some PropertyValue’s. How update PropertyGrid and PropertyStore correctly?

if I call PropertyStoreSynchronize() at GridCellUpDown->Apply() (here I insert new properties to PropertyStore), it throws exception...

Technical Support Sep 21, 2007 - 5:45 AM

We believe there must be something specific in your project that leads to these crashes. Would you send us a project that demonstrates the problem so we can hep you?

Constantine Z. Sep 21, 2007 - 2:47 AM

I don’t know maybe my version of Prof-UIS is too old, 1.52. But it crashes when I use PGCWnd->PropertyStoreSynchronizeAll() or PGC->PropertyStoreSynchronize in Apply() method of any PropertyItem.

In OnPgcCompleteInput() any of this calls crashes too. I don’t know what to do, maybe I’ll try Malcolm D way, with hidden properties instead of inserting them.

Technical Support Sep 20, 2007 - 11:00 AM

There is not enough information in your message to reproduce the crash. We tried to modify the CExtPropertyGridWnd::OnGridCellInputComplete() virtual method and invoked PropertyStoreSynchronize() after Apply(), but that did not generate any crashes in any cells. It would be helpful to receive a test which reproduces the crash. Here is the modified method’s source code:

void CExtPropertyGridWnd::OnGridCellInputComplete(
      CExtGridCell & _cell,
      LONG nColNo,
      LONG nRowNo,
      INT nColType,
      INT nRowType,
      HWND hWndInputControl // = NULL
      )
{
      ASSERT_VALID( this );
      CExtTreeGridWnd::OnGridCellInputComplete(
            _cell,
            nColNo,
            nRowNo,
            nColType,
            nRowType,
            hWndInputControl
            );
      if( nColNo != 1 || nColType != 0 || nRowType != 0 )
            return;
HTREEITEM hTreeItem =
            ItemGetByVisibleRowIndex( nRowNo );
      if( hTreeItem == NULL )
            return;
CExtPropertyItem * pPropertyItem =
            PropertyItemFromTreeItem( hTreeItem );
      if(         pPropertyItem == NULL
            ||    (! pPropertyItem->IsKindOf(RUNTIME_CLASS(CExtPropertyValue)) )
            )
            return;
      ASSERT_VALID( pPropertyItem );
CExtSafeString strCompoundPath;
      _cell.ModifyStyleEx( 0, __EGCS_EX_UNDEFINED_ROLE );
      _cell.TextGet( strCompoundPath );
CExtPropertyGridCtrl * pPGC = PropertyGridCtrlGet();
CExtPropertyValueCompound * pCompoundValue =
            DYNAMIC_DOWNCAST(
                  CExtPropertyValueCompound,
                  pPropertyItem
                  );
CExtPropertyValueMixedCompound * pMixedCompound =
            DYNAMIC_DOWNCAST(
                  CExtPropertyValueMixedCompound,
                  pPropertyItem
                  );
      if( pCompoundValue != NULL )
      {
            CExtPropertyValue * pValueParseError = NULL;
            pCompoundValue->SynchronizeChildrenTreeActive(
                  LPCTSTR( strCompoundPath ),
                  true,
                  &pValueParseError
                  );
            if( pValueParseError != NULL )
            {
                  CExtSafeString strCompoundValue =
                        pCompoundValue->BuildCompoundTextActive();
                  _cell.TextSet( strCompoundValue );
                  return;
            }
      } // if( pCompoundValue != NULL )
      if( pMixedCompound != NULL )
      {
            CExtPropertyValue * pValueParseError = NULL;
            pMixedCompound->SynchronizeChildrenTreeActive(
                  LPCTSTR( strCompoundPath ),
                  true,
                  &pValueParseError
                  );
            if( pValueParseError != NULL )
            {
                  CExtSafeString strCompoundValue =
                        pMixedCompound->BuildCompoundTextActive();
                  _cell.TextSet( strCompoundValue );
                  return;
            }
      } // if( pMixedCompound != NULL )
      pPropertyItem->Apply( &_cell );



PropertyStoreSynchronizeAll(); ////////////////// THIS LINE WAS ADDED ////////////////////////////////



      _cell.ModifyStyleEx( 0, __EGCS_EX_UNDEFINED_ROLE );
      if( pPropertyItem->IsKindOf(RUNTIME_CLASS(CExtPropertyValueMixed)) )
      {
            if( pPropertyItem->ChildrenHaveDifferentActiveValues() )
                  _cell.ModifyStyleEx( __EGCS_EX_UNDEFINED_ROLE );
            else
                  _cell.ModifyStyleEx( 0, __EGCS_EX_UNDEFINED_ROLE );
      } // if( pPropertyItem->IsKindOf(RUNTIME_CLASS(CExtPropertyValueMixed)) )
      if( pPGC != NULL )
      {
            ASSERT_VALID( pPGC );
            if( pCompoundValue != NULL )
            {
                  ASSERT_VALID( pPGC );
                  pCompoundValue->SynchronizeCompoundParentPathActive();
                  pCompoundValue->SynchronizeChildrenTreeActive(
                        LPCTSTR( strCompoundPath ),
                        false
                        );
                  pPGC->OnPgcSynchronizeCompoundValue(
                        pCompoundValue
                        );
            } // if( pCompoundValue != NULL )
            if( pMixedCompound != NULL )
            {
                  ASSERT_VALID( pPGC );
                  pMixedCompound->SynchronizeCompoundParentPathActive();
                  pMixedCompound->SynchronizeChildrenTreeActive(
                        LPCTSTR( strCompoundPath ),
                        false
                        );
                  pPGC->OnPgcSynchronizeCompoundValue(
                        pMixedCompound
                        );
            } // if( pMixedCompound != NULL )
            CTypedPtrArray < CPtrArray, CExtPropertyGridWnd * > arrGrids;
            pPGC->OnPgcQueryGrids( arrGrids );
            INT nGridIdx;
            for( nGridIdx = 0; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
            {
                  CExtPropertyGridWnd * pGrid = arrGrids[ nGridIdx ];
                  ASSERT_VALID( pGrid );
                  if( pGrid == this )
                        continue;
                  HTREEITEM htiOther =
                        pGrid->PropertyItemToTreeItem(
                              pPropertyItem
                              );
                  if( htiOther == NULL )
                        continue;
                  CExtGridCell * pCellOther =
                        pGrid->ItemGetCell( htiOther, 1 );
                  if( pCellOther == NULL )
                        continue;
                  ASSERT_VALID( pCellOther );
                  if( LPVOID(pCellOther) != LPVOID(&_cell) )
                        pCellOther->Assign( _cell );
            } // for( nGridIdx = 0; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
            CExtPropertyItem * pParentItem =
                  pPropertyItem->ItemParentGet();
            for( ; pParentItem != NULL; )
            {
                  ASSERT_VALID( pParentItem );
                  bool bSyncGrids = false;
                  CExtGridCell * pCellSrc = NULL;
                  CExtPropertyValueCompound * pCompoundValue =
                        DYNAMIC_DOWNCAST(
                              CExtPropertyValueCompound,
                              pParentItem
                              );
                  if( pCompoundValue != NULL )
                  {
                        CExtSafeString strCompoundValue =
                              pCompoundValue->BuildCompoundTextActive();
                        pCompoundValue->ValueActiveGet()->TextSet(
                              strCompoundValue.IsEmpty() ? _T("") : LPCTSTR(strCompoundValue)
                              );
                        HTREEITEM htiCompound =
                              PropertyItemToTreeItem(
                                    pCompoundValue
                                    );
                        if( htiCompound != NULL )
                        {
                              pCellSrc =
                                    ItemGetCell(
                                          htiCompound,
                                          1
                                          );
                              ASSERT_VALID( pCellSrc );
                              pCellSrc->TextSet( strCompoundValue );
                              bSyncGrids = true;
                        } // if( htiCompound != NULL )
                        pCompoundValue->SynchronizeCompoundParentPathActive();
                  } // if( pCompoundValue != NULL )
                  CExtPropertyValueMixedCompound * pMixedCompound =
                        DYNAMIC_DOWNCAST(
                              CExtPropertyValueMixedCompound,
                              pParentItem
                              );
                  if( pMixedCompound != NULL )
                  {
                        INT nMixedIndex, nMixedCount = pMixedCompound->ItemGetCount();
                        for( nMixedIndex = 0; nMixedIndex < nMixedCount; nMixedIndex ++ )
                        {
                              CExtPropertyItem * pMixedPart =
                                    pMixedCompound->ItemGetAt( nMixedIndex );
                              ASSERT_VALID( pMixedPart );
                              CExtPropertyValueCompound * pCompoundValue =
                                    STATIC_DOWNCAST(
                                          CExtPropertyValueCompound,
                                          pMixedPart
                                          );
                              CExtSafeString strCompoundValue =
                                    pCompoundValue->BuildCompoundTextActive();
                              pCompoundValue->ValueActiveGet()->TextSet(
                                    strCompoundValue.IsEmpty() ? _T("") : LPCTSTR(strCompoundValue)
                                    );
                              pCompoundValue->SynchronizeCompoundParentPathActive();
                        } // for( nMixedIndex = 0; nMixedIndex < nMixedCount; nMixedIndex ++ )
                        HTREEITEM htiCompound =
                              PropertyItemToTreeItem(
                                    pMixedCompound
                                    );
                        if( htiCompound != NULL )
                        {
                              pCellSrc =
                                    ItemGetCell(
                                          htiCompound,
                                          1
                                          );
                              ASSERT_VALID( pCellSrc );
                              CExtSafeString strCompoundValue =
                                    pMixedCompound->BuildCompoundTextActive();
                              pCellSrc->TextSet( strCompoundValue );
                              bSyncGrids = true;
                        } // if( htiCompound != NULL )
                        //pMixedCompound->SynchronizeCompoundParentPathActive();
                  } // if( pMixedCompound != NULL )
                  if( bSyncGrids )
                  {
                        ASSERT_VALID( pCellSrc );
                        for( nGridIdx = 0; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
                        {
                              CExtPropertyGridWnd * pGrid = arrGrids[ nGridIdx ];
                              ASSERT_VALID( pGrid );
                              HTREEITEM htiOther =
                                    pGrid->PropertyItemToTreeItem(
                                          pParentItem
                                          );
                              if( htiOther == NULL )
                                    continue;
                              CExtGridCell * pCellOther =
                                    pGrid->ItemGetCell( htiOther, 1 );
                              if( pCellOther == NULL )
                                    continue;
                              ASSERT_VALID( pCellOther );
                              if( LPVOID(pCellOther) != LPVOID(pCellSrc) )
                                    pCellOther->Assign( *pCellSrc );
                              pCellOther->ModifyStyleEx( 0, __EGCS_EX_UNDEFINED_ROLE );
                              if( pParentItem->IsKindOf(RUNTIME_CLASS(CExtPropertyValueMixed)) )
                              {
                                    if( pParentItem->ChildrenHaveDifferentActiveValues() )
                                          pCellOther->ModifyStyleEx( __EGCS_EX_UNDEFINED_ROLE );
                                    else
                                          pCellOther->ModifyStyleEx( 0, __EGCS_EX_UNDEFINED_ROLE );
                              } // if( pParentItem->IsKindOf(RUNTIME_CLASS(CExtPropertyValueMixed)) )
                              if( (pGrid->GetStyle()&WS_VISIBLE) == 0 )
                                    continue;
                              LONG nRowNo = pGrid->ItemGetVisibleIndexOf( htiOther );
                              if( nRowNo < 0 )
                                    continue;
                              CRect rc;
                              if(   pGrid->GridCellRectsGet(
                                          1,
                                          nRowNo,
                                          0,
                                          0,
                                          NULL,
                                          &rc
                                          )
                                    )
                              {
                                    CRect rcClient;
                                    pGrid->GetClientRect( &rcClient );
                                    rc.left = rcClient.left;
                                    rc.right = rcClient.right;
                                    pGrid->InvalidateRect( &rc );
                              }
                        } // for( nGridIdx = 0; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
                  } // if( bSyncGrids )
                  pParentItem =
                        pParentItem->ItemParentGet();
            } // for( ; pParentItem != NULL; )
      } // if( pPGC != NULL )
CRect rc;
      if(   GridCellRectsGet(
                  nColNo,
                  nRowNo,
                  nColType,
                  nRowType,
                  NULL,
                  &rc
                  )
            )
      {
            CRect rcClient;
            GetClientRect( &rcClient );
            rc.left = rcClient.left;
            rc.right = rcClient.right;
            InvalidateRect( &rc );
      }
      if( pPGC != NULL )
            pPGC->OnPgcInputComplete(
                  this,
                  pPropertyItem
                  );
}

Constantine Zzz Sep 18, 2007 - 7:34 PM

All classes created as usual.

Except GridCellUpDown->Apply();
piece of Apply:

...
    CExtGridCellUpDownFC *pV = STATIC_DOWNCAST(CExtGridCellUpDownFC, ( pValue == NULL ) ? ValueActiveGet() : pValue );

    CString t;
    pV->TextGet(t);
    int i = _wtoi(t);

    if (i>0 && i != m_pL->GetFishkaCount())
    {
        m_pL->SetFishkaCount(i);
        
        CExtPropertyCategory * pCategory = (CExtPropertyCategory*)m_pL->GetPropertyStore()->ItemGetByName(_T("Fishki"));
        VERIFY( pCategory->ItemInsert( new CLevel_FishkaID(m_pL, i)) );
    }

...

This code works. But you can’t see changes, while PropertyGridCtrl->PropertyStoreSet(...) is called. So I decided, we need to udate PropertyGridCtrl some how. But how I don’t know. Use PGC->PropertyStoreSynchronize() inside Apply is illegal, I think. Any way program crashes.
May be there is other ways to solve this problem?

In eperiment I update PGC on timer,
    if (m_PGC_needToBeSynced)
    {
        m_PGC.PropertyStoreSynchronize();
        m_PGC_needToBeSynced = false;
    }

but it leeds to unexpected results and even crashes, anyway(bad idea, I think).

Technical Support Sep 18, 2007 - 11:46 AM

Although the property grid control supports store synchronization when handling the value changing event, this approach is assumed as non-standard usage of this control behind its design. Is it possible to get a test project from you which demonstrates the crash?