📄 nrdbgrid.cpp
字号:
{
// Find next visible column
for (int i = nActiveCol+1; i < m_nCols; i++)
{
if (m_aColumns[i].m_bVisible)
{
nActiveCol = i;
break;
}
};
}
else if (nChar == VK_LEFT)
{
for (int i = nActiveCol-1; i > 0; i--)
{
if (m_aColumns[i].m_bVisible)
{
nActiveCol = i;
break;
}
};
}
// Don't process up/down if combobox is visible
if (!IsWindow(m_combo))
{
if (nChar == VK_UP)
{
nActiveRow = max(1, nActiveRow-1);
}
else if (nChar == VK_DOWN)
{
nActiveRow = min(m_nRows-1, nActiveRow+1);
}
};
// Pageup/down
if (nChar == VK_PRIOR)
{
nActiveRow = max(1, nActiveRow- m_nVisibleRows+1);
}
else if (nChar == VK_NEXT)
{
nActiveRow = min(m_nRows-1, nActiveRow + m_nVisibleRows-1);
}
// Home/end
else if (nChar == VK_HOME)
{
nActiveCol = 1;
}
else if (nChar == VK_END)
{
nActiveCol = m_nCols-1;
}
// Set visible cells
if (nActiveRow != m_nFocusRow || nActiveCol != m_nFocusCol ||
nFirstVisibleCol != m_nFirstVisibleCol || nFirstVisibleRow != m_nFirstVisibleRow)
{
if (GetRectCell(nActiveCol, nActiveRow, &rect) <= 0)
{
// Horizontal
if (nActiveCol == 1) m_nFirstVisibleCol = 1;
//else if (nActiveCol == m_nCols-1) m_nFirstVisibleCol = m_nCols-1;
else
{
if (nActiveCol > m_nFirstVisibleCol) OnHScroll(SB_LINERIGHT, 0, NULL);
else if (nActiveCol < m_nFirstVisibleCol) OnHScroll(SB_LINELEFT, 0, NULL);
};
// Vertical
// Line-up / down
if (GetRectCell(nActiveCol, nActiveRow, &rect) <= 0)
{
if (nActiveRow > m_nFirstVisibleRow) OnVScroll(SB_LINEDOWN, 0, NULL);
else if (nActiveRow < m_nFirstVisibleRow) OnVScroll(SB_LINEUP, 0, NULL);
// Still not visible, set cell
if (GetRectCell(nActiveCol, nActiveRow, &rect) <= 0)
{
m_nFirstVisibleRow = max(1, nActiveRow);
};
};
}
// Redraw if cell has changed
SetActiveCell(nActiveCol, nActiveRow);
Invalidate(FALSE);
};
m_bShift = bShift;
CButton::OnKeyDown(nChar, nRepCnt, nFlags);
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_SHIFT)
{
m_bShift = FALSE;
};
if (nChar == VK_CONTROL)
{
m_bCtrl = FALSE;
}
CButton::OnKeyUp(nChar, nRepCnt, nFlags);
}
///////////////////////////////////////////////////////////////////////////////
//
// Start editing
void CNRDBGrid::OnLButtonDblClk(UINT nFlags, CPoint point)
{
long lCol, lRow;
if (GetCellPoint(point, &lCol, &lRow) && lCol > 0 && lRow > 0)
{
SetActiveCell(lCol, lRow);
if (m_aColumns[lCol].m_celltype.m_nType == Edit && !m_aColumns[lCol].m_bLocked)
{
SetEditMode(TRUE);
}
};
CButton::OnLButtonDblClk(nFlags, point);
}
///////////////////////////////////////////////////////////////////////////////
//
// Handle message from combobox when closed up
LRESULT CNRDBGrid::OnSetEditMode(WPARAM wParam, LPARAM lParam)
{
SetEditMode(wParam);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::SetEditMode(BOOL fEditModeOn, int nChar)
{
CString s;
// Destroys current edit control if necessary
SetActiveCell(m_nActiveCol, m_nActiveRow);
if (fEditModeOn)
{
CRect rect;
GetRectCell(m_nActiveCol, m_nActiveRow, &rect);
rect.top++;
rect.bottom--;
rect.left++;
rect.right--;
// Edit control
if (m_aColumns[m_nActiveCol].m_celltype.m_nType == Edit &&
!IsWindow(m_edit))
{
m_edit.Create(ES_AUTOHSCROLL|WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS, rect, this, 1);
// Create maximum length according to cell type
m_edit.SetLimitText(m_aColumns[m_nActiveCol].m_celltype.m_nLength);
// Select font
CFont* pFont = CFont::FromHandle(m_hFont);
m_edit.SetFont(pFont);
if (nChar != -1) s = nChar;
else s = GetValue(m_nActiveCol, m_nActiveRow);
s.TrimRight();
m_edit.SetWindowText(s);
m_edit.SetFocus();
m_edit.SetSel(s.GetLength(), s.GetLength(), TRUE);
}
// Combo box
else if (m_aColumns[m_nActiveCol].m_celltype.m_nType == Combo &&
!IsWindow(m_combo))
{
long lCol = m_nActiveCol;
long lRow = m_nActiveRow;
CRect rectI = rect;
rectI.bottom = rectI.top + rectI.Height() * 10;
m_combo.Create(CBS_DROPDOWNLIST|WS_VSCROLL|WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS, rectI, this, 1);
CFont* pFont = CFont::FromHandle(m_hFont);
m_combo.SetFont(pFont);
// Fill list
CString s = m_aColumns[lCol].m_celltype.m_sItems;
while (!s.IsEmpty())
{
int i = s.Find('\t');
if (i == -1) i = s.GetLength();
int index = m_combo.AddString(s.Left(i));
if (s.GetLength() > i) s = s.Mid(i+1);
else break;
};
// Set current selection
long index = GetIndex(lCol, lRow);
m_combo.SetCurSel(index);
m_combo.ShowDropDown();
m_combo.SetFocus();
}
};
return 0;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::GetEditMode(void)
{
return IsWindow(m_edit);
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar != VK_RETURN && nChar != VK_TAB && nChar != VK_ESCAPE &&
!m_bCtrl)
{
if (m_aColumns[m_nActiveCol].m_celltype.m_nType == Edit &&
!m_aColumns[m_nActiveCol].m_bLocked)
{
SetEditMode(TRUE, nChar);
};
};
CButton::OnChar(nChar, nRepCnt, nFlags);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::SetLock(SS_COORD Col, SS_COORD Row, BOOL Lock)
{
if (Row == -1)
{
// Set default for column
m_aColumns[Col].m_bLocked = Lock;
} else
{
ASSERT(FALSE);
};
return TRUE;
};
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::ShowCol(SS_COORD Col, BOOL bShow)
{
SetMaxCols(max(GetMaxCols(), Col));
m_aColumns[Col].m_bVisible = bShow;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
// Subclass dialog (removes need to include DDX_Control entry in parent dialog
SubclassDlgItem(nID, pParentWnd);
// Store copy of parent (GetParent may not work because window does not
// have WS_CHILD flag)
m_pParent = pParentWnd;
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
//
// When control loses focus make it a child window so that mouse and keyboard
// messages are received by the parent
//
void CNRDBGrid::OnKillFocus(CWnd* pNewWnd)
{
m_bShift = FALSE;
m_bCtrl = FALSE;
m_nDragCol = 0;
if (m_bLButton) ReleaseCapture();
m_bLButton = FALSE;
if (pNewWnd != &m_edit && pNewWnd != &m_combo)
{
m_bEditMode = IsWindow(m_edit);
SetEditMode(FALSE);
};
CButton::OnKillFocus(pNewWnd);
}
//////////////////////////////////////////////////////////////////////////////
//
// When the control has focus make it a pop-up window so that it recieves all
// keyboard commands
void CNRDBGrid::OnSetFocus(CWnd* pOldWnd)
{
CButton::OnSetFocus(pOldWnd);
SetEditMode(m_bEditMode);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::SetCellType(SS_COORD Col, SS_COORD Row, LPSS_CELLTYPE CellType)
{
if (Row == -1)
{
m_aColumns[Col].m_celltype = *CellType;
} else
{
ASSERT(FALSE);
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
LPSS_CELLTYPE CNRDBGrid::SetTypeEdit(LPSS_CELLTYPE pCellType, long Style, short Len,
short ChrSet, short ChrCase)
{
pCellType->m_nType = Edit;
pCellType->m_nLength = Len;
return pCellType;
}
///////////////////////////////////////////////////////////////////////////////
LPSS_CELLTYPE CNRDBGrid::SetTypeComboBox(LPSS_CELLTYPE pCellType, long Style,
LPCTSTR lpItems)
{
pCellType->m_nType = Combo;
pCellType->m_sItems = lpItems;
return pCellType;
};
///////////////////////////////////////////////////////////////////////////////
LPSS_CELLTYPE CNRDBGrid::SetTypeInteger(LPSS_CELLTYPE pCellType, long Min, long Max)
{
pCellType->m_nType = Number;
return pCellType;
};
///////////////////////////////////////////////////////////////////////////////
LRESULT CNRDBGrid::ComboBoxSendMessage (SS_COORD Col, SS_COORD Row, UINT Msg, WPARAM wParam, LPARAM lParam)
{
ASSERT(m_aColumns[Col].m_celltype.m_nType == Combo);
if (Msg == CB_GETCURSEL)
{
return GetIndex(Col, Row);
}
if (Msg == CB_SETCURSEL)
{
SetIndex(Col, Row, wParam);
return 0;
}
if (Msg == CB_ADDSTRING)
{
CString s = (LPCSTR)lParam;
ASSERT(Row == -1);
CString sItems = m_aColumns[Col].m_celltype.m_sItems;
if (!sItems.IsEmpty()) s = '\t' + s;
sItems += s;
m_aColumns[Col].m_celltype.m_sItems = sItems;
return 0;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
LRESULT CNRDBGrid::OnCopy(WPARAM wParam, LPARAM)
{
CRect rect;
CString s;
// Copy current cell by creating a temporary edit control
m_edit.Create(WS_CHILD, rect, this, 1);
s = GetValue(m_nActiveCol, m_nActiveRow);
m_edit.SetWindowText(s);
m_edit.SetSel(0,-1);
m_edit.SendMessage(WM_COPY);
m_edit.DestroyWindow();
// Redraw (if not called by cut)
if (wParam == 0) Invalidate(FALSE);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
LRESULT CNRDBGrid::OnCut(WPARAM, LPARAM)
{
// Same as copy but deletes
OnCopy(1,0);
SetValue(m_nActiveCol, m_nActiveRow, "");
SetInteger(m_nActiveCol, m_nActiveRow, 0);
SetIndex(m_nActiveCol, m_nActiveRow, -1);
Invalidate(FALSE);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
LRESULT CNRDBGrid::OnPaste(WPARAM, LPARAM)
{
CRect rect;
CString s;
// Paste into a temporary edit control then copy to the cell
m_edit.Create(ES_AUTOHSCROLL|WS_CHILD, rect, this, 1);
m_edit.SendMessage(WM_PASTE);
m_edit.GetWindowText(s);
SetValue(m_nActiveCol, m_nActiveRow, s);
//m_edit.SendMessage(WM_COPY);
m_edit.DestroyWindow();
Invalidate(FALSE);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnEditUndo()
{
SetValue(m_nUndoCol, m_nUndoRow, m_sUndo);
Invalidate(FALSE);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_bDragCursor)
{
SetCursor(m_hDragCursor);
return TRUE;
};
return CButton::OnSetCursor(pWnd, nHitTest, message);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::PreTranslateMessage(MSG* pMsg)
{
// By default child buttons do not get keyboard messages
if (GetFocus() == this)
{
// Necessary for keys such as tab
if (pMsg->wParam == VK_TAB || pMsg->wParam == VK_ESCAPE ||
pMsg->wParam == VK_LEFT || pMsg->wParam == VK_RIGHT ||
pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN ||
pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT ||
pMsg->wParam == VK_HOME || pMsg->wParam == VK_END ||
pMsg->wParam == VK_RETURN)
{
if (pMsg->message == WM_KEYDOWN)
{
OnKeyDown(pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
return TRUE;
}
else if (pMsg->message == WM_KEYUP)
{
OnKeyUp(pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
return TRUE;
};
};
// Ensure all keys are passed OnChar
if (pMsg->message == WM_CHAR)
{
OnChar(pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
return TRUE;
}
};
return CButton::PreTranslateMessage(pMsg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -