Exemplo n.º 1
0
void CGridBtnCellCombo::OnEndEdit()
{
    ASSERT( m_pBtnDataBase != NULL);

    m_ucEditing = FALSE;
    m_pBtnDataBase->SetEditWnd( NULL);

    // make sure that all pushbuttons appear in "up" state
    const int iCtlNbr = GetDrawCtlNbr();
    for( int i1=0; i1 < iCtlNbr; i1++)
    {
        UINT uiType = GetDrawCtlType( i1);
        UINT uiState = GetDrawCtlState( i1);

        BOOL bIsScrollDown =    ( uiType == DFC_SCROLL)
                                && uiState & DFCS_SCROLLDOWN;
        BOOL bIsPushButton =    ( uiType == DFC_BUTTON)
                                && uiState & DFCS_BUTTONPUSH;

        if( bIsScrollDown
            || bIsPushButton)
        {
            ClickedCellCtl( WM_LBUTTONUP,   // Command that invoked.  e.g. WM_LBUTTONDOWN
                            i1);    // zero-based index of image to draw
        }
    }


}
Exemplo n.º 2
0
/*****************************************************************************
May mean end of a button click sequence or to edit text

*****************************************************************************/
BOOL CGridBtnCellCombo::Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar)
{
    int iCtlHit = RelPointInCtl( point);  // Relative point coords
    // returns:  Index of control that this point is within bounds of or -1 if no control matches

    BOOL bShowDropDownNow = FALSE;
    if( iCtlHit >= 0)
    {
        // if user clicked on scroll down button picture, then show
        //  the drop-down, too

        UINT uiType = GetDrawCtlType( iCtlHit);
        UINT uiState = GetDrawCtlState( iCtlHit);

        bShowDropDownNow =  ( uiType == DFC_SCROLL)
                            && uiState & DFCS_SCROLLDOWN;
    }
    BOOL bHitNonComboButton =   ( iCtlHit >= 0)
                                && !bShowDropDownNow;

    if( HasCellText()
        && !bHitNonComboButton )
    {
        m_ucEditing = TRUE;

        // InPlaceList auto-deletes itself
        CGridCtrl* pGrid = GetGrid();
        CInPlaceList* pInPlaceList = new CInPlaceList(  pGrid, rect, m_dwComboStyle, nID, nRow, nCol,
                                                        GetTextClr(), GetBackClr(), m_StringArrayCombo, GetText(), nChar);

        if( bShowDropDownNow)
        {
            if( m_dwComboStyle & CBS_DROPDOWN
                || m_dwComboStyle & CBS_DROPDOWNLIST)
            {
                pInPlaceList->ShowDropDown( TRUE);
            }
        }

        m_pBtnDataBase->SetEditWnd( pInPlaceList);
        return TRUE;
    }
    // call base class, otherwise
    return CGridBtnCell::Edit( nRow, nCol, rect, point, nID, nChar);
}
Exemplo n.º 3
0
void CGridBtnCellCombo::OnClick( CPoint PointCellRelative)
{
    // immediately edit if user clicked on scroll down button picture

    int iCtlHit = RelPointInCtl( PointCellRelative);  // Relative point coords
    // returns:  Index of control that this point is within bounds of or -1 if no control matches

    BOOL bHitScrollDown = FALSE;
    if( iCtlHit >= 0)
    {
        // if user clicked on scroll down button picture, then show
        //  the drop-down, too

        UINT uiType = GetDrawCtlType( iCtlHit);
        UINT uiState = GetDrawCtlState( iCtlHit);

        bHitScrollDown =    ( uiType == DFC_SCROLL)
                            && uiState & DFCS_SCROLLDOWN;
    }
    if( bHitScrollDown)
    {
        // invoke the edit, now -- similar to CGridCtl::OnEditCell() logic
        CGridCtrl* pGrid = GetGrid();
        ASSERT( pGrid != NULL);

        CRect rect;
        if (!pGrid->GetCellRect( m_iRow, m_iCol, rect))
            return;

        SendMessageToParent(m_iRow, m_iCol, GVN_BEGINLABELEDIT);

        Edit( m_iRow, m_iCol, rect, PointCellRelative, IDC_INPLACE_CONTROL, VK_LBUTTON);
        return;
    }

    CGridBtnCell::OnClick( PointCellRelative);
}
Exemplo n.º 4
0
/*****************************************************************************
Determines bounding rectangle to draw a button in a cell.   Used to draw cells
and for mouse hit testing.

If a fixed-size control can't fit within the cell, the control will shrink in
the required x and / or y dimension.   I do this because I'm not using a
clipping region when I display the cell -- that would be a better solution.

*****************************************************************************/
BOOL CGridBtnCellBase::CalcDrawCtlRects(CRect* apRect,     // returns:  CRects with coordinates
                                                    //  last entry has optional leftover rect
                                                    //  available for text, etc.
                                int aiNbrRectEntries,   // nbr of Rects in above array
                                const CRect& arRectCell)// cell rectangle to work with
// returns:  success / fail
{
    ASSERT( apRect != NULL);

    if( aiNbrRectEntries < GetDrawCtlNbrMax() )
    {
        ASSERT( FALSE); // need to allow for leftover rect
        return FALSE;
    }

    const int iCtlNbr = GetDrawCtlNbr();
    if( iCtlNbr <= 0)
        return FALSE;

    int i1, i2;
    int iSpinBoxDownIdx = -1;       // can have zero or 1 spin box -- no more
                                    //  identifies placment of down arrow of the spin box
    int iWidth = 0;
    CTL_ALIGN CtlAlign;
    UINT uiType;
    UINT uiState;
    CRect* pRectSav = apRect;

    // calculate the width layout of buttons by examining
    //  all of them and noting important info
    int iFixedSum = 0;
    int iSizeToFitCount = 0;
    for( i1=0; i1 < iCtlNbr; i1++)
    {
        CtlAlign = GetDrawCtlAlign( i1);

        if( CtlAlign == CTL_ALIGN_CENTER)
        {
            // forget all calculations if any are centered, all controls
            //  just overwrite each other and expand to fit cell
            for( i2=0; i2 < iCtlNbr; i2++)
            {
                apRect->operator=( arRectCell); // copy initial rectangle
                apRect++;
            }
            apRect->operator=( CRect(0,0,0,0) );    // no text leftover
            return TRUE;
        }

        iWidth = GetDrawCtlWidth( i1);
        if( iWidth > 0)
            iFixedSum += iWidth;
        else
            iSizeToFitCount++;

        // spin box rectangles are stacked on top of each other
        //  thus, avoid doubling spin box width
        if( iSpinBoxDownIdx < 0)
        {
            uiState = GetDrawCtlState( i1);
            if( GetDrawCtlType( i1) == DFC_SCROLL
                && !( uiState & (DFCS_SCROLLCOMBOBOX
                                | DFCS_SCROLLDOWN
                                | DFCS_SCROLLLEFT
                                | DFCS_SCROLLRIGHT
                                | DFCS_SCROLLSIZEGRIP)  )  )  // checking for DFCS_SCROLLUP
                                    // but it is not a bit, it is 0x0!
            {
                if( i1 + 1 < iCtlNbr)
                {
                    // at least 1 more -- see if we got spin box match
                    if( GetDrawCtlType( i1 + 1) == DFC_SCROLL
                        && ( GetDrawCtlState( i1 + 1) & DFCS_SCROLLDOWN)  )
                    {
                        // it's a spin box
                        i1++;   // skip looking at next control
                        iSpinBoxDownIdx = i1;
                    }

                }
            }
        }

    }

    int iSizeToFitWidth = 0;
    int iFitWidthsTotal = arRectCell.Width() - iFixedSum;
    if( iSizeToFitCount > 0)
    {
        iSizeToFitWidth = iFitWidthsTotal / iSizeToFitCount;
    }


    int iSizeToFitCountWrk = iSizeToFitCount;
    int iWidthSoFar = 0;
    for( i1=0; i1 < iCtlNbr; i1++)
    {
        if( iSpinBoxDownIdx == i1)
        {
            // skip down arrow of spin box for calculations
            apRect++;
            continue;
        }

        apRect->operator=( arRectCell); // copy initial rectangle
        apRect->left += iWidthSoFar;
        apRect->right = apRect->left;

        iWidth = GetDrawCtlWidth( i1);
        if( iWidth > 0)
            iWidthSoFar += iWidth; // fixed width
        else
        {
            iSizeToFitCountWrk--;   // found another one

            // may shrink width if control is square -- saves screen real-estate
            uiType = GetDrawCtlType( i1);
            uiState = GetDrawCtlState( i1);
            BOOL bIsRectangle = (   uiType == DFC_BUTTON
                                    && (uiState & DFCS_BUTTONPUSH) == DFCS_BUTTONPUSH);
                                        // all other buttons are square

            if( !bIsRectangle
                && arRectCell.Height() < iSizeToFitWidth)
            {
                // it is square -- make width the cell height
                iWidthSoFar += arRectCell.Height();

                // recalulate size to fit
                iFitWidthsTotal -= arRectCell.Height();

                if( iSizeToFitCountWrk > 0)
                    iSizeToFitWidth = iFitWidthsTotal / iSizeToFitCountWrk;
            }
            else
            {
                iWidthSoFar += iSizeToFitWidth;
                iFitWidthsTotal -= iSizeToFitWidth;
            }
        }

        apRect->right = iWidthSoFar + arRectCell.left;
        apRect++;
    }

    if( iFitWidthsTotal < (int)GetMargin() )
    {
        // no leftover rectangle available
        apRect->SetRectEmpty();
    }
    else
    {
        // calc leftover rectangle
        apRect->operator=( arRectCell);
        apRect->left += iWidthSoFar;
    }

    // I've been assuming that all controls are left-aligned.  Programmer
    //  may have defined controls as right-aligned, too.  Note that left
    //  and right controls can be declared in the array in any order

    // Ok, here's the kludge.  Since I know that the heights of each control
    //  are the same, use these unused height values in the CRect array to
    //  help me calculate the proper order of the widths
    apRect = pRectSav;
    int iSavedTop = arRectCell.left;  // seed first result

    for( i1=0; i1 < iCtlNbr; i1++)
    {
        if( iSpinBoxDownIdx == i1)
        {
            // skip down arrow of spin box for calculations
            apRect++;
            continue;
        }

        // analyzing just Left-aligned controls
        CtlAlign = GetDrawCtlAlign( i1);
        ASSERT( CtlAlign != CTL_ALIGN_CENTER);  // should've taken care of

        if( CtlAlign == CTL_ALIGN_LEFT)
        {
            apRect->top = iSavedTop;
            iSavedTop += apRect->Width();
            apRect->bottom = iSavedTop;
        }
        apRect++;

    }

    // text rectangle appears between left and right aligned controls
    //  and width has been saved in last rectangle
    apRect = pRectSav + iCtlNbr;

    apRect->top = iSavedTop + GetMargin();        // put some margin so doesn't overwrite
    iSavedTop += apRect->Width();
    apRect->bottom = iSavedTop;
    iSavedTop += GetMargin();         // some more margin...

    apRect = pRectSav;
    for( i1=0; i1 < iCtlNbr; i1++)
    {
        if( iSpinBoxDownIdx == i1)
        {
            // skip down arrow of spin box for calculations
            apRect++;
            continue;
        }

        // finally, look at right-aligned controls
        CtlAlign = GetDrawCtlAlign( i1);
        if( CtlAlign == CTL_ALIGN_RIGHT)
        {
            apRect->top = iSavedTop;
            iSavedTop += apRect->Width();
            apRect->bottom = iSavedTop;
        }
        apRect++;
    }


    // flip everything back and we're done
    apRect = pRectSav;
    for( i1=0; i1 <= iCtlNbr; i1++)     // note that I'll get leftover rect, too
    {
        apRect->left = apRect->top;
        if( apRect->left < arRectCell.left )
            apRect->left = arRectCell.left;   // can't go beyond cell
        if( apRect->left > arRectCell.right )
            apRect->left = arRectCell.right;

        apRect->right = apRect->bottom;
        if( apRect->right > arRectCell.right)
            apRect->right = arRectCell.right;
        if( apRect->right < arRectCell.left)
            apRect->right = arRectCell.left;

        apRect->bottom = arRectCell.bottom;
        apRect->top = arRectCell.top;

        apRect++;
    }


    // but wait -- special calculations for the spin box
    if( iSpinBoxDownIdx >= 0)
    {
        CRect* pRectSpinUp = pRectSav + iSpinBoxDownIdx - 1;
        apRect = pRectSav + iSpinBoxDownIdx;

        apRect->left = pRectSpinUp->left;
        apRect->right = pRectSpinUp->right;
        apRect->bottom = pRectSpinUp->bottom;

        int iHalf = apRect->top + ( (apRect->bottom - apRect->top) / 2);
        apRect->top = iHalf;
        pRectSpinUp->bottom = iHalf;
    }

    return TRUE;
}
Exemplo n.º 5
0
/*****************************************************************************
Called during all the mouse events associated with clicking a control
embedded within a cell.  Override to have more elaborate handling like
implementing radio button logic.

*****************************************************************************/
BOOL CGridBtnCellBase::ClickedCellCtl(  UINT uMsg,      // Command that invoked.  e.g. WM_LBUTTONDOWN
                                        int aiWhich)    // zero-based index of image to draw
// returns:  T=redraw occurred / F=no redraw
{
    if( aiWhich < 0
        || aiWhich >= GetDrawCtlNbrMax() )
    {
        ASSERT( FALSE);
        return FALSE;
    }

    UINT uiState = GetDrawCtlState( aiWhich);
    if( uiState & DFCS_INACTIVE)
        return FALSE;   // button is inactive -- don't do anything

    m_sLastCtlClicked = (short)aiWhich;
    UINT iType = GetDrawCtlType( aiWhich);

    switch( uMsg)
    {
        case WM_LBUTTONDOWN:
            // appears pushed in
            uiState |= DFCS_PUSHED;
            SetDrawCtlState( aiWhich, uiState);
            break;

        case WM_LBUTTONUP:
        case WM_LBUTTONDBLCLK:
            // appears pushed out
            uiState &= (~DFCS_PUSHED);

            // auto check / uncheck controls, too
            if( iType == DFC_BUTTON )
            {
                BOOL bIsMbrRadioGrp = GetDrawCtlIsMbrRadioGrp( aiWhich);

                if( uiState & DFCS_BUTTONRADIO
                    || bIsMbrRadioGrp )
                {
                    // radio buttons or any button flagged as being part
                    //  of a radio group will be made to look pressed down
                    //  while pushing-up / unchecking all other members
                    //  of the radio group

                    const int iCtlNbr = GetDrawCtlNbr();
                    UINT uiStateRadio;

                    for( int i1=0; i1 < iCtlNbr; i1++)
                    {
                        if( i1 != aiWhich)
                        {
                            uiStateRadio = GetDrawCtlState( i1);
                            bIsMbrRadioGrp = GetDrawCtlIsMbrRadioGrp( i1);

                            if( uiStateRadio & DFCS_BUTTONRADIO
                                || bIsMbrRadioGrp )
                            {
                                uiStateRadio &= (~( DFCS_PUSHED | DFCS_CHECKED)  );
                                                    // push out and uncheck
                                SetDrawCtlState( i1, uiStateRadio);
                            }
                        }
                    }
                    uiState |= DFCS_CHECKED;  // check
                    if( !(uiState & DFCS_BUTTONRADIO) )
                        uiState |= DFCS_PUSHED;  // press in if not real radio button

                }
                else if(  !( uiState & ALL_BUT_BTN_CHK)  )
                {
                    // not a pushbutton -- it's a check box
                    //  (can't check for DFCS_BUTTONCHECK directly since it is bit 0)
                    if( uiState & DFCS_CHECKED)
                        uiState &= (~DFCS_CHECKED); // uncheck
                    else
                        uiState |= DFCS_CHECKED;    // check
                }
            }

            SetDrawCtlState( aiWhich, uiState);
            break;

        default:
            ASSERT( FALSE); // gotta handle new message
            return FALSE;
    }

    CGridCtrl* pGrid = GetGrid();
    ASSERT( pGrid);

    pGrid->RedrawCell( m_iRow, m_iCol);

    return TRUE;
}
Exemplo n.º 6
0
BOOL CGridBtnCellBase::DrawBtnCell(CDC* pDC, int /* nRow */, int /* nCol */, CRect* prect,
    BOOL /* bEraseBkgnd */)
{
    CGridCtrl* pGrid = GetGrid();

    if (!pGrid || !pDC)
        return FALSE;

    if( prect->Width() <= 0
        || prect->Height() <= 0)  // prevents imagelist item from drawing even
        return FALSE;           //  though cell is hidden

    int nSavedDC = pDC->SaveDC();

    // draw any button images
    ASSERT( MAX_NBR_CTLS_INCELL > GetDrawCtlNbrMax() ); // whoa!
    const int iCtlNbr = GetDrawCtlNbr();
    CRect RectAry[ MAX_NBR_CTLS_INCELL];

    if( iCtlNbr > 0)
    {
        if( GetState() & GVIS_SELECTED
            || GetState() & GVIS_DROPHILITED )
        {
            // draw the rectangle around the grid --
            //  we may be filling cells with controls
            pDC->SelectStockObject(BLACK_PEN);
            pDC->SelectStockObject(NULL_BRUSH);
            pDC->Rectangle(*prect);
        }

        pDC->SetBkMode(TRANSPARENT);
        prect->DeflateRect( GetMargin(), 0);


        CFont* pOldFont = pDC->SelectObject(GetFontObject());

        if( CalcDrawCtlRects(   RectAry,    // returns:  CRects with coordinates
                                            //  last entry has optional leftover rect
                                            //  available for text, etc.
                                MAX_NBR_CTLS_INCELL,// nbr of Rects in above array
                                *prect) )     // cell rectangle to work with
        {
            for( int i1=0; i1 < iCtlNbr; i1++)
            {
                UINT uiType = GetDrawCtlType( i1);
                UINT uiState = GetDrawCtlState( i1);

                pDC->DrawFrameControl(  RectAry[ i1],
                                        uiType,
                                        uiState);

                // if button has text, draw it, too
                const char* pszBtnText = GetDrawCtlBtnText( i1);
                if( pszBtnText != NULL)
                {
                    COLORREF ColorCurrent = pDC->GetTextColor();

                    if( uiState & DFCS_INACTIVE)
                    {
                        // button is grayed-out

                        // draw the text so that it matches MS's look
                        RectAry[ i1].OffsetRect( 1, 1);
                        pDC->SetTextColor( RGB( 255,255,255) );
                        pDC->DrawText(  pszBtnText,
                                        -1,
                                        RectAry[ i1],
                                        DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);

                        RectAry[ i1].OffsetRect( -1, -1);
                        pDC->SetTextColor( ::GetSysColor(COLOR_GRAYTEXT));
                    }
                    else
                    {
                        pDC->SetTextColor( ::GetSysColor(COLOR_BTNTEXT));
                    }

                    pDC->DrawText(  pszBtnText,
                                    -1,
                                    RectAry[ i1],
                                    DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
                    pDC->SetTextColor( ColorCurrent);
                }
            }
            // allowable text area has shrunk up
            *prect = RectAry[ iCtlNbr];
        }

        pDC->SelectObject(pOldFont);

        // maybe there's nothing left to draw
        if( prect->Width() <= 0)
        {
            pDC->RestoreDC(nSavedDC);
            return TRUE;
        }
    }
    pDC->RestoreDC(nSavedDC);
    return TRUE;

}