⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gridctrl.cpp

📁 一种简单的股票软件源代码,编译后可以实时显示证券行情
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	                                                    //的同时对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 %d\n",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 %d\n"), 
    //      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;
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -