GridCtrl.cpp
资源名称:MyStock.rar [点击查看]
上传用户:wenjimin
上传日期:2014-08-12
资源大小:111k
文件大小:67k
源码类别:
金融证券系统
开发平台:
Visual C++
- // GridCtrl.cpp : implementation file
- //
- #include "stdafx.h"
- #include "MemDC.h"
- #include "GridCtrl.h"
- #include "MyGridFrame.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CGridCtrl
- IMPLEMENT_DYNCREATE(CGridCtrl, CWnd)
- CGridCtrl::CGridCtrl(int nRows, int nCols, int nFixedRows, int nFixedCols)
- {
- m_crWindowText = ::GetSysColor(COLOR_WINDOWTEXT);
- m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
- m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
- m_crShadow = ::GetSysColor(COLOR_3DSHADOW);
- m_crGridLineColour = RGB(192,192,192);
- m_nRows = 0;
- m_nCols = 0;
- m_nFixedRows = 0;
- m_nFixedCols = 0;
- // m_bFixedColumnSelection = TRUE;
- // m_bFixedRowSelection = TRUE;
- m_nVScrollMax = 0; // Scroll position 滚动指针
- m_nHScrollMax = 0;
- m_bSortOnClick = FALSE; // Sort on header row click
- m_bAscending = TRUE; // sorting stuff 排序...
- m_nSortColumn = 1;
- #ifdef _WIN32_WCE
- m_bDoubleBuffer = FALSE; // Use double buffering to avoid flicker?
- // 使用双缓冲消除闪烁
- #else
- m_bDoubleBuffer = TRUE; // Use double buffering to avoid flicker?
- // 使用双缓冲消除闪烁
- #endif
- m_nGridLines = GVL_BOTH; //表格线
- m_nBarState = GVL_NONE; //
- m_bColSizing = FALSE; //列Sizing状态
- m_bAllowDraw = TRUE; // allow draw updates 全部重画
- m_bAllowColHide = TRUE; // Columns can be contracted to 0-width via mouse
- m_bAllowRowHide = TRUE; // Rows can be contracted to 0-height via mouse
- m_pRtcDefault = RUNTIME_CLASS(CGridCell);
- m_nResizeCaptureRange = 3; // When resizing columns/row, the cursor has to be
- //当改变行/列尺寸时,光标在分隔线
- // within +/-3 pixels of the dividing line for
- //左右+/-3个象素之内
- // resizing to be possible
- //可以改变尺寸
- m_FillRect.top=m_FillRect.left=m_FillRect.bottom=m_FillRect.right=0;
- m_pfnCompare = NULL;
- SetGridBkColor(m_crShadow);
- SetupDefaultCells();//装载缺省的单元格数据(字体、颜色的信息)
- //也就是对m_cellDefault等几个变量的初始化
- //所以也就可以理解GetDefaultCell()的返回值了.
- // Set up the initial grid size
- // 装配最初的表格尺寸
- SetRowCount(nRows);
- SetColumnCount(nCols);
- SetFixedRowCount(nFixedRows);
- SetFixedColumnCount(nFixedCols);
- // set initial selection range (ie. none)
- // m_SelectedCellMap.RemoveAll();
- // m_PrevSelectedCellMap.RemoveAll();
- }
- CGridCtrl::~CGridCtrl()
- {
- //KillTimer(2);
- }
- BEGIN_MESSAGE_MAP(CGridCtrl, CWnd)
- //{{AFX_MSG_MAP(CGridCtrl)
- ON_WM_PAINT()
- ON_WM_ERASEBKGND()
- ON_WM_LBUTTONDOWN()
- ON_WM_SIZE()
- ON_WM_HSCROLL()
- ON_WM_VSCROLL()
- ON_WM_MOUSEMOVE()
- ON_WM_LBUTTONUP()
- ON_WM_CREATE()
- ON_WM_LBUTTONDBLCLK()
- ON_WM_TIMER()
- ON_WM_DESTROY()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CGridCtrl message handlers
- void CGridCtrl::SetupDefaultCells()
- {
- m_cellDefault.SetGrid(this); // Normal editable cell
- //原型是SetGrid(CGridCtrl* pGrid),因为现在就在CGridCtrl类里面,所以可以用this
- //另外,CGridDefaultCell继承自CGridCell,且没有改写SetGrid()函数,所以,其实是调用
- //CGridCell的SetGrid()函数.
- //又因为原型是SetGrid(CGridCtrl* pGrid),而CGridCtrl继承自CWnd,所以,参数其实是要一个
- //窗口指针(父窗口?)
- m_cellFixedColDef.SetGrid(this); // Cell for fixed columns
- m_cellFixedRowDef.SetGrid(this); // Cell for fixed rows
- m_cellFixedRowColDef.SetGrid(this); // Cell for area overlapped by fixed columns/rows
- m_cellDefault.SetTextClr(m_crWindowText);
- m_cellDefault.SetBackClr(m_crWindowColour);
- m_cellFixedColDef.SetTextClr(m_crWindowText);
- m_cellFixedColDef.SetBackClr(m_cr3DFace);
- m_cellFixedRowDef.SetTextClr(m_crWindowText);
- m_cellFixedRowDef.SetBackClr(m_cr3DFace);
- m_cellFixedRowColDef.SetTextClr(m_crWindowText);
- m_cellFixedRowColDef.SetBackClr(m_cr3DFace);
- }
- BOOL CGridCtrl::SetFixedRowCount(int nFixedRows)
- {
- if (m_nFixedRows == nFixedRows)
- return TRUE;
- ASSERT(nFixedRows >= 0);
- // ResetSelectedRange();
- // Force recalculation
- m_idTopLeftCell.col = -1;
- if (nFixedRows > GetRowCount())
- if (!SetRowCount(nFixedRows))
- return FALSE;
- // if (m_idCurrentCell.row < nFixedRows)
- // SetFocusCell(-1, - 1);
- if (1/*!GetVirtualMode()*/)
- {
- if (nFixedRows > m_nFixedRows)
- {
- for (int i = m_nFixedRows; i < nFixedRows; i++)
- for (int j = 0; j < GetColumnCount(); j++)
- {
- SetItemState(i, j, GetItemState(i, j) | GVIS_FIXED | GVIS_FIXEDROW);//m_nState是在这里改变的
- SetItemBkColor(i, j, CLR_DEFAULT );
- SetItemFgColor(i, j, CLR_DEFAULT );
- }
- }
- else
- {
- for (int i = nFixedRows; i < m_nFixedRows; i++)
- {
- int j;
- for (j = 0; j < GetFixedColumnCount(); j++)
- SetItemState(i, j, GetItemState(i, j) & ~GVIS_FIXEDROW );
- for (j = GetFixedColumnCount(); j < GetColumnCount(); j++)
- {
- SetItemState(i, j, GetItemState(i, j) & ~(GVIS_FIXED | GVIS_FIXEDROW) );
- SetItemBkColor(i, j, CLR_DEFAULT );
- SetItemFgColor(i, j, CLR_DEFAULT );
- }
- }
- }
- }
- m_nFixedRows = nFixedRows;
- Refresh();
- return TRUE;
- }
- BOOL CGridCtrl::SetFixedColumnCount(int nFixedCols)
- {
- if (m_nFixedCols == nFixedCols)
- return TRUE;
- ASSERT(nFixedCols >= 0);
- if (nFixedCols > GetColumnCount())
- if (!SetColumnCount(nFixedCols))
- return FALSE;
- // if (m_idCurrentCell.col < nFixedCols)
- // SetFocusCell(-1, - 1);
- // ResetSelectedRange();
- // Force recalculation
- m_idTopLeftCell.col = -1;
- if (1/*!GetVirtualMode()*/)
- {
- if (nFixedCols > m_nFixedCols)
- {
- for (int i = 0; i < GetRowCount(); i++)
- for (int j = m_nFixedCols; j < nFixedCols; j++)
- {
- SetItemState(i, j, GetItemState(i, j) | GVIS_FIXED | GVIS_FIXEDCOL);
- SetItemBkColor(i, j, CLR_DEFAULT );
- SetItemFgColor(i, j, CLR_DEFAULT );
- }
- }
- else
- {
- { // Scope limit i,j
- for (int i = 0; i < GetFixedRowCount(); i++)
- for (int j = nFixedCols; j < m_nFixedCols; j++)
- SetItemState(i, j, GetItemState(i, j) & ~GVIS_FIXEDCOL );
- }
- {// Scope limit i,j
- for (int i = GetFixedRowCount(); i < GetRowCount(); i++)
- for (int j = nFixedCols; j < m_nFixedCols; j++)
- {
- SetItemState(i, j, GetItemState(i, j) & ~(GVIS_FIXED | GVIS_FIXEDCOL) );
- SetItemBkColor(i, j, CLR_DEFAULT );
- SetItemFgColor(i, j, CLR_DEFAULT );
- }
- }
- }
- }
- m_nFixedCols = nFixedCols;
- Refresh();
- return TRUE;
- }
- BOOL CGridCtrl::SetRowCount(int nRows)
- {
- BOOL bResult = TRUE;
- ASSERT(nRows >= 0);
- if (nRows == GetRowCount())//新行数=总行数
- return bResult;
- // Force recalculation
- // m_idTopLeftCell.col = -1;
- if (nRows < m_nFixedRows)
- m_nFixedRows = nRows;
- // if (m_idCurrentCell.row >= nRows)
- // SetFocusCell(-1, - 1);
- int addedRows = nRows - GetRowCount();//增加的行数
- // If we are about to lose rows, then we need to delete the GridCell objects
- // in each column within each row
- if (addedRows < 0)//如果增加的行数<0(有多余的行)
- {
- //删掉它们:
- for (int row = nRows; row < m_nRows; row++)//删掉新行后面的行
- {
- // Delete cells
- //删掉单元格
- for (int col = 0; col < m_nCols; col++)
- DestroyCell(row, col);
- // Delete rows
- //删掉行
- GRID_ROW* pRow = m_RowData[row];
- if (pRow)
- delete pRow;//删掉数组中的一个元素
- }
- m_nRows = nRows;//完成新设置
- }
- TRY
- {
- m_arRowHeights.SetSize(nRows);//记录行高的数组
- // Change the number of rows.
- m_RowData.SetSize(nRows);//记录每行单元格的数组(在这里对m_RowData初始化!!!)
- // If we have just added rows, we need to construct new elements for each cell
- // and set the default row height
- if (addedRows > 0)
- {
- // initialize row heights and data
- int startRow = nRows - addedRows;
- for (int row = startRow; row < nRows; row++)
- {
- m_arRowHeights[row] = m_cellDefault.GetHeight();
- m_RowData[row] = new GRID_ROW;//创建了m_RowData的一个元素
- m_RowData[row]->SetSize(m_nCols);//对这个元素的初始化(因为它也是一个数组)
- for (int col = 0; col < m_nCols; col++)
- {
- GRID_ROW* pRow = m_RowData[row];
- if (pRow && 1/*!GetVirtualMode()*/)
- pRow->SetAt(col, CreateCell(row, col));//对数祖赋值
- }
- m_nRows++;
- }
- }
- }
- CATCH (CMemoryException, e)
- {
- e->ReportError();
- bResult = FALSE;
- }
- END_CATCH
- // SetModified();
- ResetScrollBars();
- Refresh();
- return bResult;
- }
- BOOL CGridCtrl::SetColumnCount(int nCols)
- {
- BOOL bResult = TRUE;
- ASSERT(nCols >= 0);
- if (nCols == GetColumnCount())
- return bResult;
- // Force recalculation
- // m_idTopLeftCell.col = -1;//一个CCellID型的变量
- if (nCols < m_nFixedCols)
- m_nFixedCols = nCols;
- // if (m_idCurrentCell.col >= nCols)
- // SetFocusCell(-1, - 1);
- int addedCols = nCols - GetColumnCount();
- // If we are about to lose columns, then we need to delete the GridCell objects
- // within each column
- if (addedCols < 0 /*&& !GetVirtualMode()*/)
- {
- for (int row = 0; row < m_nRows; row++)
- for (int col = nCols; col < GetColumnCount(); col++)
- DestroyCell(row, col);
- }
- TRY
- {
- // Change the number of columns.
- m_arColWidths.SetSize(nCols);
- // Change the number of columns in each row.
- if (1/*!GetVirtualMode()*/)
- for (int i = 0; i < m_nRows; i++)
- if (m_RowData[i])
- m_RowData[i]->SetSize(nCols);
- // If we have just added columns, we need to construct new elements for each cell
- // and set the default column width
- if (addedCols > 0)
- {
- // initialized column widths
- int startCol = nCols - addedCols;
- for (int col = startCol; col < nCols; col++)
- m_arColWidths[col] = m_cellFixedColDef.GetWidth();
- // initialise column data
- if (1/*!GetVirtualMode()*/)
- {
- for (int row = 0; row < m_nRows; row++)
- for (col = startCol; col < nCols; col++)
- {
- GRID_ROW* pRow = m_RowData[row];
- if (pRow)
- {
- pRow->SetAt(col, CreateCell(row, col));
- }
- }
- }
- }
- // else // check for selected cell ranges
- // ResetSelectedRange();
- }
- CATCH (CMemoryException, e)
- {
- e->ReportError();
- bResult = FALSE;
- }
- END_CATCH
- m_nCols = nCols;
- // SetModified();
- ResetScrollBars();//重值滚动条
- Refresh();
- return bResult;
- }
- BOOL CGridCtrl::SetColumnWidth(int nCol, int width)
- {
- ASSERT(nCol >= 0 && nCol < m_nCols && width >= 0);
- if (nCol < 0 || nCol >= m_nCols || width < 0)
- return FALSE;
- m_arColWidths[nCol] = width;
- ResetScrollBars();
- return TRUE;
- }
- void CGridCtrl::Refresh()
- {
- if (GetSafeHwnd() && m_bAllowDraw)
- Invalidate();
- }
- // Creates a new grid cell and performs any necessary initialisation
- /*virtual*/ CGridCellBase* CGridCtrl::CreateCell(int nRow, int nCol)
- {
- // ASSERT(!GetVirtualMode());
- if (!m_pRtcDefault || !m_pRtcDefault->IsDerivedFrom(RUNTIME_CLASS(CGridCellBase)))
- //IsDerivedFrom是CRuntimeClass的一个检验函数,
- //判断m_pRtcDefault是否是指定类的派生类.
- {
- ASSERT( FALSE);
- return NULL;
- }
- //这起到类型识别和类型检验的作用
- CGridCellBase* pCell = (CGridCellBase*) m_pRtcDefault->CreateObject();
- //m_pRtcDefault在初始化时被RUNTIME_CLASS宏绑定到CGridCell类,
- //所以这实际是用一个基类指针指向一个派生类对象(动态生成)
- //实际使用如下语句似乎也可以:
- //CGridCellBase* pCell = (CGridCellBase*) new CGridCell;
- if (!pCell)
- return NULL;
- pCell->SetGrid(this);
- // pCell->SetCoords(nRow, nCol);
- if (nCol < m_nFixedCols)//pCell就是固定列
- pCell->SetState(pCell->GetState() | GVIS_FIXED | GVIS_FIXEDCOL);//是m_nState和GVIS_FIXED | GVIS_FIXEDCOL的运算结果
- //所以m_nState是在这里改变的
- if (nRow < m_nFixedRows)//pCell就是固定行
- pCell->SetState(pCell->GetState() | GVIS_FIXED | GVIS_FIXEDROW);//是m_nState和GVIS_FIXED | GVIS_FIXEDROW的运算结果
- //所以m_nState是在这里改变的
- // pCell->SetFormat(pCell->GetDefaultCell()->GetFormat());
- return pCell;//这是非固定的单元格,其m_nState就是0;
- }
- /*virtual*/ void CGridCtrl::DestroyCell(int nRow, int nCol)
- {
- // Should NEVER get here in virtual mode.
- // ASSERT(!GetVirtualMode());
- // Set the cells state to 0. If the cell is selected, this
- // will remove the cell from the selected list.
- SetItemState(nRow, nCol, 0);
- delete GetCell(nRow, nCol);
- }
- BOOL CGridCtrl::SetItemBkColor(int nRow, int nCol, COLORREF cr /* = CLR_DEFAULT */)
- {
- // if (GetVirtualMode())
- // return FALSE;
- CGridCellBase* pCell = GetCell(nRow, nCol);
- ASSERT(pCell);
- if (!pCell)
- return FALSE;
- pCell->SetBackClr(cr);
- return TRUE;
- }
- BOOL CGridCtrl::SetItemFgColor(int nRow, int nCol, COLORREF cr /* = CLR_DEFAULT */)
- {
- CGridCellBase* pCell = GetCell(nRow, nCol);
- // ASSERT(pCell);
- if (!pCell)
- return FALSE;
- pCell->SetTextClr(cr);
- return TRUE;
- }
- BOOL CGridCtrl::SetItemState(int nRow, int nCol, UINT state)
- {
- CGridCellBase* pCell = GetCell(nRow, nCol);
- ASSERT(pCell);
- if (!pCell)
- return FALSE;
- // Set the cell's state
- pCell->SetState(state);
- return TRUE;
- }
- UINT CGridCtrl::GetItemState(int nRow, int nCol) const
- {
- CGridCellBase* pCell = GetCell(nRow, nCol);
- ASSERT(pCell);
- if (!pCell)
- return 0;
- return pCell->GetState();
- }
- void CGridCtrl::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- if (m_bDoubleBuffer) // Use a memory DC to remove flicker
- // 使用内存DC消除闪烁
- {
- CMemDC MemDC(&dc);
- OnDraw(&MemDC);
- }
- else // Draw raw - this helps in debugging vis problems.
- OnDraw(&dc);
- // Do not call CWnd::OnPaint() for painting messages
- }
- void CGridCtrl::OnDraw(CDC* pDC)
- {
- if (!m_bAllowDraw)
- return;
- CRect clipRect;
- if (pDC->GetClipBox(&clipRect) == ERROR)
- return;
- GetClientRect(&clipRect);
- EraseBkgnd(pDC);
- CRect rect;
- int row, col;
- CGridCellBase* pCell;
- int nFixedRowHeight = GetFixedRowHeight();
- int nFixedColWidth = GetFixedColumnWidth();
- CCellID idTopLeft = GetTopleftNonFixedCell();//左上角非固定单元格ID(包含行号和列号)
- int minVisibleRow = idTopLeft.row,//最小可见的行号
- minVisibleCol = idTopLeft.col;//最小可见的列号
- CRect VisRect;
- CCellRange VisCellRange = GetVisibleNonFixedCellRange(VisRect);//可见单元格的范围
- //同时初始化VisRect
- int maxVisibleRow = VisCellRange.GetMaxRow(),//最大可见的行号
- maxVisibleCol = VisCellRange.GetMaxCol();//最大可见的列号
- // draw top-left cells 0..m_nFixedRows-1, 0..m_nFixedCols-1
- // 画左上角单元格(也可能是几行几列)
- //(第一行:一列,一列...,第二行:一列,一列....);
- rect.bottom = -1;
- for (row = 0; row < m_nFixedRows; row++)
- {
- if (GetRowHeight(row) <= 0) continue;//不执行下面语句,直接到下一循环
- rect.top = rect.bottom+1;//有这一行,就不会因下一行的操作
- //而使单元格越画越窄了
- rect.bottom = rect.top + GetRowHeight(row)-1;//增加一个行高
- rect.right = -1;
- for (col = 0; col < m_nFixedCols; col++)
- {
- if (GetColumnWidth(col) <= 0) continue;
- rect.left = rect.right+1;//有这一行,就不会因下一行的操作
- //而使单元格越画越窄了
- rect.right = rect.left + GetColumnWidth(col)-1;//增加一个列宽
- pCell = GetCell(row, col);
- if (pCell)
- {
- // pCell->SetCoords(row,col);//这是一个空函数,目前没有用
- pCell->Draw(pDC, row, col, rect, FALSE);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////////
- // draw fixed column cells: m_nFixedRows..n, 0..m_nFixedCols-1
- //画固定的列(行标头):(第一行:一列,一列...,第二行:一列,一列....);
- rect.bottom = nFixedRowHeight-1;
- for (row = minVisibleRow; row <= maxVisibleRow; row++)
- {
- if (GetRowHeight(row) <= 0) continue;
- rect.top = rect.bottom+1;
- rect.bottom = rect.top + GetRowHeight(row)-1;
- // rect.bottom = bottom pixel of previous row
- if (rect.top > clipRect.bottom)
- break; // Gone past cliprect
- if (rect.bottom < clipRect.top)
- continue; // Reached cliprect yet?
- rect.right = -1;
- for (col = 0; col < m_nFixedCols; col++)
- {
- if (GetColumnWidth(col) <= 0) continue;
- rect.left = rect.right+1;
- rect.right = rect.left + GetColumnWidth(col)-1;
- if (rect.left > clipRect.right)
- break; // gone past cliprect
- if (rect.right < clipRect.left)
- continue; // Reached cliprect yet?
- pCell = GetCell(row, col);
- if (pCell)
- {
- if(col==0)
- {
- CString str;
- str.Format("%d",row);
- pCell->SetText(str);
- }
- pCell->Draw(pDC, row, col, rect, FALSE);
- }
- }
- }
- /////////////////////////////////////////////////////////////
- // draw fixed row cells 0..m_nFixedRows, m_nFixedCols..n
- //画固定的行(列标头):(第一行:一列,一列...,第二行:一列,一列....);
- rect.bottom = -1;
- for (row = 0; row < m_nFixedRows; row++)
- {
- if (GetRowHeight(row) <= 0) continue;
- rect.top = rect.bottom+1;
- rect.bottom = rect.top + GetRowHeight(row)-1;
- // rect.bottom = bottom pixel of previous row
- if (rect.top > clipRect.bottom)
- break; // Gone past cliprect
- if (rect.bottom < clipRect.top)
- continue; // Reached cliprect yet?
- rect.right = nFixedColWidth-1;
- for (col = minVisibleCol; col <= maxVisibleCol; col++)
- {
- if (GetColumnWidth(col) <= 0) continue;
- rect.left = rect.right+1;
- rect.right = rect.left + GetColumnWidth(col)-1;
- if (rect.left > clipRect.right)
- break; // gone past cliprect
- if (rect.right < clipRect.left)
- continue; // Reached cliprect yet?
- pCell = GetCell(row, col);
- if (pCell)
- {
- pCell->Draw(pDC, row, col, rect, FALSE);
- }
- }
- }
- ///////////////////////////////////////////////////////////////////
- // draw rest of non-fixed cells
- //画剩余的非固定的单元格:(第一行:一列,一列...,第二行:一列,一列....);
- rect.bottom = nFixedRowHeight-1;
- for (row = minVisibleRow; row <= maxVisibleRow; row++)
- {
- if (GetRowHeight(row) <= 0) continue;
- rect.top = rect.bottom+1;
- rect.bottom = rect.top + GetRowHeight(row)-1;
- // rect.bottom = bottom pixel of previous row
- if (rect.top > clipRect.bottom)
- break; // Gone past cliprect
- if (rect.bottom < clipRect.top)
- continue; // Reached cliprect yet?
- rect.right = nFixedColWidth-1;
- for (col = minVisibleCol; col <= maxVisibleCol; col++)
- {
- if (GetColumnWidth(col) <= 0) continue;
- rect.left = rect.right+1;
- rect.right = rect.left + GetColumnWidth(col)-1;
- if (rect.left > clipRect.right)
- break; // gone past cliprect
- if (rect.right < clipRect.left)
- continue; // Reached cliprect yet?
- pCell = GetCell(row, col);
- // TRACE(_T("Cell %d,%d type: %sn"), row, col, pCell->GetRuntimeClass()->m_lpszClassName);
- if (pCell)
- {
- pCell->Draw(pDC, row, col, rect, FALSE);
- }
- }
- }
- CPen pen;
- pen.CreatePen(PS_SOLID, 0, m_crGridLineColour);
- pDC->SelectObject(&pen);
- // draw vertical lines (drawn at ends of cells)
- //画垂直分隔线:
- if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_VERT)
- {
- int x = nFixedColWidth;
- for (col =minVisibleCol; col <= maxVisibleCol; col++)
- {
- if (GetColumnWidth(col) <= 0) continue;
- x += GetColumnWidth(col);
- pDC->MoveTo(x-1, nFixedRowHeight);
- pDC->LineTo(x-1, rect.bottom);
- }
- }
- // draw horizontal lines (drawn at bottom of each cell)
- //画水平分隔线
- if (m_nGridLines == GVL_BOTH || m_nGridLines == GVL_HORZ)
- {
- int y = nFixedRowHeight;
- for (row = minVisibleRow; row <= maxVisibleRow; row++)
- {
- if (GetRowHeight(row) <= 0) continue;
- y += GetRowHeight(row);
- pDC->MoveTo(nFixedColWidth, y-1);
- pDC->LineTo(rect.right, y-1);
- }
- }
- pDC->SelectStockObject(NULL_PEN);
- }
- int CGridCtrl::GetFixedRowHeight() const
- {
- int nHeight = 0;
- for (int i = 0; i < m_nFixedRows; i++)
- nHeight += GetRowHeight(i);
- return nHeight;
- }
- int CGridCtrl::GetFixedColumnWidth() const
- {
- int nWidth = 0;
- for (int i = 0; i < m_nFixedCols; i++)
- nWidth += GetColumnWidth(i);
- return nWidth;
- }
- int CGridCtrl::GetRowHeight(int nRow) const
- {
- ASSERT(nRow >= 0 && nRow < m_nRows);
- if (nRow < 0 || nRow >= m_nRows)
- return -1;
- return m_arRowHeights[nRow];
- }
- int CGridCtrl::GetColumnWidth(int nCol) const
- {
- ASSERT(nCol >= 0 && nCol < m_nCols);
- if (nCol < 0 || nCol >= m_nCols)
- return -1;
- return m_arColWidths[nCol];
- }
- // Gets the first non-fixed cell ID
- CCellID CGridCtrl::GetTopleftNonFixedCell(BOOL bForceRecalculation /*=FALSE*/)
- {
- // Used cached value if possible
- // 如果可能使用保存的值
- if (m_idTopLeftCell.IsValid() && !bForceRecalculation)//因为bForceRecalculation却省为假
- //所以只要IsValid()返回真就执行
- return m_idTopLeftCell;
- int nVertScroll =GetScrollPos(SB_VERT), //没有滚动条或没有设置初始位置或没有滚动,
- nHorzScroll =GetScrollPos(SB_HORZ); //会返回0值
- m_idTopLeftCell.col = m_nFixedCols;//先赋值(却省情况下这是当然的)
- int nRight = 0;
- //这个循环比较特别,主要目的是要作m_idTopLeftCell.col++的操作,
- //因为各列的宽可能不一样,不能对计数器nRight简单的++,
- //因为nHorzScroll是以屏幕像素为单位的。
- while (nRight < nHorzScroll && m_idTopLeftCell.col < (GetColumnCount()-1))
- nRight += GetColumnWidth(m_idTopLeftCell.col++);//作m_idTopLeftCell.col++操作
- //的同时对nRight每次增加一列的宽
- //道理同上:
- m_idTopLeftCell.row = m_nFixedRows;
- int nTop = 0;
- while (nTop < nVertScroll && m_idTopLeftCell.row < (GetRowCount()-1))
- nTop += GetRowHeight(m_idTopLeftCell.row++);
- TRACE2("TopLeft cell is row %d, col %dn",m_idTopLeftCell.row, m_idTopLeftCell.col);
- return m_idTopLeftCell;//返回当前的左上角单元格ID(就是行列号)
- }
- // This gets even partially visible cells
- // 得到可见部分的单元格:
- CCellRange CGridCtrl::GetVisibleNonFixedCellRange(LPRECT pRect /*=NULL*/,
- BOOL bForceRecalculation /*=FALSE*/)
- {
- CRect rect;
- GetClientRect(rect);//窗口的区域
- //左上角非固定单元格的ID:
- //GetTopleftNonFixedCell会根据滚动条的位置返回不同的左上角非固定单元格。
- //有了这个功能,GetVisibleNonFixedCellRange才会返回不同的单元格范围
- CCellID idTopLeft = GetTopleftNonFixedCell(bForceRecalculation);//左上角非固定单元格的ID
- // calc bottom
- // 找到底部(可视单元格区域的底部)
- int bottom = GetFixedRowHeight();//固定行的高
- for (int i = idTopLeft.row; i < GetRowCount(); i++)
- {
- bottom += GetRowHeight(i);//为bottom增加那一行的高
- //因为可能用户调整后各行的高都不一样
- if (bottom >= rect.bottom)//如果bottom大于等于窗口的底
- {
- bottom = rect.bottom;//botto就等于窗口的底
- break; //然后就跳出循环
- }
- }
- int maxVisibleRow = min(i, GetRowCount() - 1);//在i和总行数-1中取小
- // calc right
- //找到右边界
- int right = GetFixedColumnWidth();//固定列的宽
- for (i = idTopLeft.col; i < GetColumnCount(); i++)
- {
- right += GetColumnWidth(i);//为right增加那一列的宽
- //因为用户调整后各列的宽也可能不一样
- if (right >= rect.right)//如果right大于等于窗口的right
- {
- right = rect.right; //right就等于窗口的right
- break; //然后就跳出循环
- }
- }
- int maxVisibleCol = min(i, GetColumnCount() - 1);//在i和总列数-1中取小
- if (pRect)
- {
- //对pRect初始化:
- pRect->left = pRect->top = 0;
- pRect->right = right;
- pRect->bottom = bottom;
- }
- //返回可视部分的单元格范围:
- return CCellRange(idTopLeft.row, idTopLeft.col, maxVisibleRow, maxVisibleCol);
- }
- BOOL CGridCtrl::OnEraseBkgnd(CDC* pDC)
- {
- return true;
- // return CWnd::OnEraseBkgnd(pDC);
- }
- BOOL CGridCtrl::SetItemText(int nRow, int nCol, LPCTSTR str)
- {
- CGridCellBase* pCell = GetCell(nRow, nCol);
- if (!pCell)
- return FALSE;
- pCell->SetText(str);
- return TRUE;
- }
- void CGridCtrl::SetSortColumn(int nCol)
- {
- // if (m_nSortColumn >= 0)
- // InvalidateCellRect(0, m_nSortColumn);
- m_nSortColumn = nCol;
- // if (nCol >= 0)
- // InvalidateCellRect(0, nCol);
- }
- void CGridCtrl::OnLButtonDown(UINT nFlags, CPoint point)
- {
- CCellID cellid=GetCellFromPt(point);//得到鼠标点中的CellID
- int row=cellid.row;
- int col=cellid.col;
- COLORREF lastclr;
- CDC* pDC=GetDC();
- m_bLMouseButtonDown = TRUE;//设置鼠标按下标志(OnMouseMove()中需要)
- m_LeftClickDownPoint = point;//鼠标点(OnMouseMove()中需要)
- m_LeftClickDownCell = GetCellFromPt(point);//鼠标点中的单元格ID(重要)
- CRect cellrect;
- GetCellRect(m_LeftClickDownCell,&cellrect);
- if(m_LeftClickDownPoint.x<=(cellrect.left+5))//如果鼠标点在此范围内,就设定为左边的单元格
- m_LeftClickDownCell.col--; //这样,就限制只能从右边界调整单元格宽度
- if (m_bAllowColumnResize && MouseOverColumnResizeArea(point))
- {
- SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));//改变光标
- }
- if(this->IsValid(m_SelectedCell))//m_SelectedCell保存上一次选择的单元格,因为没有初始化
- //所以第一次是非法的。
- //如果它合法:
- {
- CGridCellBase* pcell=GetCell(row,col);//得到鼠标点中的单元格
- if(m_SelectedCell!=cellid)//如果m_SelectedCell不是当前鼠标点中的
- {
- if(pcell)
- {
- lastclr=GetDefaultCell(FALSE, FALSE)->GetBackClr();//缺省的非固定单元格的背景色
- pcell->SetBackClr(RGB(128,196,255));//设置新的背景色
- CGridCellBase* pSelcell=GetCell(m_SelectedCell.row,m_SelectedCell.col);//得到上次选中的单元格
- pSelcell->SetBackClr(lastclr);//恢复他的背景色
- m_SelectedCell=cellid;//保存这次选中的单元格
- }
- }
- }
- else//m_SelectedCell为非法(第一次肯定是的)
- {
- CGridCellBase* pcell=GetCell(row,col);
- if(pcell)
- {
- lastclr=GetDefaultCell(FALSE, FALSE)->GetBackClr();
- pcell->SetBackClr(RGB(128,196,255));
- m_SelectedCell=cellid;
- }
- }
- if(m_LeftClickDownCell.row < GetFixedRowCount())
- {
- OnFixedRowClick(m_LeftClickDownCell);
- }
- Invalidate();
- // RedrawWindow();
- CWnd::OnLButtonDown(nFlags, point);
- }
- // If resizing or cell counts/sizes change, call this - it'll fix up the scroll bars
- void CGridCtrl::ResetScrollBars()
- {
- // Force a refresh.
- m_idTopLeftCell.row = -1;
- if (!m_bAllowDraw || !::IsWindow(GetSafeHwnd()))
- return;
- CRect rect;
- // This would have caused OnSize event - Brian
- //EnableScrollBars(SB_BOTH, FALSE);
- GetClientRect(rect);
- if (rect.left == rect.right || rect.top == rect.bottom)//没有窗口面积就返回
- return;
- if (IsVisibleVScroll())
- rect.right += GetSystemMetrics(SM_CXVSCROLL) + GetSystemMetrics(SM_CXBORDER);
- //GetSystemMetrics返回显示器的屏幕尺寸
- //GetSystemMetrics(SM_CXVSCROLL)得到垂直滚动条的宽
- if (IsVisibleHScroll())
- rect.bottom += GetSystemMetrics(SM_CYHSCROLL) + GetSystemMetrics(SM_CYBORDER);
- rect.left += GetFixedColumnWidth();//左边界右移
- rect.top += GetFixedRowHeight();//顶边界下移
- if (rect.left >= rect.right || rect.top >= rect.bottom)//不显示滚动条的条件
- {
- // EnableScrollBarCtrl(SB_BOTH, FALSE);
- return;
- }
- //可见区域:
- CRect VisibleRect(GetFixedColumnWidth(), GetFixedRowHeight(),
- rect.right, rect.bottom);
- //虚区域:
- CRect VirtualRect(GetFixedColumnWidth(), GetFixedRowHeight(),
- GetVirtualWidth(), GetVirtualHeight());
- // Removed to fix single row scrollbar problem (Pontus Goffe)
- // CCellRange visibleCells = GetUnobstructedNonFixedCellRange();
- // if (!IsValid(visibleCells)) return;
- //TRACE(_T("Visible: %d x %d, Virtual %d x %d. H %d, V %dn"),
- // VisibleRect.Width(), VisibleRect.Height(),
- // VirtualRect.Width(), VirtualRect.Height(),
- // IsVisibleHScroll(), IsVisibleVScroll());
- // If vertical scroll bar, horizontal space is reduced
- //如果显示垂直滚动条,水平空间会减少一个滚动条的宽度
- if (VisibleRect.Height() < VirtualRect.Height())
- VisibleRect.right -= ::GetSystemMetrics(SM_CXVSCROLL);
- // If horz scroll bar, vert space is reduced
- //如果显示水平滚动条,垂直空间会减少一个滚动条的宽度
- if (VisibleRect.Width() < VirtualRect.Width())
- VisibleRect.bottom -= ::GetSystemMetrics(SM_CYHSCROLL);
- // Recheck vertical scroll bar
- //if (VisibleRect.Height() < VirtualRect.Height())
- // VisibleRect.right -= ::GetSystemMetrics(SM_CXVSCROLL);
- if (VisibleRect.Height() < VirtualRect.Height())
- {
- //EnableScrollBars(SB_VERT, TRUE);
- m_nVScrollMax = VirtualRect.Height() - 1;
- }
- else
- {
- // EnableScrollBars(SB_VERT, FALSE);
- m_nVScrollMax = 0;
- }
- if (VisibleRect.Width() < VirtualRect.Width())
- {
- // EnableScrollBars(SB_HORZ, TRUE);
- m_nHScrollMax = VirtualRect.Width() - 1;
- }
- else
- {
- // EnableScrollBars(SB_HORZ, FALSE);
- m_nHScrollMax = 0;
- }
- ASSERT(m_nVScrollMax < INT_MAX && m_nHScrollMax < INT_MAX); // This should be fine
- /* Old code - CJM
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_PAGE;
- si.nPage = (m_nHScrollMax>0)? VisibleRect.Width() : 0;
- SetScrollInfo(SB_HORZ, &si, FALSE);
- si.nPage = (m_nVScrollMax>0)? VisibleRect.Height() : 0;
- SetScrollInfo(SB_VERT, &si, FALSE);
- SetScrollRange(SB_VERT, 0, m_nVScrollMax, TRUE);
- SetScrollRange(SB_HORZ, 0, m_nHScrollMax, TRUE);
- */
- // New code - Paul Runstedler
- CMyGridFrame *pWnd=(CMyGridFrame*)(this->GetParent());
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_PAGE | SIF_RANGE;
- si.nPage = (m_nHScrollMax>0)? VisibleRect.Width() : 0;
- si.nMin = 0;
- si.nMax = m_nHScrollMax;
- //CWnd* pWnd=GetParent();
- SetScrollInfo(SB_HORZ,&si, TRUE);
- si.fMask |= SIF_DISABLENOSCROLL;
- si.nPage = (m_nVScrollMax>0)? VisibleRect.Height() : 0;
- si.nMin = 0;
- si.nMax = m_nVScrollMax;
- SetScrollInfo(SB_VERT,&si, TRUE);
- }
- void CGridCtrl::EnableScrollBars(int nBar, BOOL bEnable /*=TRUE*/)
- {
- CMyGridFrame* pWnd=(CMyGridFrame*)(this->GetParent());
- if (bEnable)
- {
- if (!IsVisibleHScroll() && (nBar == SB_HORZ || nBar == SB_BOTH))
- {
- m_nBarState |= GVL_HORZ;
- pWnd->EnableScrollBarCtrl(SB_HORZ, bEnable);
- //CWnd::EnableScrollBarCtrl(SB_HORZ, bEnable);
- }
- if (!IsVisibleVScroll() && (nBar == SB_VERT || nBar == SB_BOTH))
- {
- m_nBarState |= GVL_VERT;
- pWnd->EnableScrollBarCtrl(SB_VERT, bEnable);
- //CWnd::EnableScrollBarCtrl(SB_VERT, bEnable);
- }
- }
- else
- {
- if ( IsVisibleHScroll() && (nBar == SB_HORZ || nBar == SB_BOTH))
- {
- m_nBarState &= ~GVL_HORZ;
- pWnd->EnableScrollBarCtrl(SB_HORZ, bEnable);
- //CWnd::EnableScrollBarCtrl(SB_HORZ, bEnable);
- }
- if ( IsVisibleVScroll() && (nBar == SB_VERT || nBar == SB_BOTH))
- {
- m_nBarState &= ~GVL_VERT;
- pWnd->EnableScrollBarCtrl(SB_VERT, bEnable);
- //CWnd::EnableScrollBarCtrl(SB_VERT, bEnable);
- }
- }
- }
- long CGridCtrl::GetVirtualWidth() const
- {
- long lVirtualWidth = 0;
- int iColCount = GetColumnCount();
- for (int i = 0; i < iColCount; i++)
- lVirtualWidth += m_arColWidths[i];
- return lVirtualWidth;
- }
- long CGridCtrl::GetVirtualHeight() const
- {
- long lVirtualHeight = 0;
- int iRowCount = GetRowCount();
- for (int i = 0; i < iRowCount; i++)
- lVirtualHeight += m_arRowHeights[i];
- return lVirtualHeight;
- }
- void CGridCtrl::OnSize(UINT nType, int cx, int cy)
- {
- CWnd::OnSize(nType, cx, cy);
- // this->EnableScrollBarCtrl(SB_BOTH,FALSE);//不能加这一句。否则会出 "Debug Assertion Failed"错误。
- //你不能禁止滚动控件。
- //你只是把滚动控制权交给了父窗口。
- //通过重载GetScrollBarCtrl()把滚动控制权交给了CMyGridFrame.
- ResetScrollBars();
- }
- void CGridCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- int scrollPos =GetScrollPos32(SB_HORZ);
- CCellID idTopLeft = GetTopleftNonFixedCell();
- CRect rect;
- GetClientRect(rect);
- switch (nSBCode)
- {
- case SB_LINERIGHT:
- if (scrollPos < m_nHScrollMax)
- {
- // may have contiguous hidden columns. Blow by them
- while (idTopLeft.col < (GetColumnCount()-1)
- && GetColumnWidth( idTopLeft.col) < 1 )
- {
- idTopLeft.col++;
- }
- int xScroll = GetColumnWidth(idTopLeft.col);
- SetScrollPos32(SB_HORZ, scrollPos + xScroll);
- if (GetScrollPos32(SB_HORZ) == scrollPos)
- break; // didn't work
- rect.left = GetFixedColumnWidth();
- //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 iColToUse = idTopLeft.col-1;
- // may have contiguous hidden columns. Blow by them
- while( iColToUse > GetFixedColumnCount()
- && GetColumnWidth( iColToUse) < 1 )
- {
- iColToUse--;
- }
- int xScroll = GetColumnWidth(iColToUse);
- SetScrollPos32(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);
- SetScrollPos32(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);
- SetScrollPos32(SB_HORZ, pos);
- rect.left = GetFixedColumnWidth();
- InvalidateRect(rect);
- }
- break;
- case SB_THUMBPOSITION:
- case SB_THUMBTRACK:
- {
- SetScrollPos32(SB_HORZ, GetScrollPos32(SB_HORZ, TRUE));
- m_idTopLeftCell.row = -1;
- CCellID idNewTopLeft = GetTopleftNonFixedCell();
- if (idNewTopLeft != idTopLeft)
- {
- rect.left = GetFixedColumnWidth();
- InvalidateRect(rect);
- }
- }
- break;
- case SB_LEFT:
- if (scrollPos > 0)
- {
- SetScrollPos32(SB_HORZ, 0);
- Invalidate();
- }
- break;
- case SB_RIGHT:
- if (scrollPos < m_nHScrollMax)
- {
- SetScrollPos32(SB_HORZ, m_nHScrollMax);
- Invalidate();
- }
- break;
- default:
- break;
- }
- // CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
- }
- // Get/Set scroll position using 32 bit functions
- int CGridCtrl::GetScrollPos32(int nBar, BOOL bGetTrackPos /* = FALSE */)
- {
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- if (bGetTrackPos)
- {
- if (GetScrollInfo(nBar,&si, SIF_TRACKPOS))
- return si.nTrackPos;
- }
- else
- {
- if (GetScrollInfo(nBar,&si, SIF_POS))
- return si.nPos;
- }
- return 0;
- }
- BOOL CGridCtrl::SetScrollPos32(int nBar, int nPos, BOOL bRedraw /* = TRUE */)
- {
- m_idTopLeftCell.row = -1;
- SCROLLINFO si;
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_POS;
- si.nPos = nPos;
- return SetScrollInfo(nBar, &si, bRedraw);
- }
- void CGridCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- // Get the scroll position ourselves to ensure we get a 32 bit value
- int scrollPos = GetScrollPos32(SB_VERT);
- CCellID idTopLeft = GetTopleftNonFixedCell();
- CRect rect;
- GetClientRect(rect);
- switch (nSBCode)
- {
- case SB_LINEDOWN:
- if (scrollPos < m_nVScrollMax)
- {
- // may have contiguous hidden rows. Blow by them
- while( idTopLeft.row < (GetRowCount()-1)
- && GetRowHeight( idTopLeft.row) < 1 )
- {
- idTopLeft.row++;
- }
- int yScroll = GetRowHeight(idTopLeft.row);
- SetScrollPos32(SB_VERT, scrollPos + yScroll);
- if (GetScrollPos32(SB_VERT) == scrollPos)
- break; // didn't work
- rect.top = GetFixedRowHeight();
- //rect.top = GetFixedRowHeight() + yScroll;
- //ScrollWindow(0, -yScroll, rect);
- //rect.top = rect.bottom - yScroll;
- InvalidateRect(rect);
- }
- break;
- case SB_LINEUP:
- if (scrollPos > 0 && idTopLeft.row > GetFixedRowCount())
- {
- int iRowToUse = idTopLeft.row-1;
- // may have contiguous hidden rows. Blow by them
- while( iRowToUse > GetFixedRowCount()
- && GetRowHeight( iRowToUse) < 1 )
- {
- iRowToUse--;
- }
- int yScroll = GetRowHeight( iRowToUse);
- SetScrollPos32(SB_VERT, max(0, scrollPos - yScroll));
- rect.top = GetFixedRowHeight();
- //ScrollWindow(0, yScroll, rect);
- //rect.bottom = rect.top + yScroll;
- InvalidateRect(rect);
- }
- break;
- case SB_PAGEDOWN:
- if (scrollPos < m_nVScrollMax)
- {
- rect.top = GetFixedRowHeight();
- scrollPos = min(m_nVScrollMax, scrollPos + rect.Height());
- SetScrollPos32(SB_VERT, scrollPos);
- rect.top = GetFixedRowHeight();
- InvalidateRect(rect);
- }
- break;
- case SB_PAGEUP:
- if (scrollPos > 0)
- {
- rect.top = GetFixedRowHeight();
- int offset = -rect.Height();
- int pos = max(0, scrollPos + offset);
- SetScrollPos32(SB_VERT, pos);
- rect.top = GetFixedRowHeight();
- InvalidateRect(rect);
- }
- break;
- case SB_THUMBPOSITION:
- case SB_THUMBTRACK:
- {
- SetScrollPos32(SB_VERT, GetScrollPos32(SB_VERT, TRUE));
- m_idTopLeftCell.row = -1;
- CCellID idNewTopLeft = GetTopleftNonFixedCell();
- if (idNewTopLeft != idTopLeft)
- {
- rect.top = GetFixedRowHeight();
- InvalidateRect(rect);
- }
- }
- break;
- case SB_TOP:
- if (scrollPos > 0)
- {
- SetScrollPos32(SB_VERT, 0);
- Invalidate();
- }
- break;
- case SB_BOTTOM:
- if (scrollPos < m_nVScrollMax)
- {
- SetScrollPos32(SB_VERT, m_nVScrollMax);
- Invalidate();
- }
- default:
- break;
- }
- // CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
- }
- // Custom background erasure. This gets called from within the OnDraw function,
- // 自定义的背景擦除函数,它在OnDraw函数内部被呼叫
- // since we will (most likely) be using a memory DC to stop flicker. If we just
- // 然后,我们要用一个内存DC来消除闪烁。如果我们只是
- // erase the background normally through OnEraseBkgnd, and didn't fill the memDC's
- // 正常的通过OnEraseBkgnd函数去擦除背景,而不用颜色填充内存DC
- // selected bitmap with colour, then all sorts of vis problems would occur
- // 选择的位图,将会出现各式各样的难题。
- void CGridCtrl::EraseBkgnd(CDC *pDC)
- {
- //经过试验,其实要消除闪烁只要在OnEraseBkgnd中什么也不做,而只返回真就行了。
- //而这个EraseBkgnd函数的功能完全可以是OnDraw的一部分(因为它本来就是在OnDraw中调用的)。
- //但如果不使用内存DC,而只使用本函数又会产生闪烁。
- CRect VisRect, ClipRect, rect;
- CBrush FixedRowColBack(GetDefaultCell(TRUE, TRUE)->GetBackClr()),
- FixedRowBack(GetDefaultCell(TRUE, FALSE)->GetBackClr()),
- FixedColBack(GetDefaultCell(FALSE, TRUE)->GetBackClr()),
- TextBack(GetDefaultCell(FALSE, FALSE)->GetBackClr());
- CBrush Back(GetGridBkColor());
- //CBrush Back(GetTextBkColor());
- if (pDC->GetClipBox(ClipRect) == ERROR)
- return ;
- // ClipRect.bottom=ClipRect.bottom-22;
- // ClipRect.right=ClipRect.right-22;
- GetVisibleNonFixedCellRange(VisRect);
- int nFixedColumnWidth = GetFixedColumnWidth();
- int nFixedRowHeight = GetFixedRowHeight();
- // Draw Fixed row/column background
- // 画固定行/列背景:
- if (ClipRect.left < nFixedColumnWidth && ClipRect.top < nFixedRowHeight)
- pDC->FillRect(CRect(ClipRect.left, ClipRect.top,
- nFixedColumnWidth, nFixedRowHeight),
- &FixedRowColBack);
- // Draw Fixed columns background
- // 画固定列背景:
- //VisRect.bottom=nFixedRowHeight*GetRowCount();
- if (ClipRect.left < nFixedColumnWidth && ClipRect.top < VisRect.bottom)
- pDC->FillRect(CRect(ClipRect.left, ClipRect.top,
- nFixedColumnWidth, VisRect.bottom),
- &FixedColBack);
- // Draw Fixed rows background
- // 画固定行背景:
- if (ClipRect.top < nFixedRowHeight &&
- ClipRect.right > nFixedColumnWidth && ClipRect.left < VisRect.right)
- pDC->FillRect(CRect(nFixedColumnWidth-1, ClipRect.top,
- VisRect.right, nFixedRowHeight),
- &FixedRowBack);
- // 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);
- }
- // Get cell from point.
- // point - client coordinates
- // bAllowFixedCellCheck - if TRUE then fixed cells are checked
- //从鼠标点得到单元格ID:
- CCellID CGridCtrl::GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck /*=TRUE*/)
- {
- CCellID cellID; // return value
- CCellID idTopLeft = GetTopleftNonFixedCell();//得到可见范围内最左上角单元格的ID
- if (!bAllowFixedCellCheck && !IsValid(idTopLeft))
- return cellID;//???
- // calculate column index
- // 找列号
- int fixedColWidth = GetFixedColumnWidth();//得到固定列宽(所有固定列宽的和)
- if (point.x < 0 || (!bAllowFixedCellCheck && point.x < fixedColWidth)) // not in window(不在窗口内)
- cellID.col = -1;//使cellID非法
- else if (point.x < fixedColWidth) // in fixed col(在固定列内)
- {
- int xpos = 0;
- int col = 0;
- while (col < m_nFixedCols)//从第0列开始
- {
- xpos += GetColumnWidth(col);//增加一列的宽
- if (xpos > point.x)
- break;//如果第一次就跳出,列号col就是0。
- col++; //列号增加1
- }
- //当col=m_nFixedCols时循环结束,所以最后一次是col=m_nFixedCols。
- cellID.col = col;//最后得到列号
- //CString str;
- //str.Format("%d",col);
- //MessageBox(str);
- }
- else // in non-fixed col(在非固定列)
- {
- int xpos = fixedColWidth;//固定列宽(所有固定列宽的和)
- int col = idTopLeft.col; //左上角非固定单元格,其值=m_nFixedCols;
- while ( col < GetColumnCount())//GetColumnCount返回总列数
- {
- xpos += GetColumnWidth(col);////增加一列的宽
- if (xpos > point.x)
- break;//如果第一次就跳出,列号col就是左上角非固定单元格,其值=m_nFixedCols;
- col++;//列号增加1
- }
- //当col=GetColumnCount()时循环结束,所以最后是col=GetColumnCount()。
- //但是col是从0开始的,如果到col=GetColumnCount()会多一列。
- //所以需要修正:
- if (col >= GetColumnCount())//
- cellID.col = -1;
- else
- cellID.col = col;
- }
- // calculate row index
- // 找行号(类似找列号,注释略)
- int fixedRowHeight = GetFixedRowHeight();//得到固定行的高(所有固定行的高的和)
- if (point.y < 0 || (!bAllowFixedCellCheck && point.y < fixedRowHeight)) // not in window(不在窗口内)
- cellID.row = -1;//使cellID非法
- else if (point.y < fixedRowHeight) // in fixed col(在固定列)
- {
- int ypos = 0;
- int row = 0;
- while (row < m_nFixedRows)
- {
- ypos += GetRowHeight(row);
- if (ypos > point.y)
- break;
- row++;
- }
- cellID.row = row;
- }
- else
- {
- int ypos = fixedRowHeight;
- int row = idTopLeft.row; //m_nFixedRows;
- while ( row < GetRowCount() )
- {
- ypos += GetRowHeight(row);
- if (ypos > point.y)
- break;
- row++;
- }
- if (row >= GetRowCount())
- cellID.row = -1;
- else
- cellID.row = row;
- }
- return cellID;//返回单元格ID
- }
- // Is a given cell designation valid (ie within the bounds of our number
- // of columns/rows)?
- //合法性检验
- BOOL CGridCtrl::IsValid(int nRow, int nCol) const
- {
- return (nRow >= 0 && nRow < m_nRows && nCol >= 0 && nCol < m_nCols);
- }
- BOOL CGridCtrl::IsValid(const CCellID& cell) const
- {
- return IsValid(cell.row, cell.col);
- }
- // Is a given cell range valid (ie within the bounds of our number
- // of columns/rows)?
- BOOL CGridCtrl::IsValid(const CCellRange& range) const
- {
- return (range.GetMinRow() >= 0 && range.GetMinCol() >= 0 &&
- range.GetMaxRow() >= 0 && range.GetMaxCol() >= 0 &&
- range.GetMaxRow() < m_nRows && range.GetMaxCol() < m_nCols &&
- range.GetMinRow() <= range.GetMaxRow() && range.GetMinCol() <= range.GetMaxCol());
- }
- void CGridCtrl::OnMouseMove(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);
- if( MouseOverColumnResizeArea(point))
- {
- SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
- //m_LastMousePoint = point;
- 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,%dn",
- // 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 <= hi)
- {
- // Find the first element that is greater than or equal to the partition
- // element starting from the left Index.
- if (bAscending)
- while (lo < high && pfnCompare( (LPARAM)GetCell(lo, nCol), (LPARAM) pMidCell, data)< 0)
- ++lo;
- else
- while (lo < high && pfnCompare((LPARAM)GetCell(lo, nCol), pMidCell, data) > 0)
- ++lo;
- // Find an element that is smaller than or equal to the partition
- // element starting from the right Index.
- if (bAscending)
- while (hi > low && pfnCompare((LPARAM)GetCell(hi, nCol), pMidCell, data) > 0)
- --hi;
- else
- while (hi > low && pfnCompare((LPARAM)GetCell(hi, nCol), pMidCell, data) < 0)
- --hi;
- // If the indexes have not crossed, swap if the items are not equal
- if (lo <= hi)
- {
- // swap only if the items are not equal
- if (pfnCompare((LPARAM)GetCell(lo, nCol), (LPARAM)GetCell(hi, nCol), data) != 0)
- {
- for (int col = 0; col < GetColumnCount(); col++)
- {
- CGridCellBase *pCell = GetCell(lo, col);
- SetCell(lo, col, GetCell(hi, col));
- SetCell(hi, col, pCell);
- }
- UINT nRowHeight = m_arRowHeights[lo];
- m_arRowHeights[lo] = m_arRowHeights[hi];
- m_arRowHeights[hi] = nRowHeight;
- }
- ++lo;
- --hi;
- }
- }
- // If the right index has not reached the left side of array
- // must now sort the left partition.
- if (low < hi)
- SortItems(pfnCompare, nCol, bAscending, data, low, hi);
- // If the left index has not reached the right side of array
- // must now sort the right partition.
- if (lo < high)
- SortItems(pfnCompare, nCol, bAscending, data, lo, high);
- return TRUE;
- }
- // Sorts on a given column using the cell text
- BOOL CGridCtrl::SortTextItems(int nCol, BOOL bAscending, LPARAM data /* = 0 */)
- {
- SetSortColumn(nCol);
- SetSortAscending(bAscending);
- // ResetSelectedRange();
- // SetFocusCell(-1, - 1);
- return CGridCtrl::SortItems(pfnCellTextCompare, nCol, bAscending, data);
- }
- int CALLBACK CGridCtrl::pfnCellTextCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
- {
- UNUSED_ALWAYS(lParamSort);
- CGridCellBase* pCell1 = (CGridCellBase*) lParam1;
- CGridCellBase* pCell2 = (CGridCellBase*) lParam2;
- if (!pCell1 || !pCell2) return 0;
- return _tcscmp(pCell1->GetText(), pCell2->GetText());//作字符串的比较
- }
- int CALLBACK CGridCtrl::pfnCellNumericCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
- {
- UNUSED_ALWAYS(lParamSort);
- CGridCellBase* pCell1 = (CGridCellBase*) lParam1;
- CGridCellBase* pCell2 = (CGridCellBase*) lParam2;
- if (!pCell1 || !pCell2) return 0;
- //double// float
- double nValue1 = atof(pCell1->GetText());//_ttol(pCell1->GetText());
- double nValue2 = atof(pCell2->GetText());//_ttol(pCell2->GetText());
- //作数字的比较:
- if (nValue1 < nValue2)
- return -1;
- else if (nValue1 == nValue2)
- return 0;
- else
- return 1;
- }
- int CGridCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CWnd::OnCreate(lpCreateStruct) == -1)
- return -1;
- TRY
- {
- //初始化数组
- m_arRowHeights.SetSize(m_nRows); // initialize row heights
- m_arColWidths.SetSize(m_nCols); // initialize column widths
- }
- CATCH (CMemoryException, e)
- {
- e->ReportError();
- return FALSE;
- }
- END_CATCH
- //填写数组:
- int i;
- for (i = 0; i < m_nRows; i++)
- m_arRowHeights[i] = m_cellDefault.GetHeight();
- for (i = 0; i < m_nCols; i++)
- m_arColWidths[i] = m_cellDefault.GetWidth();
- SetTimer(2,30000,NULL);//设置定时器,间隔30秒
- return 0;
- }
- void CGridCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
- {
- CCellID cellid=GetCellFromPt(point);//得到鼠标点中的CellID
- int row=cellid.row;
- int col=cellid.col;
- CGridCellBase* pCell=GetCell(row,1);//只找股票代码
- CString str=pCell->GetText();//需要把str发送给父窗口
- int strlen=str.GetLength();
- if(strlen==0)
- // return;
- str="600255";
- CMyGridFrame* pParent=(CMyGridFrame*)GetParent();
- pParent->m_szLabel=str;
- pParent->OnStringChange();
- CWnd::OnLButtonDblClk(nFlags, point);
- }
- void CGridCtrl::ClearCells()
- {
- CRect rect;
- this->GetClientRect(&rect);
- CCellRange Selection=this->GetVisibleNonFixedCellRange(rect);
- for (int row = Selection.GetMinRow(); row <= Selection.GetMaxRow(); row++)
- {
- for (int col = Selection.GetMinCol(); col <= Selection.GetMaxCol(); col++)
- {
- // don't clear hidden cells
- if ( m_arRowHeights[row] > 0 && m_arColWidths[col] > 0 )
- {
- SetItemText(row, col, _T(""));
- SetItemBkColor(row,col,GetDefaultCell(FALSE,FALSE)->GetBackClr());
- }
- }
- }
- Refresh();
- }
- void CGridCtrl::OnTimer(UINT nIDEvent)
- {
- //if(m_nSortColumn!=-1)
- //{
- SortItems(GetSortColumn(),GetSortAscending());
- Refresh();
- //}
- CWnd::OnTimer(nIDEvent);
- }
- CScrollBar* CGridCtrl::GetScrollBarCtrl(int nBar) const
- {
- return ((CMyGridFrame*)GetParent())->GetScrollBar(nBar);
- // return CWnd::GetScrollBarCtrl(nBar);
- }
- void CGridCtrl::OnDestroy()
- {
- CWnd::OnDestroy();
- KillTimer(2);
- }