📄 gridbtncellbase.cpp
字号:
/*****************************************************************************
COPYRIGHT (C) 2000, Ken Bertelson <kenbertelson@hotmail.com>
*****************************************************************************/
#include "stdafx.h"
#include "..\Include\GridBtnCellBase.h"
#include "..\Include\GridCtrl.h"
#include "..\Include\InPlaceEdit.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CString CGridBtnCellBase::m_strTipText;
#define MAX_NBR_CTLS_INCELL 16 // maximum number of controls drawn in a cell
#define ALL_BUT_BTN_CHK (DFCS_BUTTON3STATE | DFCS_BUTTONPUSH | DFCS_BUTTONRADIO | DFCS_BUTTONRADIOIMAGE | DFCS_BUTTONRADIOMASK)
// checking for DFCS_BUTTONCHECK
// but it is not a bit, it is 0x0!
#define ALL_BUT_DT_LEFT (DT_CENTER | DT_RIGHT)
// checking for DT_LEFT
// but it is not a bit, it is 0x0!
IMPLEMENT_DYNCREATE(CGridBtnCellBase, CGridCellBase)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGridBtnCellBase::CGridBtnCellBase()
{
m_pBtnDataBase = NULL;
Reset();
}
CGridBtnCellBase::~CGridBtnCellBase()
{
}
void CGridBtnCellBase::Reset()
{
m_sNbrDrawCtls = 0;
m_sLastCtlClicked = -1;
m_iRow = -1;
m_iCol = -1;
m_ucEditing = FALSE;
}
BOOL CGridBtnCellBase::SetupBtns(
int aiWhich, // zero-based index of image to draw
UINT auiType, // type of frame control to draw e.g. DFC_BUTTON
UINT auiState, // like DrawFrameControl()'s nState e.g. DFCS_BUTTONCHECK
CGridBtnCellBase::CTL_ALIGN aAlign, // horizontal alignment of control image
int aiWidth, // fixed width of control or 0 for size-to-fit
BOOL abIsMbrRadioGrp, // T=btn is member of a radio group
const char* apszText) // Text to insert centered in button; if NULL no text
// returns: success / failure
{
if( aiWhich < 0
|| aiWhich >= GetDrawCtlNbrMax() )
{
ASSERT( FALSE);
return FALSE;
}
if( aAlign < 0
|| aAlign >= CTL_ALIGN_FENCE)
{
ASSERT( FALSE);
return FALSE;
}
if( aAlign == CTL_ALIGN_CENTER
&& aiWhich > 0)
{
ASSERT( FALSE); // if centered can have only 1 button
return FALSE;
}
// increase the count of controls, if necessary and possible
if( aiWhich >= GetDrawCtlNbr() )
{
if( aiWhich >= GetDrawCtlNbrMax() )
return FALSE; // wanted to add too many images
ASSERT( aiWhich == GetDrawCtlNbr() ); // if ASSERT, then you are setting
// initial image 0, then image 2 -- you've
// skipped image 1. You can't skip an image
SetDrawCtlNbr( (unsigned char)( aiWhich + 1) );
}
SetDrawCtlAlign( aiWhich, aAlign);
SetDrawCtlWidth( aiWhich, aiWidth);
SetDrawCtlType( aiWhich, auiType);
SetDrawCtlState( aiWhich, auiState);
SetDrawCtlBtnText( aiWhich, apszText);
SetDrawCtlIsMbrRadioGrp( aiWhich, abIsMbrRadioGrp);
return TRUE;
}
BOOL CGridBtnCellBase::Draw(CDC* pDC, int nRow, int nCol, CRect rect,
BOOL bEraseBkgnd /*=TRUE*/)
{
CRect RectCell( rect);
if( DrawBtnCell( pDC, nRow, nCol, &RectCell, bEraseBkgnd) )
{
// call base class to finish it off
return CGridCellBase::Draw( pDC, nRow, nCol, RectCell, bEraseBkgnd);
}
return FALSE;
}
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);
// Create the appropriate font and select into DC
LOGFONT lf;
memcpy(&lf, GetFont(), sizeof(LOGFONT));
CFont font;
font.CreateFontIndirect(&lf);
CFont* pOldFont = pDC->SelectObject(&font);
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;
}
void CGridBtnCellBase::OnClick( CPoint PointCellRelative)
{
ProcessCtlClick(WM_LBUTTONUP, // Command that invoked. e.g. WM_LBUTTONDOWN
PointCellRelative); // point to check for hit
}
/*****************************************************************************
May mean end of a button click sequence or to edit text
*****************************************************************************/
BOOL CGridBtnCellBase::Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar)
{
ASSERT( m_pBtnDataBase != NULL);
if( ProcessCtlClick(WM_LBUTTONUP, // Command that invoked. e.g. WM_LBUTTONDOWN
point) ) // point to check for hit
{
SendMessageToParent( m_iRow, m_iCol, NM_CLICK); // tell parent about it
return FALSE; // clicked a control rather than edited a value
}
const int iCtlNbr = GetDrawCtlNbr();
if( iCtlNbr > 0 )
{
// if there's at least one left-aligned control and user pressed
// space bar, activate that control
if( GetDrawCtlAlign( 0) == CTL_ALIGN_LEFT
|| iCtlNbr == 1)
{
if( nChar == ' ' )
{
// user hit space bar -- just like clicking a button
ClickedCellCtl( WM_LBUTTONDOWN, // Command that invoked. e.g. WM_LBUTTONDOWN
0); // zero-based index of image to draw
Sleep( 200);
ClickedCellCtl( WM_LBUTTONUP, // Command that invoked. e.g. WM_LBUTTONDOWN
0); // zero-based index of image to draw
SendMessageToParent( m_iRow, m_iCol, NM_CLICK); // tell parent about it
return FALSE; // clicked a control rather than edited a value
}
}
}
// if no string text to edit, then typing a character may invoke a button
if( HasCellText() )
{
DWORD dwStyle = ES_LEFT;
if (GetFormat() & DT_RIGHT)
dwStyle = ES_RIGHT;
else if (GetFormat() & DT_CENTER)
dwStyle = ES_CENTER;
m_ucEditing = TRUE;
// InPlaceEdit auto-deletes itself
CGridCtrl* pGrid = GetGrid();
CWnd* pWnd = new CInPlaceEdit(pGrid, rect, dwStyle, nID, nRow, nCol, GetText(), nChar);
m_pBtnDataBase->SetEditWnd( pWnd);
}
else
{
// since no text to edit, maybe press a button -- check for hot keys
int iCtl = HotKeyBtnMatch( (char)nChar); // hot key character
if( iCtl >= 0 )
{
// returns: index of button or -1 if no hot key matches
ClickedCellCtl( WM_LBUTTONDOWN, // Command that invoked. e.g. WM_LBUTTONDOWN
iCtl); // zero-based index of image to draw
Sleep( 200);
ClickedCellCtl( WM_LBUTTONUP, // Command that invoked. e.g. WM_LBUTTONDOWN
iCtl); // zero-based index of image to draw
SendMessageToParent( m_iRow, m_iCol, NM_CLICK); // tell parent about it
return FALSE; // clicked a control rather than edited a value
}
}
return TRUE;
}
void CGridBtnCellBase::EndEdit()
{
ASSERT( m_pBtnDataBase != NULL);
CWnd* pWnd = m_pBtnDataBase->GetEditWnd();
if (pWnd)
((CInPlaceEdit*)pWnd)->EndEdit();
}
void CGridBtnCellBase::OnEndEdit()
{
ASSERT( m_pBtnDataBase != NULL);
m_ucEditing = FALSE;
m_pBtnDataBase->SetEditWnd( NULL);
}
void CGridBtnCellBase::OnClickDown( CPoint PointCellRelative)
{
ProcessCtlClick(WM_LBUTTONDOWN, // Command that invoked. e.g. WM_LBUTTONDOWN
PointCellRelative); // point to check for hit
}
void CGridBtnCellBase::OnRClick( CPoint /* PointCellRelative */)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -