📄 gridctrl.cpp
字号:
HFONT hFont = ::CreateFontIndirect(&m_Logfont);
OnSetFont((LPARAM)hFont, 0);
DeleteObject(hFont);
// ResetScrollBars(); - called in OnSize anyway
}
// Used by DDX_GridControl. This has been found to be necessary because of
// OLE registering problems.
BOOL CGridCtrl::SubclassWindow(HWND hWnd)
{
if (!CWnd::SubclassWindow(hWnd))
return FALSE;
#ifndef GRIDCONTROL_NO_DRAGDROP
m_DropTarget.Register(this);
#endif
#ifndef GRIDCONTROL_NO_TITLETIPS
if (m_bTitleTips && !IsWindow(m_TitleTip.m_hWnd))
m_TitleTip.Create(this);
#endif
return TRUE;
}
// Sends a message to the parent in the form of a WM_NOTIFY message with
// a NM_GRIDVIEW structure attached
LRESULT CGridCtrl::SendMessageToParent(int nRow, int nCol, int nMessage)
{
if (!IsWindow(m_hWnd))
return 0;
NM_GRIDVIEW nmgv;
nmgv.iRow = nRow;
nmgv.iColumn = nCol;
nmgv.hdr.hwndFrom = m_hWnd;
nmgv.hdr.idFrom = GetDlgCtrlID();
nmgv.hdr.code = nMessage;
CWnd *pOwner = GetOwner();
if (pOwner && IsWindow(pOwner->m_hWnd))
return pOwner->SendMessage(WM_NOTIFY, nmgv.hdr.idFrom, (LPARAM)&nmgv);
else
return 0;
}
BEGIN_MESSAGE_MAP(CGridCtrl, CWnd)
//EFW - Added ON_WM_RBUTTONUP
//{{AFX_MSG_MAP(CGridCtrl)
ON_WM_PAINT()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_SIZE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
ON_WM_CHAR()
ON_WM_LBUTTONDBLCLK()
ON_WM_ERASEBKGND()
ON_UPDATE_COMMAND_UI(ID_EDIT_SELECT_ALL, OnUpdateEditSelectAll)
ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
ON_WM_SYSKEYDOWN()
//}}AFX_MSG_MAP
#ifndef _WIN32_WCE_NO_CURSOR
ON_WM_SETCURSOR()
#endif
#ifndef _WIN32_WCE
ON_WM_RBUTTONUP()
ON_WM_SYSCOLORCHANGE()
ON_WM_CAPTURECHANGED()
#endif
#ifndef GRIDCONTROL_NO_CLIPBOARD
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
#endif
#if (_WIN32_WCE >= 210)
ON_WM_SETTINGCHANGE()
#endif
#if !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
ON_WM_MOUSEWHEEL()
#endif
ON_MESSAGE(WM_SETFONT, OnSetFont)
ON_MESSAGE(WM_GETFONT, OnGetFont)
ON_NOTIFY(GVN_ENDLABELEDIT, IDC_INPLACE_CONTROL, OnEndInPlaceEdit)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGridCtrl message handlers
void CGridCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (m_bDoubleBuffer) // Use a memory DC to remove flicker
{
CMemDC MemDC(&dc);
OnDraw(&MemDC);
}
else // Draw raw - this helps in debugging vis problems.
OnDraw(&dc);
}
BOOL CGridCtrl::OnEraseBkgnd(CDC* /*pDC*/)
{
return TRUE; // Don't erase the background.
}
// Custom background erasure. This gets called from within the OnDraw function,
// since we will (most likely) be using a memory DC to stop flicker. If we just
// erase the background normally through OnEraseBkgnd, and didn't fill the memDC's
// selected bitmap with colour, then all sorts of vis problems would occur
void CGridCtrl::EraseBkgnd(CDC* pDC)
{
CRect VisRect, ClipRect, rect;
CBrush FixedBack(GetFixedBkColor()),
TextBack(GetTextBkColor()),
Back(GetBkColor());
if (pDC->GetClipBox(ClipRect) == ERROR)
return;
GetVisibleNonFixedCellRange(VisRect);
// Draw Fixed columns background
int nFixedColumnWidth = GetFixedColumnWidth();
if (ClipRect.left < nFixedColumnWidth && ClipRect.top < VisRect.bottom)
pDC->FillRect(CRect(ClipRect.left, ClipRect.top,
nFixedColumnWidth, VisRect.bottom),
&FixedBack);
// Draw Fixed rows background
int nFixedRowHeight = GetFixedRowHeight();
if (ClipRect.top < nFixedRowHeight &&
ClipRect.right > nFixedColumnWidth && ClipRect.left < VisRect.right)
pDC->FillRect(CRect(nFixedColumnWidth-1, ClipRect.top,
VisRect.right, nFixedRowHeight),
&FixedBack);
// Draw non-fixed cell background
if (rect.IntersectRect(VisRect, ClipRect))
{
CRect CellRect(max(nFixedColumnWidth, rect.left),
max(nFixedRowHeight, rect.top),
rect.right, rect.bottom);
pDC->FillRect(CellRect, &TextBack);
}
// Draw right hand side of window outside grid
if (VisRect.right < ClipRect.right)
pDC->FillRect(CRect(VisRect.right, ClipRect.top,
ClipRect.right, ClipRect.bottom),
&Back);
// Draw bottom of window below grid
if (VisRect.bottom < ClipRect.bottom && ClipRect.left < VisRect.right)
pDC->FillRect(CRect(ClipRect.left, VisRect.bottom,
VisRect.right, ClipRect.bottom),
&Back);
}
void CGridCtrl::OnSize(UINT nType, int cx, int cy)
{
static BOOL bAlreadyInsideThisProcedure = FALSE;
if (bAlreadyInsideThisProcedure)
return;
if (!::IsWindow(m_hWnd))
return;
// Start re-entry blocking
bAlreadyInsideThisProcedure = TRUE;
EndEditing(); // destroy any InPlaceEdit's
CWnd::OnSize(nType, cx, cy);
ResetScrollBars();
// End re-entry blocking
bAlreadyInsideThisProcedure = FALSE;
}
UINT CGridCtrl::OnGetDlgCode()
{
UINT nCode = DLGC_WANTARROWS | DLGC_WANTCHARS; // DLGC_WANTALLKEYS; //
if (m_bHandleTabKey && !IsCTRLpressed())
nCode |= DLGC_WANTTAB;
return nCode;
}
#ifndef _WIN32_WCE
// 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);
}
#endif
#ifndef _WIN32_WCE_NO_CURSOR
// 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;
}
#ifndef GRIDCONTROL_NO_DRAGDROP
// Kill drag and drop if active
if (m_MouseMode == MOUSE_DRAGGING)
m_MouseMode = MOUSE_NOTHING;
#endif
}
#endif
#if (_MFC_VER >= 0x0421) || (_WIN32_WCE >= 210)
// 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
}
#endif
// 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;
#ifdef _WIN32_WCE
if (m_MouseMode == MOUSE_NOTHING)
return;
origPt = GetMessagePos();
#else
if (!GetCursorPos(&origPt))
return;
#endif
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))
{
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
return;
}
CCellID next = m_idCurrentCell;
BOOL bChangeLine = FALSE;
if (IsCTRLpressed())
{
switch (nChar)
{
case 'A':
OnEditSelectAll();
break;
#ifndef GRIDCONTROL_NO_CLIPBOARD
case 'X':
OnEditCut();
break;
case VK_INSERT:
case 'C':
OnEditCopy();
break;
case 'V':
OnEditPaste();
break;
#endif
}
}
#ifndef GRIDCONTROL_NO_CLIPBOARD
if (IsSHIFTpressed() &&(nChar == VK_INSERT))
OnEditPaste();
#endif
BOOL bFoundVisible;
int iOrig;
switch (nChar)
{
case VK_DELETE:
if (IsCellEditable(m_idCurrentCell.row, m_idCurrentCell.col))
{
SendMessageToParent(m_idCurrentCell.row, m_idCurrentCell.col, GVN_BEGINLABELEDIT);
SetItemText(m_idCurrentCell.row, m_idCurrentCell.col, _T(""));
SetModified(TRUE, m_idCurrentCell.row, m_idCurrentCell.col);
SendMessageToParent(m_idCurrentCell.row, m_idCurrentCell.col, GVN_ENDLABELEDIT);
RedrawCell(m_idCurrentCell);
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -