📄 gridctrl.cpp.svn-base
字号:
else
SendMessage(WM_HSCROLL, SB_LINERIGHT, 0);
}
break;
}
Invalidate();
}
}
}
// Instant editing of cells when keys are pressed
void CGridCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (!IsCTRLpressed() && m_MouseMode == MOUSE_NOTHING)
{
if (!m_bHandleTabKey || (m_bHandleTabKey && nChar != VK_TAB))
OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, nChar);
}
CWnd::OnChar(nChar, nRepCnt, nFlags);
}
// Callback from any CInPlaceEdits that ended. This just calls OnEndEditCell,
// refreshes the edited cell and moves onto next cell if the return character
// from the edit says we should.
void CGridCtrl::OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
GV_DISPINFO *pgvDispInfo = (GV_DISPINFO *)pNMHDR;
GV_ITEM *pgvItem = &pgvDispInfo->item;
// In case OnEndInPlaceEdit called as window is being destroyed
if (!IsWindow(GetSafeHwnd()))
return;
OnEndEditCell(pgvItem->row, pgvItem->col, pgvItem->szText);
InvalidateCellRect(CCellID(pgvItem->row, pgvItem->col));
SendMessageToParent(pgvItem->row, pgvItem->col, GVN_ENDLABELEDIT);
switch (pgvItem->lParam)
{
case VK_TAB:
case VK_DOWN:
case VK_UP:
case VK_RIGHT:
case VK_LEFT:
case VK_NEXT:
case VK_PRIOR:
case VK_HOME:
case VK_END:
OnKeyDown(pgvItem->lParam, 0, 0);
OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, pgvItem->lParam);
}
*pResult = 0;
}
// Handle horz scrollbar notifications
void CGridCtrl::OnHScroll(UINT nSBCode, UINT /*nPos*/, CScrollBar* /*pScrollBar*/)
{
if (GetFocus()->GetSafeHwnd() != GetSafeHwnd())
SetFocus(); // Auto-destroy any InPlaceEdit's
#ifndef GRIDCONTROL_NO_TITLETIPS
m_TitleTip.Hide(); // hide any titletips
#endif
int scrollPos = GetScrollPos32(SB_HORZ);
CCellID idTopLeft = GetTopleftNonFixedCell();
CRect rect;
GetClientRect(rect);
switch (nSBCode)
{
case SB_LINERIGHT:
if (scrollPos < m_nHScrollMax)
{
int xScroll = GetColumnWidth(idTopLeft.col);
SetScrollPos32(SB_HORZ, scrollPos + xScroll);
if (GetScrollPos32(SB_HORZ) == scrollPos) break; // didn't work
rect.left = GetFixedColumnWidth() + xScroll;
ScrollWindow(-xScroll, 0, rect);
rect.left = rect.right - xScroll;
InvalidateRect(rect);
}
break;
case SB_LINELEFT:
if (scrollPos > 0 && idTopLeft.col > GetFixedColumnCount())
{
int xScroll = GetColumnWidth(idTopLeft.col-1);
SetScrollPos32(SB_HORZ, max(0,scrollPos - xScroll));
rect.left = GetFixedColumnWidth();
ScrollWindow(xScroll, 0, rect);
rect.right = rect.left + xScroll;
InvalidateRect(rect);
}
break;
case SB_PAGERIGHT:
if (scrollPos < m_nHScrollMax)
{
rect.left = GetFixedColumnWidth();
int offset = rect.Width();
int pos = min(m_nHScrollMax, scrollPos + offset);
SetScrollPos32(SB_HORZ, pos);
rect.left = GetFixedColumnWidth();
InvalidateRect(rect);
}
break;
case SB_PAGELEFT:
if (scrollPos > 0)
{
rect.left = GetFixedColumnWidth();
int offset = -rect.Width();
int pos = max(0, scrollPos + offset);
SetScrollPos32(SB_HORZ, pos);
rect.left = GetFixedColumnWidth();
InvalidateRect(rect);
}
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
{
SetScrollPos32(SB_HORZ, GetScrollPos32(SB_HORZ, TRUE));
CCellID idNewTopLeft = GetTopleftNonFixedCell();
if (idNewTopLeft != idTopLeft)
{
rect.left = GetFixedColumnWidth();
InvalidateRect(rect);
}
}
break;
case SB_LEFT:
if (scrollPos > 0)
{
SetScrollPos32(SB_HORZ, 0);
Invalidate();
}
break;
case SB_RIGHT:
if (scrollPos < m_nHScrollMax)
{
SetScrollPos32(SB_HORZ, m_nHScrollMax);
Invalidate();
}
break;
default: break;
}
}
// Handle vert scrollbar notifications
void CGridCtrl::OnVScroll(UINT nSBCode, UINT /*nPos*/, CScrollBar* /*pScrollBar*/)
{
if (GetFocus()->GetSafeHwnd() != GetSafeHwnd())
SetFocus(); // Auto-destroy any InPlaceEdit's
#ifndef GRIDCONTROL_NO_TITLETIPS
m_TitleTip.Hide(); // hide any titletips
#endif
// Get the scroll position ourselves to ensure we get a 32 bit value
int scrollPos = GetScrollPos32(SB_VERT);
CCellID idTopLeft = GetTopleftNonFixedCell();
CRect rect;
GetClientRect(rect);
switch (nSBCode)
{
case SB_LINEDOWN:
if (scrollPos < m_nVScrollMax)
{
int yScroll = GetRowHeight(idTopLeft.row);
SetScrollPos32(SB_VERT, scrollPos + VSCROLL_FACTOR);
if (GetScrollPos32(SB_VERT) == scrollPos)
break; // didn't work
rect.top = GetFixedRowHeight() + yScroll;
ScrollWindow( 0, -yScroll, rect);
rect.top = rect.bottom - yScroll;
InvalidateRect(rect);
}
break;
case SB_LINEUP:
if (scrollPos > 0 && idTopLeft.row > GetFixedRowCount())
{
int yScroll = GetRowHeight(idTopLeft.row-1);
SetScrollPos32(SB_VERT, max(0, scrollPos - VSCROLL_FACTOR));
rect.top = GetFixedRowHeight();
ScrollWindow(0, yScroll, rect);
rect.bottom = rect.top + yScroll;
InvalidateRect(rect);
}
break;
case SB_PAGEDOWN:
if (scrollPos < m_nVScrollMax)
{
rect.top = GetFixedRowHeight();
int nHeightSum = 0, nOffset = 0;
while( nHeightSum < rect.Height() && idTopLeft.row+nOffset < GetRowCount() )
{
nHeightSum += GetRowHeight(idTopLeft.row+nOffset);
nOffset ++;
}
scrollPos = min(m_nVScrollMax, scrollPos + nOffset*VSCROLL_FACTOR);
SetScrollPos32(SB_VERT, scrollPos);
rect.top = GetFixedRowHeight();
InvalidateRect(rect);
}
break;
case SB_PAGEUP:
if (scrollPos > 0)
{
rect.top = GetFixedRowHeight();
int nHeightSum = 0, nOffset = 0;
while( nHeightSum < rect.Height() && idTopLeft.row+nOffset >= GetFixedRowCount() )
{
nHeightSum += GetRowHeight(idTopLeft.row+nOffset);
nOffset --;
}
int pos = max(0, scrollPos + nOffset*VSCROLL_FACTOR);
SetScrollPos32(SB_VERT, pos);
rect.top = GetFixedRowHeight();
InvalidateRect(rect);
}
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
{
SetScrollPos32(SB_VERT, GetScrollPos32(SB_VERT, TRUE));
CCellID idNewTopLeft = GetTopleftNonFixedCell();
if (idNewTopLeft != idTopLeft)
{
rect.top = GetFixedRowHeight();
InvalidateRect(rect);
}
}
break;
case SB_TOP:
if (scrollPos > 0)
{
SetScrollPos32(SB_VERT, 0);
Invalidate();
}
break;
case SB_BOTTOM:
if (scrollPos < m_nVScrollMax)
{
SetScrollPos32(SB_VERT, m_nVScrollMax);
Invalidate();
}
default: break;
}
}
/////////////////////////////////////////////////////////////////////////////
// CGridCtrl implementation functions
void CGridCtrl::OnDraw(CDC* pDC)
{
CRect rect;
int row,col;
CRect clipRect;
if (pDC->GetClipBox(&clipRect) == ERROR)
return;
EraseBkgnd(pDC); // OnEraseBkgnd does nothing, so erase bkgnd here.
// This necessary since we may be using a Memory DC.
int nFixedRowHeight = GetFixedRowHeight();
int nFixedColWidth = GetFixedColumnWidth();
CCellID idTopLeft = GetTopleftNonFixedCell();
int minVisibleRow = idTopLeft.row,
minVisibleCol = idTopLeft.col;
CRect VisRect;
CCellRange VisCellRange = GetVisibleNonFixedCellRange(VisRect);
int maxVisibleRow = VisCellRange.GetMaxRow(),
maxVisibleCol = VisCellRange.GetMaxCol();
// draw top-left cells 0..m_nFixedRows-1, 0..m_nFixedCols-1
rect.bottom = -1;
for (row = 0; row < m_nFixedRows; row++)
{
rect.top = rect.bottom+1;
rect.bottom = rect.top + GetRowHeight(row)-1;
rect.right = -1;
for (col = 0; col < m_nFixedCols; col++)
{
rect.left = rect.right+1;
rect.right = rect.left + GetColumnWidth(col)-1;
DrawFixedCell(pDC, row, col, rect);
}
}
// draw fixed column cells: m_nFixedRows..n, 0..m_nFixedCols-1
rect.bottom = nFixedRowHeight-1;
for (row = minVisibleRow; row <= maxVisibleRow; row++)
{
rect.top = rect.bottom+1;
rect.bottom = rect.top + GetRowHeight(row)-1;
// rect.bottom = bottom pixel of previous row
if (rect.top > clipRect.bottom)
break; // Gone past cliprect
if (rect.bottom < clipRect.top)
continue; // Reached cliprect yet?
rect.right = -1;
for (col = 0; col < m_nFixedCols; col++)
{
rect.left = rect.right+1;
rect.right = rect.left + GetColumnWidth(col)-1;
if (rect.left > clipRect.right)
break; // gone past cliprect
if (rect.right < clipRect.left)
continue; // Reached cliprect yet?
DrawFixedCell(pDC, row, col, rect);
}
}
// draw fixed row cells 0..m_nFixedRows, m_nFixedCols..n
rect.bottom = -1;
for (row = 0; row < m_nFixedRows; row++)
{
rect.top = rect.bottom+1;
rect.bottom = rect.top + GetRowHeight(row)-1;
// rect.bottom = bottom pixel of previous row
if (rect.top > clipRect.bottom)
break; // Gone past cliprect
if (rect.bottom < clipRect.top)
continue; // Reached cliprect yet?
rect.right = nFixedColWidth-1;
for (col = minVisibleCol; col <= maxVisibleCol; col++)
{
rect.left = rect.right+1;
rect.right = rect.left + GetColumnWidth(col)-1;
if (rect.left > clipRect.right)
break; // gone past cliprect
if (rect.right < clipRect.left)
continue; // Reached cliprect yet?
DrawFixedCell(pDC, row, col, rect);
}
}
// draw rest of non-fixed cells
rect.bottom = nFixedRowHeight-1;
for (row = minVisibleRow; row <= maxVisibleRow; row++)
{
rect.top = rect.bottom+1;
rect.bottom = rect.top + GetRowHeight(row)-1;
// rect.bottom = bottom pixel of previous row
if (rect.top > clipRect.bottom)
break; // Gone past cliprect
if (rect.bottom < clipRect.top)
continue; // Reached cliprect yet?
rect.right = nFixedColWidth-1;
for (col = minVisibleCol; col <= maxVisibleCol; col++)
{
rect.left = rect.right+1;
rect.right = rect.left + GetColumnWidth(col)-1;
if (rect.left > clipRect.right)
break; // gone past cliprect
if (rect.right < clipRect.left)
continue; // Reached cliprect yet?
DrawCell(pDC, row, col, rect);
}
}
CPen pen;
TRY {
pen.CreatePen(PS_SOLID, 0, m_crGridColour);
}
CATCH (CResourceException, e)
{
e->Delete();
return;
}
END_CATCH
pDC->SelectObject(&pen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -