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 do I create a CExtButton inside a CExtGridCellProgress? Collapse All
Subject Author Date
Scott Moore Nov 20, 2006 - 7:31 AM

Basically I have a grid which holds some data. While this data is being worked on, I display a progress bar in one of the cells. What I would like to do is provide the user a way to cancel the operation by clicking a small red button (like an X, not an ellipse) to the right of the progress bar, but inside the same cell.

Scott Moore Nov 28, 2006 - 1:42 PM

Okay, I figured out why the button never gets pressed. I removed the __EGCS_READ_ONLY style.

Why does my button callback still get called when I click elsewhere in the cell?

Technical Support Nov 29, 2006 - 1:12 PM

We agree with you. Thank you for your comment. Please open the CExtGridWnd::OnGbwBeginEdit() method and remove the following code snippet:

if( (dwCellStyle&__EGCS_BUTTON_ELLIPSIS) != 0 )
{
    bool bEnabled = false;
    if( pCellToEdit->OnQueryButtonInfo(
            INT(CExtGridCell::__EBTT_ELLIPSIS),
            &bEnabled
            )
        )
    {
        if( bEnabled )
        {
            pCellToEdit->OnButtonPressed(
                *this,
                INT(CExtGridCell::__EBTT_ELLIPSIS),
                rcCellExtra,
                rcCell,
                nVisibleColNo,
                nVisibleRowNo,
                nColNo,
                nRowNo,
                nColType,
                nRowType
                );
            return true;
        } // if( bEnabled )
    }
} // if( (dwCellStyle&__EGCS_BUTTON_ELLIPSIS) != 0 )

Scott Moore Nov 28, 2006 - 1:38 PM

Honestly, I’m not sure what is going on. OnButtonPressed() is NOT called when I click the button, only if I click elsewhere in the cell. This is the code I’m using to show progress:


int percent = 0; // modify in a timer for testing
    CCancelCellProgress * pCellProgress =
        STATIC_DOWNCAST(
            CCancelCellProgress,
            m_wndGrid.GridCellGet(
                GRID_COL_STATUS,
                rowNum,
                0,
                0,
                RUNTIME_CLASS(CCancelCellProgress)
                )
            );


    if (percent >= 0)
    {
        CString perc;
        perc.Format(L"%d%%", percent);

        pCellProgress->InvertBarGradientSet(true); // vertical gradient
        pCellProgress->BarColorsSet(RGB(0, 220, 0), RGB(90, 90, 90));
        pCellProgress->TextModeSet(CExtGridCellProgress::eTextAndPercent);
        pCellProgress->SetPos(percent);
        pCellProgress->ModifyStyle(__EGCS_NO_INPLACE_CONTROL|__EGCS_TA_HORZ_CENTER|__EGCS_BUTTON_ELLIPSIS);
    }
    else
    {
        pCellProgress->TextModeSet(CExtGridCellProgress::eText);
        pCellProgress->SetPos(0);
        pCellProgress->ModifyStyle(__EGCS_READ_ONLY|__EGCS_NO_INPLACE_CONTROL|__EGCS_TA_HORZ_CENTER);
        pCellProgress->ModifyStyle(0L, __EGCS_BUTTON_ELLIPSIS);
    }
    bool valid = true; // modify at will

    if (percent >= 0)
    {
        pCellProgress->TextColorSet(CExtGridCell::__ECS_ALL, RGB(0,0,0) );
    }
    else
    {
        pCellProgress->TextColorSet(CExtGridCell::__ECS_ALL, valid ? RGB(0,90,0): RGB(255,0,0) );
    }
    pCellProgress->TextSet("Working");



Some things that I’ve noticed while debugging.

1) My callstack when I click elsewhere in the cell (but not on the ellipse button) is:

>    ProfUIS261ud.dll!CExtGridWnd::OnGbwBeginEdit(long nVisibleColNo=3, long nVisibleRowNo=0, long nColNo=3, long nRowNo=0, int nColType=0, int nRowType=0, const tagRECT & rcCellExtra={...}, const tagRECT & rcCell={...}, const tagRECT & rcInplaceControl={...}, bool bContinueMsgLoop=true, const unsigned short * strStartEditText=0x00000000) Line 46840    C++
    ProfUIS261ud.dll!CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(unsigned int nChar=1, unsigned int nRepCnt=3, unsigned int nFlags=1, CPoint point={...}) Line 45497 + 0x60    C++
    ProfUIS261ud.dll!CExtGridBaseWnd::OnLButtonDown(unsigned int nFlags=1, CPoint point={...}) Line 8971 + 0x20    C++


However, when I put a breakpoint in CExtGridWnd::OnGbwBeginEdit(), it’s never called when I click the button.

Looking at your SimpleGrids project, in ExtGridWnd.cpp:45399 the call pCell->OnClick() returns true when the button is pressed in that project. In my project, it always returns false.


Scott Moore Nov 27, 2006 - 7:34 PM

Hmm, seems cut and paste didn’t work so well. Here it is again:

Now I have a new problem. I can’t seem to press the button. The button is enabled. And I overrode OnButtonPressed(). But it’s not called if I click the button. But it IS called if I click anywhere else in the cell, just not on the button itself.

Technical Support Nov 28, 2006 - 11:24 AM

Actually it is not clear why you need to use OnQueryButtonInfo() to enable the button. The button is enabled by default. As for the button pressed event, here is the code we used for testing and it works.

// DECLARATION
class CYourGridCellProgress : public CExtGridCellProgress
{
public:

    ….
    
    virtual void OnButtonPressed(
        CExtGridWnd & wndGrid,
        INT nButtonType,
        const RECT & rcCellExtra,
        const RECT & rcCell,
        LONG nVisibleColNo,
        LONG nVisibleRowNo,
        LONG nColNo,
        LONG nRowNo,
        INT nColType,
        INT nRowType
        );
    
}; // class CYourGridCellProgress


//IMPLEMENTATION:

void CYourGridCellProgress::OnButtonPressed(
    CExtGridWnd & wndGrid,
    INT nButtonType,
    const RECT & rcCellExtra,
    const RECT & rcCell,
    LONG nVisibleColNo,
    LONG nVisibleRowNo,
    LONG nColNo,
    LONG nRowNo,
    INT nColType,
    INT nRowType
    )
{
    ASSERT_VALID( this );
    ASSERT_VALID( (&wndGrid) );

    CExtGridCellProgress::OnButtonPressed(
        wndGrid,
        nButtonType,
        rcCellExtra,
        rcCell,
        nVisibleColNo,
        nVisibleRowNo,
        nColNo,
        nRowNo,
        nColType,
        nRowType
        );
    
    if( nButtonType == __EBTT_ELLIPSIS )
    {
        AfxMessageBox( _T("CYourGridCellProgress::OnButtonPressed") );
    }
}

Scott Moore Nov 27, 2006 - 7:32 PM

My email was incorrect in my profile, but I have since fixed it.

You must have missed my latest problem, so I will repost:

I canaˆ™t seem to press the button. The button is enabled. And I overrode OnButtonPressed(). But itaˆ™s not called if I click the button. But it IS called if I click anywhere else in the cell, just not on the button itself. Iaˆ™d kinda like the reverse to happen. :)

Scott Moore Nov 24, 2006 - 12:36 PM

Well, the fun never ends. OnQueryButtonInfo() works fine.

Now I have a new problem. I can’t seem to press the button. The button is enabled. And I overrode OnButtonPressed(). But it’s not called if I click the button. But it IS called if I click anywhere else in the cell, just not on the button itself.

I’d kinda like the reverse to happen. :)

Scott Moore Nov 24, 2006 - 12:10 PM

As a followup to #1, I looked at the header file and IsButtonEnabled() is not virtual.


I will try overriding OnQueryButtonInfo().

Scott Moore Nov 24, 2006 - 11:40 AM

Thanks for the quick response.

1) Did not work. It’s never called. I put a breakpoint in this procedure and it never hits:

virtual bool IsButtonEnabled(INT nButtonType) const;

bool CCancelCellProgress::IsButtonEnabled(INT) const
{
    return true;
}


2) Works great, thx

Technical Support Nov 24, 2006 - 12:37 PM

We are sorry for giving you the wrong advice. In fact, this method is non virtual. But it invokes the OnQueryButtonInfo() virtual method. So please override OnQueryButtonInfo() instead:

virtual bool OnQueryButtonInfo(
            INT nButtonType,
            bool * p_bEnabled,
            bool * p_bPressed = NULL,
            bool * p_bStayPressed = NULL,
            UINT * p_nTimerElapseValue = NULL
            ) const;


Technical Support Nov 24, 2006 - 12:42 PM

By the way, we keep receiving non-delivery notifications. So please check this if you want to get notifications from this forum.

Scott Moore Nov 24, 2006 - 10:38 AM

Wow, thanks for providing the code. I’ve implemented what you’ve written, but I have a couple more questions.

1) How do I enable the button? I see a IsButtonEnabled() method, but nothing to enable it.

2) Is there a way to remove the button when I’m done processing? Basically when the row is finished working, I set the progress bar to zero and call pCellProgress->TextModeSet(CExtGridCellProgress::eText) to make it look like a regular text cell.

Thanks for the help.

Technical Support Nov 24, 2006 - 11:08 AM

1) CExtGridCell::IsButtonEnabled() is a virtual method. It is called to determine the state of the button. When this method returns false the button is disabled. The nButtonType parameter cab be one of the following values:

__EBTT_ELLIPSIS
__EBTT_DROPDOWN
__EBTT_UPDOWN_UP
__EBTT_UPDOWN_DOWN

2) You can hide the button by removing the __EGCS_BUTTON_ELLIPSIS cell style:

pCell->ModifyStyle( 0L, __EGCS_BUTTON_ELLIPSIS );



Technical Support Nov 21, 2006 - 3:38 AM

You could override the CExtGridCellProgress::OnPaintButton() virtual method and draw whatever button you need. As for the sample, below is a CYourGridCellProgress class which draws an ellipsis button with the close symbol instead of dots.

progress cell and close button

Here is how you can initialize the new cell:

CYourGridCellProgress * pCellProgress =
            STATIC_DOWNCAST(
                        CYourGridCellProgress,
                        m_wndGrid.GridCellGet(
                                    nColNo,
                                    nRowNo,
                                    0,
                                    0,
                                    RUNTIME_CLASS(CYourGridCellProgress)
                                    )
                        );
pCellProgress->ModifyStyle( __EGCS_BUTTON_ELLIPSIS );
DECLARATION:
/////////////////////////////////////////////////////////////////////////////
// CYourGridCellProgress
 
class CYourGridCellProgress : public CExtGridCellProgress
{
public:
            DECLARE_SERIAL( CYourGridCellProgress );
            IMPLEMENT_ExtGridCell_Clone( CYourGridCellProgress, CExtGridCellProgress );
            CYourGridCellProgress(
                        CExtGridDataProvider * pDataProvider = NULL
                        );
            
            virtual void OnPaintButton(
                        const RECT & rcButton,
                        INT nButtonType, // e_button_type_t
                        bool bPressed,
                        bool bEnabled,
                        const CExtGridWnd & wndGrid,
                        CDC & dc,
                        LONG nVisibleColNo,
                        LONG nVisibleRowNo,
                        LONG nColNo,
                        LONG nRowNo,
                        INT nColType,
                        INT nRowType,
                        const RECT & rcCellExtra,
                        const RECT & rcCell,
                        const RECT & rcVisibleRange,
                        DWORD dwAreaFlags,
                        DWORD dwHelperPaintFlags
                        ) const;
 
}; // class CYourGridCellProgress
IMPLEMENTATION:
#if (! defined __VSSYM32_H__)
            #include <vssym32/vssym32.h>
#endif
 
IMPLEMENT_SERIAL( CYourGridCellProgress, CExtGridCellProgress, VERSIONABLE_SCHEMA|1 );
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
/////////////////////////////////////////////////////////////////////////////
// CYourGridCellProgress
 
CYourGridCellProgress::CYourGridCellProgress(
            CExtGridDataProvider * pDataProvider // = NULL
            )
            : CExtGridCellProgress( pDataProvider )
{
}
 
void CYourGridCellProgress::OnPaintButton(
            const RECT & rcButton,
            INT nButtonType, // e_button_type_t
            bool bPressed,
            bool bEnabled,
            const CExtGridWnd & wndGrid,
            CDC & dc,
            LONG nVisibleColNo,
            LONG nVisibleRowNo,
            LONG nColNo,
            LONG nRowNo,
            INT nColType,
            INT nRowType,
            const RECT & rcCellExtra,
            const RECT & rcCell,
            const RECT & rcVisibleRange,
            DWORD dwAreaFlags,
            DWORD dwHelperPaintFlags
            ) const
{
            ASSERT_VALID( this );
            ASSERT_VALID( (&wndGrid) );
            ASSERT( dc.GetSafeHdc() != NULL );
            if( ! dc.RectVisible(&rcButton) )
                        return;
            if( nButtonType != __EBTT_ELLIPSIS )
            {
                        CExtGridCellProgress::OnPaintButton(
                                    rcButton,
                                    nButtonType,
                                    bPressed,
                                    bEnabled,
                                    wndGrid,
                                    dc,
                                    nVisibleColNo,
                                    nVisibleRowNo,
                                    nColNo,
                                    nRowNo,
                                    nColType,
                                    nRowType,
                                    rcCellExtra,
                                    rcCell,
                                    rcVisibleRange,
                                    dwAreaFlags,
                                    dwHelperPaintFlags
                                    );
                        return ;
            }
            COLORREF clrFace =
                        wndGrid.OnSiwGetSysColor( COLOR_3DFACE );
            COLORREF clrLight = 
                        wndGrid.OnSiwGetSysColor( COLOR_3DHIGHLIGHT );
            COLORREF clrShadow = 
                        wndGrid.OnSiwGetSysColor( COLOR_3DSHADOW );
            COLORREF clrWindow = 
                        wndGrid.OnSiwGetSysColor( COLOR_WINDOW );
            COLORREF clrText = RGB(255,0,0);
            
            wndGrid.PmBridge_GetPM()->Grid_PaintButton( 
                        dc,
                        rcButton,
                        -1,
                        bPressed,
                        bEnabled,
                        clrFace,
                        clrLight,
                        clrShadow,
                        clrWindow,
                        clrText,
                        (CObject*) &wndGrid,
                        0L
                        );
 
            CRect rc( rcButton );
 
            CExtPaintManager::glyph_t * pGlyph = 
                        CExtPaintManager::g_DockingCaptionGlyphs[
                                    (INT) CExtPaintManager::__DCBT_CLOSE_DC2K
                                    ];          
            
            COLORREF ColorValues[2] =
            {
                        RGB(0,0,0),
                        RGB(0,0,0),
            };
            ColorValues[1] = 
                        bEnabled ? clrText : clrLight;
            if( ! bEnabled )
                        rc.OffsetRect( 1, 1 );
            wndGrid.PmBridge_GetPM()->PaintGlyphCentered(
                        dc,
                        rc,
                        *pGlyph,
                        ColorValues
                        );
            if( ! bEnabled )
            {
                        rc.OffsetRect( -1, -1 );
                        ColorValues[1] = clrShadow;
                        wndGrid.PmBridge_GetPM()->PaintGlyphCentered(
                                    dc,
                                    rc,
                                    *pGlyph,
                                    ColorValues
                                    );
            } // if( ! bEnabled )
}