📄 gridctrl.cpp
字号:
if(nFlags==MK_LBUTTON)
{
m_bColSizing=true;
}
else
{
m_bColSizing=false;
}
}
if(m_bColSizing)
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
if(point.x>=left+15)
{
if(m_bColSizing && nFlags==MK_LBUTTON )
{
m_bLMouseButtonDown=false;
CDC* pDC = GetDC();
if (!pDC)
return;
CRect oldInvertedRect(m_LastMousePoint.x, rect.top,
m_LastMousePoint.x + 1, rect.bottom);
pDC->InvertRect(&oldInvertedRect);//(用反色填充矩形)用它擦除上一个鼠标位置画的线
CRect newInvertedRect(point.x, rect.top,
point.x + 1, rect.bottom);
pDC->InvertRect(&newInvertedRect);//(用反色填充矩形)在新位置画线,两句形成一条移动的分隔线
ReleaseDC(pDC);
}
m_LastMousePoint = point;
}
CWnd::OnMouseMove(nFlags, point);
}
// Forces a redraw of a cell immediately (using a direct DC construction,
// or the supplied dc)
BOOL CGridCtrl::RedrawCell(const CCellID& cell, CDC* pDC /* = NULL */)
{
return RedrawCell(cell.row, cell.col, pDC);
}
BOOL CGridCtrl::RedrawCell(int nRow, int nCol, CDC* pDC /* = NULL */)
{
BOOL bResult = TRUE;
BOOL bMustReleaseDC = FALSE;
if (!m_bAllowDraw || !IsCellVisible(nRow, nCol))
return FALSE;
CRect rect;
if (!GetCellRect(nRow, nCol, rect))
return FALSE;
if (!pDC)
{
pDC = GetDC();
if (pDC)
bMustReleaseDC = TRUE;
}
if (pDC)
{
// Redraw cells directly
if (nRow < m_nFixedRows || nCol < m_nFixedCols)
{
CGridCellBase* pCell = GetCell(nRow, nCol);
if (pCell)
bResult = pCell->Draw(pDC, nRow, nCol, rect, TRUE);
}
else
{
CGridCellBase* pCell = GetCell(nRow, nCol);
if (pCell)
bResult = pCell->Draw(pDC, nRow, nCol, rect, TRUE);
// Since we have erased the background, we will need to redraw the gridlines
CPen pen;
pen.CreatePen(PS_SOLID, 0, m_crGridLineColour);
CPen* pOldPen = (CPen*) pDC->SelectObject(&pen);
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
{
pDC->MoveTo(rect.left, rect.bottom);
pDC->LineTo(rect.right + 1, rect.bottom);
}
if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
{
pDC->MoveTo(rect.right, rect.top);
pDC->LineTo(rect.right, rect.bottom + 1);
}
pDC->SelectObject(pOldPen);
}
} else
InvalidateRect(rect, TRUE); // Could not get a DC - invalidate it anyway
// and hope that OnPaint manages to get one
if (bMustReleaseDC)
ReleaseDC(pDC);
return bResult;
}
// redraw a complete row
BOOL CGridCtrl::RedrawRow(int row)
{
BOOL bResult = TRUE;
CDC* pDC = GetDC();
for (int col = 0; col < GetColumnCount(); col++)
bResult = RedrawCell(row, col, pDC) && bResult;
if (pDC)
ReleaseDC(pDC);
return bResult;
}
// Returns the bounding box of the cell
BOOL CGridCtrl::GetCellRect(const CCellID& cell, LPRECT pRect)
{
return GetCellRect(cell.row, cell.col, pRect);
}
BOOL CGridCtrl::GetCellRect(int nRow, int nCol, LPRECT pRect)
{
CPoint CellOrigin;
if (!GetCellOrigin(nRow, nCol, &CellOrigin))
return FALSE;
pRect->left = CellOrigin.x;
pRect->top = CellOrigin.y;
pRect->right = CellOrigin.x + GetColumnWidth(nCol)-1;
pRect->bottom = CellOrigin.y + GetRowHeight(nRow)-1;
//TRACE("Row %d, col %d: L %d, T %d, W %d, H %d: %d,%d - %d,%d\n",
// nRow,nCol, CellOrigin.x, CellOrigin.y, GetColumnWidth(nCol), GetRowHeight(nRow),
// pRect->left, pRect->top, pRect->right, pRect->bottom);
return TRUE;
}
BOOL CGridCtrl::IsCellVisible(CCellID cell)
{
return IsCellVisible(cell.row, cell.col);
}
BOOL CGridCtrl::IsCellVisible(int nRow, int nCol)
{
if (!IsWindow(m_hWnd))
return FALSE;
int x, y;
CCellID TopLeft;
if (nCol >= GetFixedColumnCount() || nRow >= GetFixedRowCount())
{
TopLeft = GetTopleftNonFixedCell();
if (nCol >= GetFixedColumnCount() && nCol < TopLeft.col)
return FALSE;
if (nRow >= GetFixedRowCount() && nRow < TopLeft.row)
return FALSE;
}
CRect rect;
GetClientRect(rect);
if (nCol < GetFixedColumnCount())
{
x = 0;
for (int i = 0; i <= nCol; i++)
{
if (x >= rect.right)
return FALSE;
x += GetColumnWidth(i);
}
}
else
{
x = GetFixedColumnWidth();
for (int i = TopLeft.col; i <= nCol; i++)
{
if (x >= rect.right)
return FALSE;
x += GetColumnWidth(i);
}
}
if (nRow < GetFixedRowCount())
{
y = 0;
for (int i = 0; i <= nRow; i++)
{
if (y >= rect.bottom)
return FALSE;
y += GetRowHeight(i);
}
}
else
{
if (nRow < TopLeft.row)
return FALSE;
y = GetFixedRowHeight();
for (int i = TopLeft.row; i <= nRow; i++)
{
if (y >= rect.bottom)
return FALSE;
y += GetRowHeight(i);
}
}
return TRUE;
}
// returns the top left point of the cell. Returns FALSE if cell not visible.
BOOL CGridCtrl::GetCellOrigin(int nRow, int nCol, LPPOINT p)
{
int i;
if (!IsValid(nRow, nCol))
return FALSE;
CCellID idTopLeft;
if (nCol >= m_nFixedCols || nRow >= m_nFixedRows)
idTopLeft = GetTopleftNonFixedCell();
if ((nRow >= m_nFixedRows && nRow < idTopLeft.row) ||
(nCol>= m_nFixedCols && nCol < idTopLeft.col))
return FALSE;
p->x = 0;
if (nCol < m_nFixedCols) // is a fixed column
for (i = 0; i < nCol; i++)
p->x += GetColumnWidth(i);
else
{ // is a scrollable data column
for (i = 0; i < m_nFixedCols; i++)
p->x += GetColumnWidth(i);
for (i = idTopLeft.col; i < nCol; i++)
p->x += GetColumnWidth(i);
}
p->y = 0;
if (nRow < m_nFixedRows) // is a fixed row
for (i = 0; i < nRow; i++)
p->y += GetRowHeight(i);
else
{ // is a scrollable data row
for (i = 0; i < m_nFixedRows; i++)
p->y += GetRowHeight(i);
for (i = idTopLeft.row; i < nRow; i++)
p->y += GetRowHeight(i);
}
return TRUE;
}
BOOL CGridCtrl::GetCellOrigin(const CCellID& cell, LPPOINT p)
{
return GetCellOrigin(cell.row, cell.col, p);
}
// TRUE if the mouse is over a column resize area. point is in Client coords
//当鼠标在一个列的resize范围之内时返回真
BOOL CGridCtrl::MouseOverColumnResizeArea(CPoint& point)
{
if (point.y >= GetFixedRowHeight())
return FALSE;
CCellID idCurrentCell = GetCellFromPt(point);
CPoint start;
if (!GetCellOrigin(idCurrentCell, &start))
return FALSE;
int endx = start.x + GetColumnWidth(idCurrentCell.col);
if ((point.x - start.x < m_nResizeCaptureRange && idCurrentCell.col != 0) ||
endx - point.x < m_nResizeCaptureRange)
{
return TRUE;
}
else
return FALSE;
}
void CGridCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
int leftcol=(m_LeftClickDownCell.col-1)>0 ? (m_LeftClickDownCell.col-1) : 0;//左边的列
int leftrow=m_LeftClickDownCell.row;//行号
CRect leftrc;
GetCellRect(leftrow,leftcol,leftrc);//得到指定单元格的大小
int left;
if(leftcol==0)
{
left=0;
}
else
{
left=leftrc.right;
}
CRect rect;
GetClientRect(rect);
CRect invertedRect(m_LastMousePoint.x, rect.top, m_LastMousePoint.x + 1, rect.bottom);//划线的矩形
CDC* pDC = GetDC();
if (pDC)
{
if(m_bColSizing)
pDC->InvertRect(&invertedRect);//擦除最后一次画的移动分隔线
ReleaseDC(pDC);
}
if (m_LeftClickDownPoint != point && (point.x != 0 || point.y != 0)) // 0 pt fix by email1@bierling.net
{
CPoint start;
if (!GetCellOrigin(m_LeftClickDownCell, &start))
return;
if(point.x<=left+15)
point.x=left+15;
int nColumnWidth = point.x-left;//max(point.x - start.x, m_bAllowColHide? 0 : 1);
if(m_bColSizing)
{
// int lie=m_LeftClickDownCell.col;
// CString s;
// s.Format("%d",lie);
// MessageBox(s);
SetColumnWidth(m_LeftClickDownCell.col, nColumnWidth);//设置新的列宽
m_bColSizing=false;
}
ResetScrollBars();
Invalidate();
}
// CWnd::OnLButtonUp(nFlags, point);
}
//////排序
void CGridCtrl::OnFixedRowClick(CCellID& cell)
{
if (!IsValid(cell))
return;
if(cell.col==0)// 序号列不排序
return;
if (GetHeaderSort())//GetHeaderSort()得到允许排序的标志,使用SetHeaderSort(true)可以允许排序
{
CWaitCursor waiter;
int sort=GetSortColumn();
if (cell.col == GetSortColumn())
SortItems(cell.col, !GetSortAscending());
else
SortItems(cell.col, TRUE);//
Invalidate();
}
}
// Sorts on a given column using the cell text and using the specified comparison
// function
BOOL CGridCtrl::SortItems(int nCol, BOOL bAscending, LPARAM data /* = 0 */)
{
SetSortColumn(nCol);
SetSortAscending(bAscending);
// ResetSelectedRange();
// SetFocusCell(-1, - 1);
if(nCol!=2)
m_pfnCompare=pfnCellNumericCompare;
else
m_pfnCompare=NULL;
if (m_pfnCompare == NULL)
return CGridCtrl::SortItems(pfnCellTextCompare, nCol, bAscending, data);
else
return CGridCtrl::SortItems(m_pfnCompare, nCol, bAscending, data);//
}
// Sorts on a given column using the supplied compare function (see CListCtrl::SortItems)
BOOL CGridCtrl::SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending,
LPARAM data /* = 0 */)
{
SetSortColumn(nCol);
SetSortAscending(bAscending);
// ResetSelectedRange();
// SetFocusCell(-1, -1);
return SortItems(pfnCompare, nCol, bAscending, data, GetFixedRowCount(), -1);
}
// private recursive sort implementation
BOOL CGridCtrl::SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data,
int low, int high)
{
if (nCol >= GetColumnCount())
return FALSE;
if (high == -1)
high = GetRowCount() - 1;
int lo = low;
int hi = high;
if (hi <= lo)
return FALSE;
int mm=(lo + hi)/2;
//LPARAM midItem = GetItemData((lo + hi)/2, nCol);
LPARAM pMidCell = (LPARAM) GetCell((lo + hi)/2, nCol);
// loop through the list until indices cross
while (lo <
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -