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

📄 gridctrl.cpp

📁 Visual C++下的界面设计
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        pDC->FillSolidRect(VisRect.right, ClipRect.top, 
                           ClipRect.right - VisRect.right+1, ClipRect.Height(), 
                           GetBkColor());

    // Draw bottom of window below grid
    if (VisRect.bottom < ClipRect.bottom && ClipRect.left < VisRect.right) 
        pDC->FillSolidRect(ClipRect.left, VisRect.bottom, 
                           VisRect.right-ClipRect.left+1, ClipRect.bottom - VisRect.bottom+1, 
                           GetBkColor());
}

void CGridCtrl::OnSize(UINT nType, int cx, int cy) 
{
//    if (::IsWindow(GetSafeHwnd()) && GetFocus()->GetSafeHwnd() != GetSafeHwnd()) 
        SetFocus();        // Auto-destroy any InPlaceEdit's

    CWnd::OnSize(nType, cx, cy);
    ResetScrollBars();    
}

UINT CGridCtrl::OnGetDlgCode() 
{
    return DLGC_WANTARROWS | DLGC_WANTCHARS;
}

// If system settings change, then redo colours
void CGridCtrl::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) 
{
    CWnd::OnSettingChange(uFlags, lpszSection);
    
    if (GetTextColor() == m_crWindowText)                   // Still using system colours
        SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));      // set to new system colour
    if (GetTextBkColor() == m_crWindowColour)
        SetTextBkColor(::GetSysColor(COLOR_WINDOW));
    if (GetBkColor() == m_crShadow)
        SetBkColor(::GetSysColor(COLOR_3DSHADOW));
    if (GetFixedTextColor() == m_crWindowText)
        SetFixedTextColor(::GetSysColor(COLOR_WINDOWTEXT));
    if (GetFixedBkColor() == m_cr3DFace)
        SetFixedBkColor(::GetSysColor(COLOR_3DFACE));

    m_crWindowText   = ::GetSysColor(COLOR_WINDOWTEXT);
    m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
    m_cr3DFace       = ::GetSysColor(COLOR_3DFACE);
    m_crShadow       = ::GetSysColor(COLOR_3DSHADOW);

    m_nRowsPerWheelNotch = GetMouseScrollLines(); // Get the number of lines
}

// If system colours change, then redo colours
void CGridCtrl::OnSysColorChange() 
{
    CWnd::OnSysColorChange();
    
    if (GetTextColor() == m_crWindowText)                   // Still using system colours
        SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));      // set to new system colour
    if (GetTextBkColor() == m_crWindowColour)
        SetTextBkColor(::GetSysColor(COLOR_WINDOW));
    if (GetBkColor() == m_crShadow)
        SetBkColor(::GetSysColor(COLOR_3DSHADOW));
    if (GetFixedTextColor() == m_crWindowText)
        SetFixedTextColor(::GetSysColor(COLOR_WINDOWTEXT));
    if (GetFixedBkColor() == m_cr3DFace)
        SetFixedBkColor(::GetSysColor(COLOR_3DFACE));

    m_crWindowText   = ::GetSysColor(COLOR_WINDOWTEXT);
    m_crWindowColour = ::GetSysColor(COLOR_WINDOW);
    m_cr3DFace       = ::GetSysColor(COLOR_3DFACE);
    m_crShadow       = ::GetSysColor(COLOR_3DSHADOW);
}

// If we are drag-selecting cells, or drag and dropping, stop now
void CGridCtrl::OnCaptureChanged(CWnd *pWnd) 
{
    if (pWnd->GetSafeHwnd() == GetSafeHwnd()) return;

    // kill timer if active
    if (m_nTimerID != 0)
    {
        KillTimer(m_nTimerID);
        m_nTimerID = 0;
    }

    // Kill drag and drop if active
    if (m_MouseMode == MOUSE_DRAGGING)
    {
        m_pDragImage->DragLeave(GetDesktopWindow());
        m_pDragImage->EndDrag();
        delete m_pDragImage;
        m_pDragImage = NULL;
        m_MouseMode = MOUSE_NOTHING;
    }
}

// For drag-selection. Scrolls hidden cells into view
// TODO: decrease timer interval over time to speed up selection over time
void CGridCtrl::OnTimer(UINT nIDEvent)
{
    ASSERT(nIDEvent == WM_LBUTTONDOWN);
    if (nIDEvent != WM_LBUTTONDOWN) return;

    CPoint pt, origPt;

    if (!GetCursorPos(&origPt)) return;
    ScreenToClient(&origPt);

    CRect rect;
    GetClientRect(rect);

    int nFixedRowHeight = GetFixedRowHeight();
    int nFixedColWidth = GetFixedColumnWidth();

    pt = origPt;
    if (pt.y > rect.bottom)
    {
        //SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);
        SendMessage(WM_KEYDOWN, VK_DOWN, 0);

        if (pt.x < rect.left)  pt.x = rect.left;
        if (pt.x > rect.right) pt.x = rect.right;
        pt.y = rect.bottom;
        OnSelecting(GetCellFromPt(pt));
    }
    else if (pt.y < nFixedRowHeight)
    {
        //SendMessage(WM_VSCROLL, SB_LINEUP, 0);
        SendMessage(WM_KEYDOWN, VK_UP, 0);

        if (pt.x < rect.left)  pt.x = rect.left;
        if (pt.x > rect.right) pt.x = rect.right;
        pt.y = nFixedRowHeight + 1;
        OnSelecting(GetCellFromPt(pt));
    }

    pt = origPt;
    if (pt.x > rect.right)
    {
        // SendMessage(WM_HSCROLL, SB_LINERIGHT, 0);
        SendMessage(WM_KEYDOWN, VK_RIGHT, 0);

        if (pt.y < rect.top)    pt.y = rect.top;
        if (pt.y > rect.bottom) pt.y = rect.bottom;
        pt.x = rect.right;
        OnSelecting(GetCellFromPt(pt));
    } 
    else if (pt.x < nFixedColWidth)
    {
        //SendMessage(WM_HSCROLL, SB_LINELEFT, 0);
        SendMessage(WM_KEYDOWN, VK_LEFT, 0);

        if (pt.y < rect.top)    pt.y = rect.top;
        if (pt.y > rect.bottom) pt.y = rect.bottom;
        pt.x = nFixedColWidth + 1;
        OnSelecting(GetCellFromPt(pt));
    }

}

// move about with keyboard
void CGridCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    if (!IsValid(m_idCurrentCell)) return;

    CCellID next = m_idCurrentCell;

    if (IsCTRLpressed())
    {
        switch (nChar)
        {
           case 'X': OnEditCut();   break;
           case 'C': OnEditCopy();  break;
           case 'V': OnEditPaste(); break;
        }
    }
    else
    {
        switch (nChar)
        {
            case VK_DOWN:  if (next.row < (GetRowCount() - 1)) next.row++; break;
            case VK_UP:    if (next.row > m_nFixedRows)        next.row--; break;
            case VK_RIGHT: if (next.col < (GetColumnCount() - 1)) next.col++; break;
            case VK_LEFT:  if (next.col > m_nFixedCols)        next.col--; break;

            case VK_NEXT:  {
                              CCellID idOldTopLeft = GetTopleftNonFixedCell();
                              SendMessage(WM_VSCROLL, SB_PAGEDOWN, 0);
                              CCellID idNewTopLeft = GetTopleftNonFixedCell();

                              int increment = idNewTopLeft.row - idOldTopLeft.row;
                              if (increment) {
                                  next.row += increment;
                                  if (next.row > (GetRowCount() - 1)) 
                                      next.row = GetRowCount() - 1;
                              }
                              else
                                  next.row = GetRowCount() - 1;
                              break;
                           }
    
            case VK_PRIOR: {
                              CCellID idOldTopLeft = GetTopleftNonFixedCell();
                              SendMessage(WM_VSCROLL, SB_PAGEUP, 0);
                              CCellID idNewTopLeft = GetTopleftNonFixedCell();

                              int increment = idNewTopLeft.row - idOldTopLeft.row;
                              if (increment) {
                                  next.row += increment;
                                  if (next.row < m_nFixedRows) next.row = m_nFixedRows;
                              } else
                                  next.row = m_nFixedRows;
                              break;
                           }
    
            case VK_HOME:  SendMessage(WM_VSCROLL, SB_TOP, 0);
                           next.row = m_nFixedRows;
                           break;
        
            case VK_END:   {
                              SendMessage(WM_VSCROLL, SB_BOTTOM, 0);
                              next.row = GetRowCount() - 1;
                              break;
                           }
            default:
                CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
        }
    }

    if (next != m_idCurrentCell) 
    {
        SetFocusCell(next);
        while (!IsCellVisible(next))
        {
            switch (nChar) {
                case VK_RIGHT: SendMessage(WM_HSCROLL, SB_LINERIGHT, 0); break;
                case VK_LEFT:  SendMessage(WM_HSCROLL, SB_LINELEFT, 0);  break;
                case VK_DOWN:  SendMessage(WM_VSCROLL, SB_LINEDOWN, 0);  break;
                case VK_UP:    SendMessage(WM_VSCROLL, SB_LINEUP, 0);    break;
            }
            Invalidate();
        }
    }
}

// Instant editing of cells when keys are pressed
void CGridCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    if (!IsCTRLpressed() && m_MouseMode == MOUSE_NOTHING && IsCellVisible(m_idCurrentCell))
        OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, nChar);

    CWnd::OnChar(nChar, nRepCnt, nFlags);
}

// Callback from any CInPlaceEdits that ended. This just calls OnEndEditCell,
// refreshes the edited cell and moves onto next cell if the return character
// from the edit says we should.
BOOL CGridCtrl::OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult) 
{    
    LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
    LV_ITEM    *plvItem = &plvDispInfo->item;

    *pResult = 0;

    OnEndEditCell(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
    InvalidateCellRect(CCellID(plvItem->iItem, plvItem->iSubItem));

	if (plvDispInfo->hdr.idFrom == IDC_IPLIST)
	{
		SetItemData(plvItem->iItem, plvItem->iSubItem, plvItem->lParam);
		return FALSE;
	}

    switch (plvItem->lParam) 
    {
        case VK_DOWN: 
        case VK_UP:   
        case VK_RIGHT:
        case VK_LEFT:  
        case VK_NEXT:  
        case VK_PRIOR: 
        case VK_HOME:  
        case VK_END:    OnKeyDown(plvItem->lParam, 0, 0);
                        OnEditCell(m_idCurrentCell.row, m_idCurrentCell.col, plvItem->lParam);
    }

    if (plvItem->lParam != VK_ESCAPE) SetModified(TRUE);

    return FALSE;
}

// Handle horz scrollbar notifications
void CGridCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
    if (GetFocus()->GetSafeHwnd() != GetSafeHwnd()) SetFocus();  // Auto-destroy any InPlaceEdit's

    int scrollPos = GetGridScrollPos(SB_HORZ);

    CCellID idTopLeft = GetTopleftNonFixedCell();

    CRect rect;
    GetClientRect(rect);

    switch (nSBCode)
    {
        case SB_LINERIGHT:
            if (scrollPos < m_nHScrollMax)
            {
                int xScroll = GetColumnWidth(idTopLeft.col);
                SetGridScrollPos(SB_HORZ, scrollPos + xScroll);
                if (GetGridScrollPos(SB_HORZ) == scrollPos) break;          // didn't work

                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 xScroll = GetColumnWidth(idTopLeft.col-1);
                SetGridScrollPos(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);
                SetGridScrollPos(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);
                SetGridScrollPos(SB_HORZ, pos);
                rect.left = GetFixedColumnWidth();
                InvalidateRect(rect);
            }
            break;

        case SB_THUMBPOSITION:
        case SB_THUMBTRACK:
            {
                SetGridScrollPos(SB_HORZ, nPos);
                rect.left = GetFixedColumnWidth();
                InvalidateRect(rect);
            }
            break;

        case SB_LEFT:
            if (scrollPos > 0)
            {
                SetGridScrollPos(SB_HORZ, 0);
                Invalidate();
            }
            break;

        case SB_RIGHT:
            if (scrollPos < m_nHScrollMax)
            {
                SetGridScrollPos(SB_HORZ, m_nHScrollMax);
                Invalidate();
            }
            break;


        default: break;
    }
}

// Handle vert scrollbar notifications
void CGridCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
    if (GetFocus()->GetSafeHwnd() != GetSafeHwnd()) SetFocus();        // Auto-destroy any InPlaceEdit's

    int scrollPos = GetGridScrollPos(SB_VERT);

    CCellID idTopLeft = GetTopleftNonFixedCell();

    CRect rect;
    GetClientRect(rect);

⌨️ 快捷键说明

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