📄 gridctrl.cpp
字号:
pDC->FillSolidRect(VisRect.right, ClipRect.top,
ClipRect.right - VisRect.right+1, ClipRect.Height(),
GetBkColor());
// Draw bottom of window below grid
if (VisRect.bottom < ClipRect.bottom && ClipRect.left < VisRect.right)
pDC->FillSolidRect(ClipRect.left, VisRect.bottom,
VisRect.right-ClipRect.left+1, ClipRect.bottom - VisRect.bottom+1,
GetBkColor());
}
void CGridCtrl::OnSize(UINT nType, int cx, int cy)
{
// if (::IsWindow(GetSafeHwnd()) && GetFocus()->GetSafeHwnd() != GetSafeHwnd())
SetFocus(); // Auto-destroy any InPlaceEdit's
CWnd::OnSize(nType, cx, cy);
ResetScrollBars();
}
UINT CGridCtrl::OnGetDlgCode()
{
return DLGC_WANTARROWS | DLGC_WANTCHARS;
}
// If system settings change, then redo colours
void CGridCtrl::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
CWnd::OnSettingChange(uFlags, lpszSection);
if (GetTextColor() == m_crWindowText) // Still using system colours
SetTextColor(::GetSysColor(COLOR_WINDOWTEXT)); // set to new system colour
if (GetTextBkColor() == m_crWindowColour)
SetTextBkColor(::GetSysColor(COLOR_WINDOW));
if (GetBkColor() == m_crShadow)
SetBkColor(::GetSysColor(COLOR_3DSHADOW));
if (GetFixedTextColor() == m_crWindowText)
SetFixedTextColor(::GetSysColor(COLOR_WINDOWTEXT));
if (GetFixedBkColor() == m_cr3DFace)
SetFixedBkColor(::GetSysColor(COLOR_3DFACE));
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
m_nRowsPerWheelNotch = GetMouseScrollLines(); // Get the number of lines
}
// If system colours change, then redo colours
void CGridCtrl::OnSysColorChange()
{
CWnd::OnSysColorChange();
if (GetTextColor() == m_crWindowText) // Still using system colours
SetTextColor(::GetSysColor(COLOR_WINDOWTEXT)); // set to new system colour
if (GetTextBkColor() == m_crWindowColour)
SetTextBkColor(::GetSysColor(COLOR_WINDOW));
if (GetBkColor() == m_crShadow)
SetBkColor(::GetSysColor(COLOR_3DSHADOW));
if (GetFixedTextColor() == m_crWindowText)
SetFixedTextColor(::GetSysColor(COLOR_WINDOWTEXT));
if (GetFixedBkColor() == m_cr3DFace)
SetFixedBkColor(::GetSysColor(COLOR_3DFACE));
m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
}
// If we are drag-selecting cells, or drag and dropping, stop now
void CGridCtrl::OnCaptureChanged(CWnd *pWnd)
{
if (pWnd->GetSafeHwnd() == GetSafeHwnd()) return;
// kill timer if active
if (m_nTimerID != 0)
{
KillTimer(m_nTimerID);
m_nTimerID = 0;
}
// Kill drag and drop if active
if (m_MouseMode == MOUSE_DRAGGING)
{
m_pDragImage->DragLeave(GetDesktopWindow());
m_pDragImage->EndDrag();
delete m_pDragImage;
m_pDragImage = NULL;
m_MouseMode = MOUSE_NOTHING;
}
}
// For drag-selection. Scrolls hidden cells into view
// TODO: decrease timer interval over time to speed up selection over time
void CGridCtrl::OnTimer(UINT nIDEvent)
{
ASSERT(nIDEvent == WM_LBUTTONDOWN);
if (nIDEvent != WM_LBUTTONDOWN) return;
CPoint pt, origPt;
if (!GetCursorPos(&origPt)) return;
ScreenToClient(&origPt);
CRect rect;
GetClientRect(rect);
int nFixedRowHeight = GetFixedRowHeight();
int nFixedColWidth = GetFixedColumnWidth();
pt = origPt;
if (pt.y > rect.bottom)
{
//SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
SendMessage(WM_KEYDOWN, VK_DOWN, 0);
if (pt.x < rect.left) pt.x = rect.left;
if (pt.x > rect.right) pt.x = rect.right;
pt.y = rect.bottom;
OnSelecting(GetCellFromPt(pt));
}
else if (pt.y < nFixedRowHeight)
{
//SendMessage(WM_VSCROLL, SB_LINEUP, 0);
SendMessage(WM_KEYDOWN, VK_UP, 0);
if (pt.x < rect.left) pt.x = rect.left;
if (pt.x > rect.right) pt.x = rect.right;
pt.y = nFixedRowHeight + 1;
OnSelecting(GetCellFromPt(pt));
}
pt = origPt;
if (pt.x > rect.right)
{
// SendMessage(WM_HSCROLL, SB_LINERIGHT, 0);
SendMessage(WM_KEYDOWN, VK_RIGHT, 0);
if (pt.y < rect.top) pt.y = rect.top;
if (pt.y > rect.bottom) pt.y = rect.bottom;
pt.x = rect.right;
OnSelecting(GetCellFromPt(pt));
}
else if (pt.x < nFixedColWidth)
{
//SendMessage(WM_HSCROLL, SB_LINELEFT, 0);
SendMessage(WM_KEYDOWN, VK_LEFT, 0);
if (pt.y < rect.top) pt.y = rect.top;
if (pt.y > rect.bottom) pt.y = rect.bottom;
pt.x = nFixedColWidth + 1;
OnSelecting(GetCellFromPt(pt));
}
}
// move about with keyboard
void CGridCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (!IsValid(m_idCurrentCell)) return;
CCellID next = m_idCurrentCell;
if (IsCTRLpressed())
{
switch (nChar)
{
case 'X': OnEditCut(); break;
case 'C': OnEditCopy(); break;
case 'V': OnEditPaste(); break;
}
}
else
{
switch (nChar)
{
case VK_DOWN: if (next.row < (GetRowCount() - 1)) next.row++; break;
case VK_UP: if (next.row > m_nFixedRows) next.row--; break;
case VK_RIGHT: if (next.col < (GetColumnCount() - 1)) next.col++; break;
case VK_LEFT: if (next.col > m_nFixedCols) next.col--; break;
case VK_NEXT: {
CCellID idOldTopLeft = GetTopleftNonFixedCell();
SendMessage(WM_VSCROLL, SB_PAGEDOWN, 0);
CCellID idNewTopLeft = GetTopleftNonFixedCell();
int increment = idNewTopLeft.row - idOldTopLeft.row;
if (increment) {
next.row += increment;
if (next.row > (GetRowCount() - 1))
next.row = GetRowCount() - 1;
}
else
next.row = GetRowCount() - 1;
break;
}
case VK_PRIOR: {
CCellID idOldTopLeft = GetTopleftNonFixedCell();
SendMessage(WM_VSCROLL, SB_PAGEUP, 0);
CCellID idNewTopLeft = GetTopleftNonFixedCell();
int increment = idNewTopLeft.row - idOldTopLeft.row;
if (increment) {
next.row += increment;
if (next.row < m_nFixedRows) next.row = m_nFixedRows;
} else
next.row = m_nFixedRows;
break;
}
case VK_HOME: SendMessage(WM_VSCROLL, SB_TOP, 0);
next.row = m_nFixedRows;
break;
case VK_END: {
SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
next.row = GetRowCount() - 1;
break;
}
default:
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
}
if (next != m_idCurrentCell)
{
SetFocusCell(next);
while (!IsCellVisible(next))
{
switch (nChar) {
case VK_RIGHT: SendMessage(WM_HSCROLL, SB_LINERIGHT, 0); break;
case VK_LEFT: SendMessage(WM_HSCROLL, SB_LINELEFT, 0); break;
case VK_DOWN: SendMessage(WM_VSCROLL, SB_LINEDOWN, 0); break;
case VK_UP: SendMessage(WM_VSCROLL, SB_LINEUP, 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 && IsCellVisible(m_idCurrentCell))
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.
BOOL CGridCtrl::OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
LV_ITEM *plvItem = &plvDispInfo->item;
*pResult = 0;
OnEndEditCell(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
InvalidateCellRect(CCellID(plvItem->iItem, plvItem->iSubItem));
if (plvDispInfo->hdr.idFrom == IDC_IPLIST)
{
SetItemData(plvItem->iItem, plvItem->iSubItem, plvItem->lParam);
return FALSE;
}
switch (plvItem->lParam)
{
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(plvItem->lParam, 0, 0);
OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, plvItem->lParam);
}
if (plvItem->lParam != VK_ESCAPE) SetModified(TRUE);
return FALSE;
}
// Handle horz scrollbar notifications
void CGridCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
if (GetFocus()->GetSafeHwnd() != GetSafeHwnd()) SetFocus(); // Auto-destroy any InPlaceEdit's
int scrollPos = GetGridScrollPos(SB_HORZ);
CCellID idTopLeft = GetTopleftNonFixedCell();
CRect rect;
GetClientRect(rect);
switch (nSBCode)
{
case SB_LINERIGHT:
if (scrollPos < m_nHScrollMax)
{
int xScroll = GetColumnWidth(idTopLeft.col);
SetGridScrollPos(SB_HORZ, scrollPos + xScroll);
if (GetGridScrollPos(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);
SetGridScrollPos(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);
SetGridScrollPos(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);
SetGridScrollPos(SB_HORZ, pos);
rect.left = GetFixedColumnWidth();
InvalidateRect(rect);
}
break;
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
{
SetGridScrollPos(SB_HORZ, nPos);
rect.left = GetFixedColumnWidth();
InvalidateRect(rect);
}
break;
case SB_LEFT:
if (scrollPos > 0)
{
SetGridScrollPos(SB_HORZ, 0);
Invalidate();
}
break;
case SB_RIGHT:
if (scrollPos < m_nHScrollMax)
{
SetGridScrollPos(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
int scrollPos = GetGridScrollPos(SB_VERT);
CCellID idTopLeft = GetTopleftNonFixedCell();
CRect rect;
GetClientRect(rect);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -