📄 nrdbgrid.cpp
字号:
default:
CButton::OnHScroll(nSBCode, nPos, pScrollBar);
return;
}
SetEditMode(FALSE);
Invalidate(FALSE);
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int nRow = 0;
switch(nSBCode)
{
case SB_LINEUP:
if (m_nFirstVisibleRow > 1) m_nFirstVisibleRow --;
else return;
break;
case SB_LINEDOWN:
if (m_nFirstVisibleRow+1 < m_nRows) m_nFirstVisibleRow ++;
break;
// page left
case SB_PAGEUP:
nRow = max(1, m_nFirstVisibleRow - m_nVisibleRows);
if (nRow != m_nFirstVisibleRow) m_nFirstVisibleRow = nRow;
else return;
break;
// page right
case SB_PAGEDOWN:
nRow = min(m_nRows-1, m_nFirstVisibleRow + m_nVisibleRows);
if (nRow != m_nFirstVisibleRow) m_nFirstVisibleRow = nRow;
else return;
break;
case SB_THUMBPOSITION:
m_nFirstVisibleRow = nPos;
break;
default:
CButton::OnHScroll(nSBCode, nPos, pScrollBar);
return;
}
SetEditMode(FALSE);
Invalidate(FALSE);
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnLButtonDown(UINT nFlags, CPoint point)
{
CButton::OnLButtonDown(nFlags, point);
// Under windows 98, upon gaining focus point is 0,0
if (point.x == 0 && point.y == 0) return;
// Clear any previous selection
if (!m_bShift)
{
SetActiveCell(m_nActiveCol, m_nActiveRow, clearsel|save);
};
long lCol, lRow;
if (GetCellPoint(point, &lCol, &lRow))
{
if (lCol > 0 && lRow > 0)
{
CRect rect;
GetRectCell(lCol, lRow, &rect);
// If the cell is a combobox then create it and fill list
if (m_aColumns[lCol].m_celltype.m_nType == Combo)
{
m_nActiveRow = lRow;
m_nActiveCol = lCol;
SetEditMode(TRUE);
} else
{
SetActiveCell(lCol, lRow);
}
Invalidate(FALSE);
}
// Select entire column
else
{
if (lRow == 0) lRow = -1;
if (lCol == 0) lCol = -1;
SetActiveCell(lCol, lRow);
}
}
// Set after processing so that active cell is changed
if (!IsWindow(m_combo))
{
m_bLButton = TRUE;
SetCapture();
};
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnLButtonUp(UINT nFlags, CPoint point)
{
// End drag selection
if (m_bLButton) ReleaseCapture();
m_bLButton = FALSE;
m_nDragCol = 0;
CButton::OnLButtonUp(nFlags, point);
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnMouseMove(UINT nFlags, CPoint point)
{
long lCol, lRow;
m_bDragCursor = FALSE;
CRect rect;
GetWindowRect(&rect);
// Detect drag position
if (m_nDragCol == 0)
{
if (GetCellPoint(point, &lCol, &lRow) && lRow == 0)
{
long lDragCol = 0;
for (int i = 1; i < m_aRectCols.GetSize(); i++)
{
if (m_aRectCols[i].right -2 <= point.x && point.x < m_aRectCols[i].right+2)
{
lDragCol = i + m_nFirstVisibleCol-1;
break;
}
}
if (lDragCol != 0)
{
m_bDragCursor = TRUE;
if (m_bLButton)
{
m_nDragCol = lDragCol;
};
};
}
}
// Drag current column
else
{
// Not sure how this occurs but causes error
if (point.x > rect.Width()-4) return;
m_bDragCursor = TRUE;
// Get width of current column
double dWidth = m_aColumns[m_nDragCol].m_dWidth;
// Get the rectangle corresponding to the current column
CRect rectC = m_aRectCols[m_nDragCol-m_nFirstVisibleCol+1];
// Calculate new width
dWidth = max(1, (dWidth * (point.x - rectC.left)) / rectC.Width());
m_aColumns[m_nDragCol].m_dWidth = dWidth;
Invalidate(FALSE);
}
// Check for selection of cells
if (m_bLButton)
{
if (GetCellPoint(point, &lCol, &lRow))
{
if (lCol > 0 && lRow > 0)
{
if (lCol != m_nFocusCol || lRow != m_nFocusRow)
{
m_nFocusCol = lCol;
m_nFocusRow = lRow;
SetActiveCell(lCol, lRow);
Invalidate(FALSE);
};
}
} else
{
// If over the edge of the control then scroll
CPoint point2 = point;
ClientToScreen(&point2);
if (point2.x > rect.right) OnKeyDown(VK_RIGHT, 0, 0);
if (point2.x < rect.left) OnKeyDown(VK_LEFT, 0, 0);
if (point2.y < rect.top) OnKeyDown(VK_UP, 0, 0);
if (point2.y > rect.bottom) OnKeyDown(VK_DOWN, 0,0);
}
};
// Set the drag cursor
if (m_bDragCursor)
{
SetCursor(m_hDragCursor);
};
CButton::OnMouseMove(nFlags, point);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::SetActiveCell(SS_COORD Col, SS_COORD Row, int nFlags)
{
CString s;
BOOL bChanged = m_nActiveCol != Col || m_nActiveRow != Row;
if (bChanged) m_bEditMode = FALSE;
// If editing then save data
if (IsWindow(m_edit))
{
m_edit.GetWindowText(s);
BOOL bChanged = GetValue(m_nActiveCol, m_nActiveRow) != s;
if (nFlags & save) SetValue(m_nActiveCol, m_nActiveRow, s);
m_edit.DestroyWindow();
// If data has changed then send message
if (nFlags & save && bChanged) m_pParent->PostMessage(SSM_DATACHANGE);
}
if (IsWindow(m_combo))
{
int index = m_combo.GetCurSel();
if (index != CB_ERR)
{
m_combo.GetLBText(index, s);
if (nFlags & save) SetValue(m_nActiveCol, m_nActiveRow, s);
long index1 = GetIndex(m_nActiveCol, m_nActiveRow);
BOOL bChanged = index1 != index;
if (nFlags & save) SetIndex(m_nActiveCol, m_nActiveRow, index);
if (bChanged && nFlags & save) m_pParent->PostMessage(SSM_COMBOSELCHANGE);
}
m_combo.DestroyWindow();
}
// Set window
if (!m_bShift && !m_bLButton)
{
if (Col == -1) m_nActiveCol = 1;
else m_nActiveCol = Col;
if (Row == -1) m_nActiveRow = 1;
else m_nActiveRow = Row;
m_nFocusCol = m_nActiveCol;
m_nFocusRow = m_nActiveRow;
// Store undo information
if (bChanged)
{
m_sUndo = GetValue(m_nActiveCol, m_nActiveRow);
m_nUndoRow = Row;
m_nUndoCol = Col;
}
};
// Inform parent
if (bChanged && Col > 0 && Row > 0)
{
// Open combobox for new cell
if (m_aColumns[Col].m_celltype.m_nType == Combo && !m_bShift &&
!m_bLButton)
{
SetEditMode(TRUE);
}
m_pParent->PostMessage(SSM_LEAVECELL);
};
// Update selection
if ((m_bShift || m_bLButton || Col == -1 || Row == -1) && !(nFlags & clearsel))
{
m_nFocusRow = Row;
m_nFocusCol = Col;
m_celltopleft.Col = Col;
m_celltopleft.Row = Row;
if (m_bShift || m_bLButton)
{
m_cellbottomright.Col = m_nActiveCol;
m_cellbottomright.Row = m_nActiveRow;
} else
{
m_cellbottomright = m_celltopleft;
}
if (m_celltopleft.Col > m_cellbottomright.Col) swap(m_celltopleft.Col, m_cellbottomright.Col);
if (m_celltopleft.Row > m_cellbottomright.Row) swap(m_celltopleft.Row, m_cellbottomright.Row);
}
else
{
if (bChanged || nFlags & clearsel)
{
m_celltopleft.Row = -2;
m_celltopleft.Col = -2;
m_cellbottomright = m_celltopleft;
};
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CNRDBGrid::GetCellPoint(CPoint point, SS_COORD* pCol, SS_COORD* pRow)
{
*pCol = -1;
*pRow = -1;
// First determine the column
for (int i = 0; i < m_aRectCols.GetSize(); i++)
{
if (m_aRectCols[i].left <= point.x && point.x < m_aRectCols[i].right)
{
if (i == 0) *pCol = 0;
else *pCol = i + m_nFirstVisibleCol-1;
break;
}
}
for (i = 0; i < m_aRectRows.GetSize(); i++)
{
if (m_aRectRows[i].top <= point.y && point.y < m_aRectRows[i].bottom)
{
if (i == 0) *pRow = 0;
else *pRow = i + m_nFirstVisibleRow-1;
break;
}
}
return *pRow != -1 && *pCol != -1;
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns the recangle for a given cell, if available
//
// Returns 1 if cell is visible,
// -1 if cell is in first row or column
// -2 if the cell is partially visible
// otherwise 0
//
int CNRDBGrid::GetRectCell(SS_COORD Col, SS_COORD Row, CRect* pRect)
{
int iCol = 0;
if (Col != 0) iCol = Col - m_nFirstVisibleCol+1;
if (iCol < 0 || iCol >= m_aRectCols.GetSize()) return FALSE;
pRect->left = m_aRectCols[iCol].left;
pRect->right = m_aRectCols[iCol].right;
int iRow = 0;
if (Row != 0) iRow = Row - m_nFirstVisibleRow+1;
if (iRow < 0 || iRow >= m_aRectRows.GetSize()) return FALSE;
pRect->top = m_aRectRows[iRow].top;
pRect->bottom = m_aRectRows[iRow].bottom;
if (iCol == 0 || iRow == 0) return -1;
// Cell is partially visible
CRect rectC;
GetClientRect(&rectC);
if (pRect->right > rectC.right) return -2;
else return 1;
}
///////////////////////////////////////////////////////////////////////////////
void CNRDBGrid::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CRect rect;
int nActiveRow = m_nFocusRow;
int nActiveCol = m_nFocusCol;
int nFirstVisibleCol = m_nFirstVisibleCol;
int nFirstVisibleRow = m_nFirstVisibleRow;
// Check if shift is pressed down
if (nChar == VK_SHIFT)
{
m_bShift = TRUE;
}
if (nChar == VK_CONTROL)
{
m_bCtrl = TRUE;
}
BOOL bShift = m_bShift;
// Copy, cut and paste
if ((nChar == VK_INSERT || nChar == 'C') && m_bCtrl)
{
OnCopy(0,0);
}
if ((nChar == VK_INSERT && m_bShift) || (nChar == 'V' && m_bCtrl))
{
OnPaste(0,0);
}
if ((nChar == VK_DELETE && m_bShift) || (nChar == 'X' && m_bCtrl))
{
OnCut(0,0);
}
if (nChar == 'Z' && m_bCtrl)
{
OnEditUndo();
}
// Next cell
if (nChar == VK_RETURN || (nChar == VK_TAB && !m_bShift))
{
// Prevent dragging of selection
m_bShift = FALSE;
nActiveCol++;
// If column is hidden then advance
while (nActiveCol < m_nCols && !m_aColumns[nActiveCol].m_bVisible)
{
nActiveCol++;
}
if (nActiveCol >= m_nCols)
{
if (nActiveRow+1 < m_nRows)
{
nActiveCol = 1;
nActiveRow++;
} else
{
nActiveCol = m_nCols-1;
}
}
}
// Previous cell
else if (nChar == VK_TAB && m_bShift)
{
// Prevent dragging of selection
m_bShift = FALSE;
nActiveCol--;
// If column is hidden then advance
while (nActiveCol >= 0 && !m_aColumns[nActiveCol].m_bVisible)
{
nActiveCol--;
}
if (nActiveCol == 0)
{
if (nActiveRow > 1)
{
nActiveRow--;
nActiveCol = m_nCols-1;
} else
{
nActiveCol = 1;
}
}
}
else if (nChar == VK_F2)
{
SetEditMode(TRUE);
}
else if (nChar == VK_ESCAPE)
{
// Quit without saving
SetActiveCell(nActiveCol, nActiveRow, clearsel);
SetEditMode(FALSE);
}
// Quit if combobox so not as to interfere with its options
if (nChar == VK_RIGHT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -