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

📄 customgrid.cpp

📁 ADO数据库编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// CustomGrid.cpp : implementation file
//

#include "stdafx.h"
#include "CustomGrid.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCustomGrid

CCustomGrid::CCustomGrid()
{
    WNDCLASS wndcls;
    HINSTANCE hInst = AfxGetInstanceHandle();

    if (!(::GetClassInfo(hInst, GRIDCTRL_CLASSNAME, &wndcls)))
    {
        // otherwise we need to register a new class
        wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
        wndcls.lpfnWndProc      = ::DefWindowProc;
        wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
        wndcls.hInstance        = hInst;
        wndcls.hIcon            = NULL;
        wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
        wndcls.hbrBackground    = (HBRUSH) (COLOR_3DFACE + 1);
        wndcls.lpszMenuName     = NULL;
        wndcls.lpszClassName    = GRIDCTRL_CLASSNAME;

        if (!AfxRegisterClass(&wndcls)) {
            AfxThrowResourceException();
            return;
        }
    }
	m_nRows = 0; 
	m_nColums = 0;
	m_nFixedRows = 1;
	m_nFixedColums = 0;
    m_nVScrollMax = 0;
	m_nHScrollMax = 0;
	m_bCanScrollPage = false;
	m_nMouseMode = MOUSE_NOTHING;
	m_bCellEditable = false;
}

CCustomGrid::~CCustomGrid()
{
	m_Font.DeleteObject();
	m_strItems.RemoveAll();
    DestroyWindow();
}


BEGIN_MESSAGE_MAP(CCustomGrid, CWnd)
	//{{AFX_MSG_MAP(CCustomGrid)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	//}}AFX_MSG_MAP
    ON_MESSAGE(WM_GETFONT, OnGetFont)
    ON_NOTIFY(GVN_ENDLABELEDIT, IDC_CELLEDIT_CONTROL, OnModifyEditCell)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCustomGrid custom function

void CCustomGrid::SetItemFont(int FontHeight)
{//创建栅格中文字显示使用的字体
	m_Font.DeleteObject();
	m_Font.CreateFont(FontHeight, 0, 0, 0, FW_NORMAL, false, false, false,
		DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH, "宋体");//创建字体

	m_nFontHeight = FontHeight;
}

void CCustomGrid::SetRowCount(UINT row)
{
	//改变行数,调整数组大小
	if(m_nRows != row){
		m_nRows = row;
		m_strItems.SetSize(m_nRows * m_nColums);
	}
	//更新显示
    if (GetSafeHwnd())
    {
        ResetScrollBars();
    }
	//调整固定行的最大值
	if(m_nRows < m_nFixedRows) 
		m_nFixedRows = m_nRows;
}

void CCustomGrid::SetColumnCount(UINT colum, int* columwidth)
{
	int i, j;
	CString item;

	if(colum < m_nColums){//列变少,数组变小
		for(i = 1; i < m_nRows; i++){
			for(j = 0; j < colum; j++){
				item = m_strItems.GetAt(i*m_nColums+j);
				m_strItems.SetAt( i*colum+j, item );
			}
		}
		m_strItems.SetSize(m_nRows * colum);
	}
	else if(colum > m_nColums){//列变多,数组变大
		m_strItems.SetSize(m_nRows * colum);
		for(i = m_nRows-1; i > 0; i--){
			for(j = m_nColums-1; j >= 0; j--){
				item = m_strItems.GetAt( i*m_nColums+j);
				m_strItems.SetAt( i*colum+j, item );
			}
		}
	}

	m_nColumsWidth.SetSize(colum);
	if(columwidth)
		for(i = 0 ; i < colum; i++)
			m_nColumsWidth.SetAt(i, *(columwidth+i));
	else
		for(i = m_nColums; i < colum; i++)
			m_nColumsWidth.SetAt(i, DEFAULT_COLUMWIDTH);

	m_nColums = colum;

    if (GetSafeHwnd())
    {
        ResetScrollBars();
    }
	//调整固定列的最大值
	if(m_nColums < m_nFixedColums) 
		m_nFixedColums = m_nColums;
}

void CCustomGrid::SetItemString(int row, int colum, LPCTSTR item)
{
	ASSERT( row < m_nRows && colum < m_nColums);

	m_strItems.SetAt(row*m_nColums + colum, item);
}

int CCustomGrid::GetFixedColumnWidth()
{
	int i, n;

	if(m_nFixedColums > m_nColums){
		return 0;
	}

	for(i=0, n=0;i<m_nFixedColums;i++){
		n += m_nColumsWidth[i];
	}
	n += m_nFixedColums * (DEFAULT_TEXTWRAP * 2 +1);
	return n;
}

int CCustomGrid::GetFixedRowHeight()
{
	if( m_nFixedRows > m_nRows)
		return 0;
	else
		return m_nFixedRows * (m_nFontHeight + DEFAULT_TEXTWRAP * 2 +1);
}

int CCustomGrid::GetVirtualWidth()
{
	int i,n;

	for(i=0, n=0;i<m_nColums;i++){
		n += m_nColumsWidth[i];
	}
	n += m_nColums * (DEFAULT_TEXTWRAP * 2 +1);
	return n;
}

int CCustomGrid::GetVirtualHeight()
{
	return m_nRows * (m_nFontHeight + DEFAULT_TEXTWRAP * 2 + 1);
}

void CCustomGrid::ResetScrollBars()
{
    if (!::IsWindow(GetSafeHwnd())) 
        return;

    CRect rect;
    GetClientRect(rect);
	int hPage = rect.Width() - GetFixedColumnWidth();
	int vPage = rect.Height() - GetFixedRowHeight();

    SCROLLINFO si;
    si.cbSize = sizeof(SCROLLINFO);
    si.fMask  = SIF_PAGE;
    si.nPage  = hPage;   SetScrollInfo(SB_HORZ, &si, FALSE); 
    si.nPage  = vPage;   SetScrollInfo(SB_VERT, &si, FALSE); 

    if (rect.Height() < GetVirtualHeight() && rect.Height() > GetFixedRowHeight()){
        m_nVScrollMax = GetVirtualHeight() - rect.Height();
		SetScrollRange(SB_VERT, 0, m_nVScrollMax + vPage, FALSE);
	}
    else{
        m_nVScrollMax = 0;
		SetScrollRange(SB_VERT, 0, 0, TRUE);
	}

    if (rect.Width() < GetVirtualWidth() && rect.Width() > GetFixedColumnWidth()){
        m_nHScrollMax = GetVirtualWidth() - rect.Width();
	    SetScrollRange(SB_HORZ, 0, m_nHScrollMax + hPage, TRUE);
	}
    else{
        m_nHScrollMax = 0;
	    SetScrollRange(SB_HORZ, 0, 0, TRUE);
	}
	Invalidate(false);//更新显示
}

int CCustomGrid::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 CCustomGrid::SetScrollPos32(int nBar, int nPos, BOOL bRedraw /* = TRUE */)
{
    SCROLLINFO si;
    si.cbSize = sizeof(SCROLLINFO);
    si.fMask  = SIF_POS;
    si.nPos   = nPos;
    return SetScrollInfo(nBar, &si, bRedraw);
}

void CCustomGrid::DrawCell(CDC* pDC, int nRow, int nCol, CRect rect)
{
    COLORREF oldcolor = pDC->SetTextColor(CR_DEFAULT_ITEM);
	int oldbkmode = pDC->SetBkMode(TRANSPARENT);//背景透明
	CFont* oldfont = pDC->SelectObject( &m_Font );

	CString title = GetItemString(nRow, nCol);
	pDC->ExtTextOut(rect.left, rect.top, ETO_CLIPPED , rect, title, NULL);

	pDC->SelectObject( oldfont );
	pDC->SetTextColor(oldcolor);
	pDC->SetBkMode(oldbkmode);
}

void CCustomGrid::DrawFixedCell(CDC* pDC, int nRow, int nCol, CRect rect)
{
    COLORREF oldcolor = pDC->SetTextColor(CR_DEFAULT_FIXITEM);
	int oldbkmode = pDC->SetBkMode(TRANSPARENT);//背景透明
 	CFont* oldfont = pDC->SelectObject( &m_Font );

	CRect bkrect(rect.left -DEFAULT_TEXTWRAP, rect.top -DEFAULT_TEXTWRAP, rect.right+DEFAULT_TEXTWRAP, rect.bottom+DEFAULT_TEXTWRAP);
    pDC->FillSolidRect(bkrect, CR_DEFAULT_FIXEDBK);

	CString title = GetItemString(nRow, nCol);
	pDC->ExtTextOut(rect.left, rect.top, ETO_CLIPPED, rect, title, NULL);
	
	pDC->SelectObject( oldfont );
	pDC->SetTextColor(oldcolor);
	pDC->SetBkMode(oldbkmode);
}

CPoint CCustomGrid::GetScrolledCellFromPT(CPoint& Point)
{
	CPoint cell;
	int i;

	if(Point.x < GetFixedColumnWidth())
		cell.x = 0;
	else
		cell.x = -GetScrollPos32(SB_HORZ);
	for(i=0;i< m_nColums; i++){
		if(cell.x + m_nColumsWidth[i] + 2 * DEFAULT_TEXTWRAP + 1 > Point.x)
			break;
		cell.x += m_nColumsWidth[i] + 2 * DEFAULT_TEXTWRAP + 1;
	}
	cell.x = i >= m_nColums ? -1 : i;

	if(Point.y < GetFixedRowHeight())
		cell.y = 0;
	else
		cell.y = -GetScrollPos32(SB_VERT);
	i = (Point.y - cell.y) * 1.0 / (2 * DEFAULT_TEXTWRAP + 1 + m_nFontHeight);
	cell.y = i >= m_nRows ? -1 : i;

	return cell;
}

RECT CCustomGrid::GetScrolledCellRect(int Row, int Col)
{
	ASSERT(Row < m_nRows && Col < m_nColums);

	CRect rect(0, 0, 0, 0);
	int i;

	if(Col < m_nFixedColums){
		rect.left = 0;
	}
	else{
		rect.left = -GetScrollPos32(SB_HORZ);
	}
	for(i = 0; i < Col; i++){
		rect.left += m_nColumsWidth[i] + 2 * DEFAULT_TEXTWRAP + 1;
	}
	rect.right = rect.left + m_nColumsWidth[i] + 2 * DEFAULT_TEXTWRAP + 1;

	if(Row < m_nFixedRows){
		rect.top = 0;
	}
	else{
		rect.top = -GetScrollPos32(SB_VERT);
	}
	rect.top += Row * (m_nFontHeight + 2 * DEFAULT_TEXTWRAP + 1);
	rect.bottom = rect.top + m_nFontHeight + 2 * DEFAULT_TEXTWRAP + 1;

	return rect;
}

void CCustomGrid::VisibleCell(int Row, int Col)
{
	CRect CellRect = GetScrolledCellRect(Row, Col);
	CRect ClientRect;
	GetClientRect(&ClientRect);
	int vOffset, hOffset;

	ClientRect.left += GetFixedColumnWidth();
	ClientRect.top += GetFixedRowHeight();

	if(Row < m_nFixedRows)
		vOffset = 0;
	else if( (CellRect.Height() > ClientRect.Height())
		|| (CellRect.top < ClientRect.top) )
		vOffset = CellRect.top - ClientRect.top;
	else if(CellRect.bottom > ClientRect.bottom)
		vOffset = CellRect.bottom - ClientRect.bottom;
	else
		vOffset = 0;

	if(Col < m_nFixedColums)
		hOffset = 0;
	else if( (CellRect.Width() > ClientRect.Width())
		|| (CellRect.left < ClientRect.left) )
		hOffset = CellRect.left - ClientRect.left;
	else if(CellRect.right > ClientRect.right)
		hOffset = CellRect.right - ClientRect.right;
	else
		hOffset = 0;

	SetScrollPos(SB_HORZ, GetScrollPos(SB_HORZ) + hOffset);
	SetScrollPos(SB_VERT, GetScrollPos(SB_VERT) + vOffset);
	Invalidate(false);
}

int CCustomGrid::MouseOverColumnResizeArea(CPoint& point)
{
	CPoint Cell = GetScrolledCellFromPT(point);
	if(Cell.x < 0 || Cell.y < 0)
		return -1;

	CRect CellRect = GetScrolledCellRect(Cell.y, Cell.x);
	int i=-1;

	if( Cell.y == 0 && Cell.x > 0 && abs(point.x - CellRect.left) <= DEFAULT_TEXTWRAP )
		i = Cell.x -1;
	if( Cell.y == 0 && Cell.x >= 0 && abs(point.x - CellRect.right) <= DEFAULT_TEXTWRAP )
		i = Cell.x;
	return i;
}

LRESULT CCustomGrid::SendMessageToParent(int nRow, int nCol, int nMessage)
{
    if (!IsWindow(m_hWnd) || nRow < 0 || nCol < 0)
        return 0;

    NMHDR32 nmgv;
    nmgv.hwndFrom = m_hWnd;
    nmgv.idFrom   = GetDlgCtrlID();
    nmgv.code     = nMessage;
    nmgv.nRow     = nRow;
    nmgv.nCol     = nCol;
	nmgv.strText  = GetItemString(nRow, nCol);

    CWnd *pOwner = GetOwner();
    if (pOwner && IsWindow(pOwner->m_hWnd))
        return pOwner->SendMessage(WM_NOTIFY, nmgv.idFrom, (LPARAM)&nmgv);
    else
        return 0;
}

void CCustomGrid::StartEditCell(int nRow, int nCol)
{
	CRect CellRect = GetScrolledCellRect(nRow, nCol);
	if(!IsEditable() || nRow < 0 || nCol < 0 || nCol < m_nFixedColums || nRow < m_nFixedRows )
		//指定单元不可编辑
		return;

	new CCellEdit(this, CellRect, IDC_CELLEDIT_CONTROL, nRow, nCol, GetItemString(nRow, nCol));
}
/////////////////////////////////////////////////////////////////////////////
// CCustomGrid message handlers


void CCustomGrid::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	SetFocus();

	CPoint Cell = GetScrolledCellFromPT(point);

    if (m_nMouseMode == MOUSE_OVER_COL_DIVIDE) // sizing column
    {
		CRect client;
		GetClientRect(client);
        CRect invertedRect(point.x - 1, client.top, point.x + 1, client.bottom);
        CDC* pDC = GetDC();
        if (pDC) {
            pDC->InvertRect(&invertedRect);
            ReleaseDC(pDC);
			m_nMouseMode = MOUSE_SIZING_COL;
			m_OldPoint = point;
        }
		if(m_nSizingCol == m_nColums - 1){
			m_bCanScrollPage = true;
		}
		ClientToScreen(&client);
		ClipCursor(client);
	}
	else if(m_nMouseMode == MOUSE_NOTHING){
		CPoint Cell = GetScrolledCellFromPT(point);
		if(Cell.x >= 0 && Cell.y >= 0)
			//移动滚动条,显示指定单元
			VisibleCell(Cell.y, Cell.x);
		if( IsEditable() )
			//创建编辑对话框
			StartEditCell(Cell.y, Cell.x);
	}
	if(Cell.x >=0 && Cell.y >=0)
		SendMessageToParent(Cell.y, Cell.x, GVN_CLICK);
}

void CCustomGrid::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CRect client;
	GetClientRect(client);

	if(m_nMouseMode == MOUSE_NOTHING){
		if( (m_nSizingCol = MouseOverColumnResizeArea(point)) >= 0){
			::SetClassLong(GetSafeHwnd(), GCL_HCURSOR, (LONG)AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));

⌨️ 快捷键说明

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