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 » CExtPropertyGridCtrl question Collapse All
Subject Author Date
Offer Har Nov 14, 2006 - 4:34 PM

Hi,

I have a dialog with a CExtPropertyGridCtrl.
The CExtPropertyGridCtrl is hooked to the width of the dialog.
When the dialog is resizing, both columns width changes.
I would like the first column to stay at the same width, and only the width of the second column to absorb the width changes.
Thanks.

Offer Har Dec 18, 2006 - 8:21 PM

Dear Support,

Is there any chance to get a sample application of this simple request?
I could not understand you last few reply, please try and help me on this one.

Regards,
Ron.

Suhai Gyorgy Nov 16, 2006 - 7:17 AM

What you might need is CExtPropertyGridWnd::SetProportionalColumnWidth. If you handle the WM_SIZE message of the dialog, you can somehow measure what percent of the whole grid width should the first column occupy and you can set that new value in SetProportionalColumnWidth. However, I haven’t tried it myself, just a guess.

Offer Har Nov 16, 2006 - 7:35 AM

What I need is the simplest thing, which is available in all grids i worked with, and this is that a column width is fixed... not a percentage calculation, but a fixed width.

Technical Support Nov 17, 2006 - 8:10 AM

We believe the current implementation of how columns are resized is reasonably convenient. If you need to disable column resizing in the tree grid windows inside the property grid control, you should override the CExtPropertyGridCtrl::OnPgcCreateGrids() virtual method. Your method should be the same as the original one but you need to create your CExtPropertyGridWndCategorized-derived and CExtPropertyGridWndSorted-derived tree grid windows. Both of the tree grid windows should have the following internal virtual method:

virtual void _DoColumnLayout( const CRect & ) { }

Offer Har Jan 24, 2007 - 7:26 PM

Dear Support,

I have finally got around to this bug again, and found the problem.
You suggested to derive from CExtPropertyGridWndCategorized and over-ride the function _DoColumnLayout so that it will do nothing.

This does not work.
If i just derive my class, and do not add the _DoColumnLayout over-riding, all is well, but when i add the function, the application crash as i described before.

The bottom line is that your suggestion does not work.
Please supply me an alternative solution.

Regards,
Ron.

Technical Support Jan 29, 2007 - 12:45 PM


You don’t have to override the CExtPropertyGridCtrl::_DoColumnLayout() virtual method at all. If you need a property grid control with non-resizable columns, you should simply remove the __EGBS_RESIZING_CELLS_INNER_H|__EGBS_DYNAMIC_RESIZING_H basic grid styles from the tree grid windows in the property grid control as we advised before. We added the following virtual to the declaration of the CCanvasPropertyGridCtrl class in the CompoundProperties sample and got the property grid like you need:

    virtual bool OnPgcCreateGrids()
    {
        if( ! CExtPropertyGridCtrl::OnPgcCreateGrids() )
            return false;
        CTypedPtrArray < CPtrArray, CExtPropertyGridWnd * > arrGrids;
        OnPgcQueryGrids( arrGrids );
        INT nGridIdx, nGridCount = INT(arrGrids.GetSize());
        for( nGridIdx = 0; nGridIdx < nGridCount; nGridIdx ++ )
        {
            CExtPropertyGridWnd * pGrid = arrGrids[ nGridIdx ];
            ASSERT_VALID( pGrid );
            pGrid->SiwModifyStyle(
                0,
                __EGBS_RESIZING_CELLS_INNER_H|__EGBS_DYNAMIC_RESIZING_H
                );
        }
        return true;
    }

Offer Har Jan 29, 2007 - 1:05 PM

Dear Support,

This is not the issue.
The issue in this thread is how to prevent column resizing automatcialy when the dialog size changes.

I tried adding
pGrid->SiwModifyStyle(0, __EGBS_RESIZING_CELLS_INNER_V|__EGBS_DYNAMIC_RESIZING_V);
As well, but still, when you resize the dialog, and the property grid’s size changes, so does the width of the two columns.

I want the left column to have a fixed size (i know what is its content, so there is no need to resize it, let me set its size myself), and the second column will get the rest of control’s width.

In a normal grid, this is very simple, but here for some reason it’s complicated. You suggested to over-ride the _DoColumnLayout(), in which i should do my own handling of the columns layout, but if you’ll try it yourself (as i did) this crashes the application deep inside Prof-UIS code.

Please let me know of an alternative solution.

Regards,
Ron.

Technical Support Jan 30, 2007 - 12:15 PM

The _DoColumnLayout() method is responsible both for automatic proportional column resizing and for automatic column width synchronization between all the tree grid windows inserted into the property grid control. We can implement an improved version of the _DoColumnLayout() method which does not resize the first column and even allow tree grids be scrollable horizontally, but we do not see any reason for this. Typically the user sets up all the resizable windows in some handy layout and forgets about resizing after that. I.e. all the data in the property grid control will be persistently available and visible and as result, there should not be any reason to change the standard behavior of the property grid control.

Offer Har Jan 30, 2007 - 12:51 PM

I categorically disagree with you.
The user usually does not want to mess his hands with resizing columns, unless it’s a very complicated grid like excel sheet.
We are talking about a simple property grid, in which the left column’s size never changes, because the texts in it are known in advance, and the user cannot edit them (this is usually the case in any property grid).

This is the reason why we can set the width of the left column in the code, and tell the user decide if he needs space for the right column only, according to what he type in it. We don’t care about horizontal scroll, all we want is to make the width of the first column fixed according to what we set in the code.

In any case, you state that you can do it, so please do so, or let me know what to do in order to achieve this behavior.

Best Regards,
Ron.

Technical Support Feb 1, 2007 - 4:46 AM

Here is a version of the CExtPropertyGridWnd::_DoColumnLayout() method that does not resize tree grid columns when the size of the property grid control changes. Please let us know if it is what you mean?

void _DoColumnLayout(
    const CRect & rcClient
    )
{
    ASSERT_VALID( this );
int nColCount = ColumnCountGet();
    if( nColCount == 0 )
        return;
INT nAvailExtent = rcClient.Width();
    if( nAvailExtent < 0 )
        nAvailExtent = 0;
INT        i, nSummaryExtentCurrent = 0, nNumberToProcess = 0,
        nSummaryExtentMin = 0, nSummaryExtentMax = 0;
    for( i = 0; i < nColCount; i++ )
    {
        CExtGridCell * pHeaderCell =
            GridCellGetOuterAtTop( i, 0 );
        ASSERT_VALID( pHeaderCell );
        INT nExtentCurrent, nExtentMin, nExtentMax;
        pHeaderCell->ExtentGet( nExtentCurrent, 0 );
        pHeaderCell->ExtentGet( nExtentMin, -1 );
        pHeaderCell->ExtentGet( nExtentMax, 1 );
        if( i == 0 && m_nConstantIndent >= 0 )
        {
            ASSERT( nExtentMax > m_nConstantIndent );
            if( nExtentMin > m_nConstantIndent )
            {
                nExtentMin = m_nTrackExtentCurrent;
                pHeaderCell->ExtentSet( nExtentMin, -1 );
            }
            if( nExtentCurrent < m_nConstantIndent )
            {
                nExtentCurrent = m_nConstantIndent;
                pHeaderCell->ExtentSet( nExtentCurrent, 0 );
            }
        }
        nSummaryExtentCurrent += nExtentCurrent;
        nSummaryExtentMin += nExtentMin;
        nSummaryExtentMax += nExtentMax;
        if( nExtentMin != nExtentMax )
            nNumberToProcess ++;
    }
    if(     nSummaryExtentCurrent == nAvailExtent
        ||  nNumberToProcess == 0
        )
        return;
INT nSpaceRequest = nAvailExtent - nSummaryExtentCurrent;
INT nAdvance = ( nSpaceRequest > 0 ) ? 1 : (-1);
    if( nAdvance < 0 )
    {
        if( nSummaryExtentCurrent == nSummaryExtentMin )
            return;
    }
    else
    {
        if( nSummaryExtentCurrent == nSummaryExtentMax )
            return;
    }
    for( ; true; )
    {
        nNumberToProcess = 0;
        for( i = 1; i < nColCount; i++ )
        {
            if( nSpaceRequest == 0 )
                break;
            CExtGridCell * pHeaderCell =
                GridCellGetOuterAtTop( i, 0 );
            ASSERT_VALID( pHeaderCell );
            INT nExtentCurrent, nExtentMin, nExtentMax;
            pHeaderCell->ExtentGet( nExtentCurrent, 0 );
            pHeaderCell->ExtentGet( nExtentMin, -1 );
            pHeaderCell->ExtentGet( nExtentMax, 1 );
            if(     nExtentMin == nExtentMax
                ||  (    nAdvance < 0
                    &&    nExtentCurrent == nExtentMin
                    )
                ||  (    nAdvance > 0
                    &&    nExtentCurrent == nExtentMax
                    )
                )
                continue;
            nNumberToProcess ++;
            if( nAdvance < 0 )
            {
                pHeaderCell->ExtentSet( nExtentCurrent-1, 0 );
                nSpaceRequest++;
            }
            else
            {
                pHeaderCell->ExtentSet( nExtentCurrent+1, 0 );
                nSpaceRequest--;
            }
        }
        if( nNumberToProcess == 0 )
            break;
        if( nSpaceRequest == 0 )
            break;
    }
}

Offer Har Nov 17, 2006 - 9:39 AM

Dear support.

I do not understand what to do. Please elaborate.
What i want is that the first column width will be fixed when the control size changes, and the second one will fill the extra space, and vice versa with the width gets narrower.

Isn’t there a command like SetColumnWidth(int, int) that I specify the column’s index and width? it looks as a simple request...

Thanks.

Technical Support Nov 17, 2006 - 1:32 PM

The tree grid windows inside the property grid control are resizing the columns proportionally and column width are synchonized between grids if you are resizing a column in one of them. There are no API to change this behavior. If you need to change it like described in your message, try the following CExtPropertyGridCtrl-derived class:

class CYourPropertyGridCtrl : public CExtPropertyGridCtrl
{
public:
    class CYourPropertyGridWndCategorized
        : public CExtPropertyGridWndCategorized
    {
    protected:
        virtual void _DoColumnLayout(
            const CRect & rcClient
            )
        {
            rcClient;
        }
    };
    class CYourPropertyGridWndSorted
        : public CExtPropertyGridWndSorted
    {
    protected:
        virtual void _DoColumnLayout(
            const CRect & rcClient
            )
        {
            rcClient;
        }
    };
    bool OnPgcCreateGrids()
    {
        ASSERT_VALID( this );
        try
        {
            CYourPropertyGridWndCategorized * pGridCategorized =
                new CYourPropertyGridWndCategorized( this );
            pGridCategorized->m_bAutoDeleteWindow = true;
            if( ! pGridCategorized->Create(
                    this,
                    __EXT_MFC_ID_PROPERTY_GRID_CATEGORIZED,
                    true
                    )
                )
            {
                ASSERT( FALSE );
                throw __EXT_MFC_ID_PROPERTY_GRID_CATEGORIZED;
            }
            CYourPropertyGridWndSorted * pGridSorted =
                new CYourPropertyGridWndSorted( this );
            pGridSorted->m_bAutoDeleteWindow = true;
            if( ! pGridSorted->Create(
                    this,
                    __EXT_MFC_ID_PROPERTY_GRID_SORTED
                    )
                )
            {
                ASSERT( FALSE );
                throw __EXT_MFC_ID_PROPERTY_GRID_SORTED;
            }
        }
        catch( ... )
        {
            return false;
        }
        return true;
    }
};

Offer Har Nov 17, 2006 - 1:59 PM

I have added your code, and the application crashes when going to draw the propery grid in an assert,
The assert is line in line 4170

Also, i needed to add constructors to your code.
If possible, please send me a working example.

This is the stack:

>    ProfUIS262md.dll!CExtGridBaseWnd::OnSiwWalkCell(CDC & dc={...}, void * pQueryData=0x00000000, long nVisibleColNo=1, long nVisibleRowNo=0, long nColNo=1, long nRowNo=0, const tagRECT & rcCellExtra={...}, const tagRECT & rcCell={...}, const tagRECT & rcVisibleRange={...}, bool & bVirtualRightReached=false, bool & bVirtualBottomReached=false, unsigned long dwAreaFlags=512, bool bFocusedControl=false) Line 4170 + 0x1c    C++
    ProfUIS262md.dll!CExtGridBaseWnd::OnSiwWalkItemsH(CDC & dc={...}, void * pQueryData=0x00000000, const tagRECT & rcRowExtra={...}, const tagRECT & rcRow={...}, long nVisibleRowNo=0, long nRowNo=0, const tagRECT & rcVisibleRange={...}, bool & bVirtualBottomReached=false, unsigned long dwAreaFlags=512, bool bFocusedControl=false) Line 4578 + 0x4a    C++
    ProfUIS262md.dll!CExtGridBaseWnd::OnGbwWalkVisibleAreas(CDC & dc={...}, bool bFocusedControl=false, CExtGridHitTestInfo * pHT=0x00000000) Line 3165 + 0x48    C++
    ProfUIS262md.dll!CExtGridBaseWnd::OnSiwPaintForeground(CDC & dc={...}, bool bFocusedControl=false) Line 2295 + 0x1a    C++
    ProfUIS262md.dll!CExtScrollItemWnd::OnSwPaint(CDC & dc={...}) Line 5062 + 0x18    C++
    ProfUIS262md.dll!CExtScrollWnd::OnPaint() Line 3283 + 0x17    C++
    mfc71d.dll!CWnd::OnWndMsg(unsigned int message=15, unsigned int wParam=0, long lParam=0, long * pResult=0x00128f5c) Line 2023    C++
    mfc71d.dll!CWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0) Line 1745 + 0x1e    C++
    ProfUIS262md.dll!CExtPropertyGridWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0) Line 4252    C++
    mfc71d.dll!AfxCallWndProc(CWnd * pWnd=0x03958aa8, HWND__ * hWnd=0x00022118, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0) Line 241 + 0x1a    C++
    mfc71d.dll!AfxWndProc(HWND__ * hWnd=0x00022118, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0) Line 389    C++
    mfc71d.dll!AfxWndProcBase(HWND__ * hWnd=0x00022118, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0) Line 209 + 0x15    C++

Technical Support Nov 20, 2006 - 12:25 PM

Could you modify any of our sample applications with the grid window inside to reproduce this crash?

Offer Har Nov 20, 2006 - 12:30 PM

1. Can you please explain what is all the OnSiwWalkCell code, and why this assert happens.
2. It is very hard to backtrack to old threads.. is there a way to put more then 20 posts in each page? i have to browse 5 pages to find this post...

I will appreciate if you will sending me a modified sample with this feature/code in it, and then i will be able to find what I’m doing wrong, and may assist other users with this problem, as i’m sure i’m not the only one requiring this option.

Thanks a lot.

Technical Support Nov 21, 2006 - 11:14 AM

The CExtScrollItemWnd::OnSiwWalkCell() virtual method is part of a set of virtual methods in the CExtScrollItemWnd class which are designed for traversing all the visible cells:

virtual bool OnSiwVirtualEndTestH( LONG nColNo, LPARAM lParam ) const;
virtual bool OnSiwVirtualEndTestV( LONG nRowNo, LPARAM lParam ) const;
virtual bool OnSiwWalkCell(
    CDC & dc,
    LPVOID pQueryData,
    LONG nVisibleColNo,
    LONG nVisibleRowNo,
    LONG nColNo,
    LONG nRowNo,
    const RECT & rcCellExtra,
    const RECT & rcCell,
    const RECT & rcVisibleRange,
    bool & bVirtualRightReached,
    bool & bVirtualBottomReached,
    DWORD dwAreaFlags,
    bool bFocusedControl
    ) const;
virtual bool OnSiwWalkItemsH(
    CDC & dc,
    LPVOID pQueryData,
    const RECT & rcRowExtra,
    const RECT & rcRow,
    LONG nVisibleRowNo,
    LONG nRowNo,
    const RECT & rcVisibleRange,
    bool & bVirtualBottomReached,
    DWORD dwAreaFlags,
    bool bFocusedControl
    ) const;
virtual bool OnSiwWalkItemsV(
    CDC & dc,
    LPVOID pQueryData,
    const RECT & rcColExtra,
    const RECT & rcCol,
    LONG nVisibleColNo,
    LONG nColNo,
    const RECT & rcVisibleRange,
    bool & bVirtualRightReached,
    DWORD dwAreaFlags,
    bool bFocusedControl
       ) const;
This subsystem is used by the grid windows for painting and hit testing. You should not face any assertions in these methods. We believe it is possible to find the source of the problem in your project if you try excluding those parts of the code that relate to the grid initialization.

Offer Har Nov 21, 2006 - 12:49 PM

It’s impossible for me to strip down the class, and run the grid as a stand alone project
Please let me know what parts you think are problematic.
The other and more preferable way is for you to send me a simple working example, as you must have many samples and test application of these kind of features.

Technical Support Nov 23, 2006 - 9:59 AM

You need only the following branch of classes:

CExtScrollWnd --> CExtScrollItemWnd --> CExtGridBaseWnd --> CExtGridWnd
These classes are located in the ExtScrollWnd.h/.cpp and ExtGridWnd.h/.cpp files only. All the data provider classes and grid cell classes are also in these files only. You can put them into a test project, remove all the __PROF_UIS_API macros in class declarations and comment out several pieces of code where the paint manage is invoked including CExtPmBridge-related code.

Offer Har Nov 23, 2006 - 11:52 AM

I don’t understand your reply.
Maybe you posted in the wrong thread?

I am still waiting for a sample application...

Thanks.