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 Tech Support » Problem with CExtPropertyGridComboBoxBar Collapse All
Subject Author Date
Krustys Donuts Jul 11, 2005 - 12:10 PM

Hi, I’m trying to play with CExtPropertyGridCtrl, and am currently trying to populate the comboboxbar with property stores. If I don’t insert any property values into the property category, everything is fine (but of course nothing appears in the property grid). If I then add values with the following code, my application crashes:

CExtPropertyGridComboBoxBar * pCombo = STATIC_DOWNCAST( CExtPropertyGridComboBoxBar, 
					grid.GetChildByRTC( RUNTIME_CLASS(CExtPropertyGridComboBoxBar)) );
ASSERT_VALID( pCombo );
// stores[] is of type CExtPropertyStore
for( int i=0; i<NumSides; i++) {
    stores[i].NameSet( sideNames[i]);
    CExtPropertyCategory * pCategoryField = new CExtPropertyCategory( _T("Field") );
    pCategoryField->DescriptionSet( _T("Field properties") );
    VERIFY( stores[i].ItemInsert( pCategoryField) );
    pCategoryField->ItemInsert( new CExtPropertyValue( "foo"));
    pCategoryField->ItemInsert( new CExtPropertyValue( "bar"));
		pCombo->PropertyStoreInsert( &stores[i]);
}


I pulled this code from the propertygridctrl example, except for a change to these lines:

    pCategoryField->ItemInsert( new CExtPropertyValue( "foo"));
    pCategoryField->ItemInsert( new CExtPropertyValue( "bar"));


These lines are basically the same as the example, except that I’m just using passing in the base class. When my application crashes, the call stack looks like this:

msvcr71d.dll!__crtMessageBoxA(const char * lpText=0x0012a88c, const char * lpCaption=0x00388444, unsigned int uType=73746)  Line 119	C
msvcr71d.dll!CrtMessageWindow(int nRptType=2, const char * szFile=0x1073f214, const char * szLine=0x0012b8d0, const char * szModule=0x00000000, const char * szUserMessage=0x0012b8f0)  Line 617 + 0x16	C
msvcr71d.dll!_CrtDbgReport(int nRptType=2, const char * szFile=0x1073f214, int nLine=1561, const char * szModule=0x00000000, const char * szFormat=0x00000000, ...)  Line 516 + 0x4c	C
mfc71d.dll!AfxAssertFailedLine(const char * lpszFileName=0x1073f214, int nLine=1561)  Line 28 + 0x14	C++
mfc71d.dll!AfxAssertValidObject(const CObject * pOb=0x00000000, const char * lpszFileName=0x1073f214, int nLine=1561)  Line 74 + 0xd	C++
ProfUIS240md.dll!CExtPropertyGridCellArea::OnQueryCellFont(const CExtGridWnd & wndGrid={...}, long nVisibleColNo=0, long nVisibleRowNo=1, long nColNo=0, long nRowNo=1, int nColType=0, int nRowType=0, unsigned long dwAreaFlags=512)  Line 1563	C++
ProfUIS240md.dll!CExtGridCell::OnPaintText(const tagRECT & rcCellText={...}, const CExtGridWnd & wndGrid={...}, CDC & dc={...}, long nVisibleColNo=0, long nVisibleRowNo=1, long nColNo=0, long nRowNo=1, int nColType=0, int nRowType=0, const tagRECT & rcCellExtra={...}, const tagRECT & rcCell={...}, const tagRECT & rcVisibleRange={...}, unsigned long dwAreaFlags=512, unsigned long dwHelperPaintFlags=0)  Line 14666 + 0x2d	C++
ProfUIS240md.dll!CExtGridCell::OnPaintForeground(const CExtGridWnd & wndGrid={...}, CDC & dc={...}, long nVisibleColNo=0, long nVisibleRowNo=1, long nColNo=0, long nRowNo=1, int nColType=0, int nRowType=0, const tagRECT & rcCellExtra={...}, const tagRECT & rcCell={...}, const tagRECT & rcVisibleRange={...}, unsigned long dwAreaFlags=512, unsigned long dwHelperPaintFlags=0)  Line 14061 + 0x45	C++
ProfUIS240md.dll!CExtGridWnd::OnGbwPaintCell(CDC & dc={...}, long nVisibleColNo=0, long nVisibleRowNo=1, long nColNo=0, long nRowNo=1, const tagRECT & rcCellExtra={...}, const tagRECT & rcCell={...}, const tagRECT & rcVisibleRange={...}, unsigned long dwAreaFlags=512, unsigned long dwHelperPaintFlags=0)  Line 30971 + 0x41	C++
ProfUIS240md.dll!CExtTreeGridWnd::OnGbwPaintCell(CDC & dc={...}, long nVisibleColNo=0, long nVisibleRowNo=1, long nColNo=0, long nRowNo=1, const tagRECT & rcCellExtra={...}, const tagRECT & rcCell={...}, const tagRECT & rcVisibleRange={...}, unsigned long dwAreaFlags=512, unsigned long dwHelperPaintFlags=0)  Line 2287	C++
ProfUIS240md.dll!CExtGridBaseWnd::OnSiwWalkCell(CDC & dc={...}, void * pQueryData=0x00000000, long nVisibleColNo=0, long nVisibleRowNo=1, long nColNo=0, long nRowNo=1, const tagRECT & rcCellExtra={...}, const tagRECT & rcCell={...}, const tagRECT & rcVisibleRange={...}, bool & bVirtualRightReached=false, bool & bVirtualBottomReached=false, unsigned long dwAreaFlags=512, bool bFocusedControl=false)  Line 4033 + 0x38	C++
ProfUIS240md.dll!CExtGridBaseWnd::OnSiwWalkItemsH(CDC & dc={...}, void * pQueryData=0x00000000, const tagRECT & rcRowExtra={...}, const tagRECT & rcRow={...}, long nVisibleRowNo=1, long nRowNo=1, const tagRECT & rcVisibleRange={...}, bool & bVirtualBottomReached=false, unsigned long dwAreaFlags=512, bool bFocusedControl=false)  Line 4179 + 0x4a	C++
ProfUIS240md.dll!CExtGridBaseWnd::OnGbwWalkVisibleAreas(CDC & dc={...}, bool bFocusedControl=false, CExtGridHitTestInfo * pHT=0x00000000)  Line 2837 + 0x48	C++
ProfUIS240md.dll!CExtGridBaseWnd::OnSiwPaintForeground(CDC & dc={...}, bool bFocusedControl=false)  Line 1979 + 0x1a	C++
ProfUIS240md.dll!CExtScrollItemWnd::OnSwPaint(CDC & dc={...})  Line 3458 + 0x18	C++
ProfUIS240md.dll!CExtScrollWnd::OnPaint()  Line 1754 + 0x17	C++
mfc71d.dll!CWnd::OnWndMsg(unsigned int message=15, unsigned int wParam=0, long lParam=0, long * pResult=0x0012f80c)  Line 2023	C++
mfc71d.dll!CWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0)  Line 1745 + 0x1e	C++
ProfUIS240md.dll!CExtGridBaseWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0)  Line 10150	C++
mfc71d.dll!AfxCallWndProc(CWnd * pWnd=0x003bbfe0, HWND__ * hWnd=0x00190692, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 241 + 0x1a	C++
mfc71d.dll!AfxWndProc(HWND__ * hWnd=0x00190692, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 389	C++
mfc71d.dll!AfxWndProcBase(HWND__ * hWnd=0x00190692, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 209 + 0x15	C++
user32.dll!_InternalCallWinProc@20()  + 0x28	
user32.dll!_UserCallWinProcCheckWow@32()  + 0xb7	
user32.dll!_DispatchClientMessage@20()  + 0x4d	
user32.dll!___fnDWORD@4()  + 0x24	
ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x13	
user32.dll!_NtUserCallHwndLock@8()  + 0xc	
user32.dll!_InternalCreateDialog@28()  + 0x130d	
user32.dll!_CreateDialogIndirectParamAorW@24()  + 0x33	
user32.dll!_CreateDialogIndirectParamA@20()  + 0x1b	
mfc71d.dll!CWnd::CreateDlgIndirect(const DLGTEMPLATE * lpDialogTemplate=0x00439ab0, CWnd * pParentWnd=0x00000000, HINSTANCE__ * hInst=0x00400000)  Line 310 + 0x2a	C++
mfc71d.dll!CDialog::DoModal()  Line 519 + 0x20	C++


Thanks!

Technical Support Jul 11, 2005 - 12:45 PM

Your code instantiates two property values as child items inside a category. Each property value stores two CExtGridCell objects which assumed to be the default and active values of the property. You simply forgot to initialize the CExtGridCell objects and attach them to each CExtPropertyValue instance. It is not difficult to improve your code. Please replace

pCategoryField->ItemInsert(new CExtPropertyValue( "foo"));
with
CExtPropertyValue * pValue =
        new CExtPropertyValue( "foo")
CExtGridCellComboBox * pGridCell =
        STATIC_DOWNCAST(
            CExtGridCellComboBox,
            pValue->ValueActiveGetByRTC(
                RUNTIME_CLASS(CExtGridCellComboBox)
                )
            );
    ASSERT_VALID( pGridCell );
    pGridCell->InsertString( _T("None"),   0 );
    pGridCell->InsertString( _T("Slow"),   1 );
    pGridCell->InsertString( _T("Middle"), 2 );
    pGridCell->InsertString( _T("Fast"),   3 );
    pGridCell->SetEnumMode();
    // pGridCell->SetCurSel( ... );
    pValue->ValueDefaultFromActive();
    pCategoryField->ItemInsert( pValue );
Of course, you should do the same for the second property value in your code.

Krustys Donuts Jul 11, 2005 - 3:40 PM

Fantastic! That solved everything, thank you.

Krustys Donuts Jul 12, 2005 - 12:34 AM

Ok, so it worked, but not the way I wanted it to. I need my UI to update based on the item selected from the combobox. To try to fix this, I subclassed CExtGridCellComboBox and overrode OnInplaceControlTextInputComplete, but it never got called. I then looked at the grid sample, and saw that the combobox needs to be contained by a CExtPropertyValue. I proceeded to change my previous combobox class to look like this:

class CLabelPropertySource : public CExtPropertyValue
{
    DECLARE_DYNCREATE(CLabelPropertySource)
public:
    CLabelPropertySource();
    virtual ~CLabelPropertySource();
    virtual void Apply( CExtGridCell* pValue);
};


and the implementation looks like this:

IMPLEMENT_DYNCREATE( CLabelPropertySource, CExtPropertyValue)
CLabelPropertySource::CLabelPropertySource()
: CExtPropertyValue( "Source")
{
    DescriptionSet( "Specifies source" );
    CExtGridCellComboBox* pValue = STATIC_DOWNCAST( CExtGridCellComboBox, ValueGetByRTC( RUNTIME_CLASS(CExtGridCellComboBox)));
    ASSERT_VALID( pValue );
    pValue->InsertString( "Source A", 0);
    pValue->InsertString( "Source B", 1);
    pValue->InsertString( "Source C", 2);
    pValue->InsertString( "Source D", 3);
    pValue->SetEnumMode();
}

CLabelPropertySource::~CLabelPropertySource()
{
}

void CLabelPropertySource::Apply( CExtGridCell* pValue)
{
    ASSERT_VALID( this );
    ASSERT_VALID( pValue );
    ASSERT_KINDOF( CExtGridCellComboBox, pValue );
    CExtPropertyValue::Apply( pValue );
    CExtGridCellComboBox * pValueComboBox = STATIC_DOWNCAST( CExtGridCellComboBox, pValue);
}


The code is pretty much copied straight from the sample. The problem is the ValueGetByRTC macro (is it a macro?). The sample compiles with this line, but my code doesn’t. I checked the docs, and I can only see ValueDefaultGetByRTC in the base class (CExtPropertyItem), but that crashes when I run.

Thanks for any help you can provide me!

Krustys Donuts Jul 12, 2005 - 10:39 AM

Hi, sorry, I was looking at an old sample from 2.33... I was supposed to use ValueActiveGetByRTC.

Technical Support Jul 12, 2005 - 12:35 PM

The design of property classes was changed in the Prof-UIS 2.40 major release. Please use the latest source code to avoid misunderstanding. If you are going to use your own classes derived from CExtGridCell or CExtGridCellComboBox, make sure that you dd not forget to use the IMPLEMENT_ExtGridCell_Clone pre-processor macro in the class declaration. The methods of the CExtPropertyItem class for operating with default and active cell objects were introduced in 2.40, including cell object initialization by its Run Time Class (RTC). The 2.33 version of the property value supports only one cell object and, as a result, the old property grid does not perform "Reset" operation for property values and does not display the context menu.