www.gusucode.com > ADO智能开发包C++源码程序 > ADO智能开发包/sfxdb_src_1.0.510.1/sfx/Source/db/src/AdoGrid.cpp

    // f:\forever_vc\forever_code\database\AdoGrid.cpp : implementation file
//

#include "stdafx.h"
#include "AdoGrid.h"
#include <WindowsX.h>


BOOL
WINAPI
ListView_DeleteAllColumn(HWND hWndCtrl)
{
	int nCount = 0;
	HWND hHeaderWnd = NULL;

	if (hWndCtrl)
	{
		hHeaderWnd = ListView_GetHeader(hWndCtrl);
		nCount = Header_GetItemCount(hHeaderWnd);

		for (int i=0; i<nCount; i++)
		{
			ListView_DeleteColumn(hWndCtrl, 0);
		}

		return TRUE;
	}

	return FALSE;
}


int WINAPI ListView_GetVisibleItemCount(HWND hWndCtrl)
{
	RECT rcRect;
	int nItemCount = -1;
	RECT rcHeaderRect;
	RECT rcItemRect;
	//LVHITTESTINFO lvInfo;
	//int nItem=0;
	if (NULL != hWndCtrl)
	{
		//find item height

		//lvInfo.pt.x = 4;
		//lvInfo.pt.y = rcHeaderRect.bottom;
		//while(true)
		//{
		//	nItem = ListView_HitTest(hWndCtrl, &lvInfo);
		//	if (nItem == 1)
		//	{
		//	}
		//	lvInfo.pt.y++;
		//	//nItem
		//} while();
		//lvInfo.pt.y--;


		if (ListView_GetItemCount(hWndCtrl)>0)
		{
			GetClientRect(hWndCtrl, &rcRect);
			GetClientRect(ListView_GetHeader(hWndCtrl), &rcHeaderRect);
			ListView_GetItemRect(hWndCtrl, 0, &rcItemRect, LVIR_BOUNDS);

			rcRect.bottom -= rcHeaderRect.bottom;
			nItemCount = rcRect.bottom/(rcItemRect.bottom - rcHeaderRect.bottom);
		}
	}

	return nItemCount;
}

// CAdoGrid
IMPLEMENT_DYNAMIC(CAdoGrid, CListCtrl)

CAdoGrid::CAdoGrid()
	:m_nItem(0)
	,m_nSubItem(1)
	,m_DataItem(NULL)
	,m_nDispinfoItem(0)
	,m_nRecordPos(0)
	,m_nVisibleColCount(0)
	,m_nVisibleItemCount(0)
{
	memset((VOID*)m_cRowBuffer, 0, sizeof(m_cRowBuffer));
	m_varBookmarkFirst	= (long)adBookmarkFirst;
	m_varColumn.vt		= VT_I4;
	m_nItemHeight		= 22;
	m_pWnd = this;
}

CAdoGrid::~CAdoGrid()
{
	if (NULL != m_DataItem)
	{
		delete []m_DataItem;
		m_DataItem = NULL;
	}
}


void CAdoGrid::UpdateField()
{
	int nCount = 0;
	CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl();
	nCount = pHeaderCtrl->GetItemCount();
	if (0 >= nCount)
	{
		AddAllField();
	}
}

BEGIN_MESSAGE_MAP(CAdoGrid, CListCtrl)
	ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnLvnGetdispinfo)
	ON_WM_LBUTTONDOWN()
	ON_WM_MEASUREITEM()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
	ON_WM_SIZE()
	ON_WM_RBUTTONDOWN()
	ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()


void CAdoGrid::_OnElseCMDEvents(BASE_CMD nCMD, LPARAM lParam)
{
	if (CDBBaseControl::BC_READONLY	== nCMD)
	{
		return;
	}

	if (CDBBaseControl::BC_CLEAR == nCMD)
	{
		//if (!m_pRecordSet->IsOpen())
		//{
		//	SetItemCount(0);
		//	ListView_DeleteAllColumn(m_hWnd);
		//}
		return ;
	}

	CDBBaseControl::_OnElseCMDEvents(nCMD, lParam);
}


void CAdoGrid::virDataChange()
{
	TRACE(_T("CAdoGrid::virDataChange()\n"));

	int nCurRecord = -1;
	ASSERT(NULL != m_pRecordSet);

	if (NULL != m_pRecordSet)
	{

		//判断Grid中是否存在数据记录,如果不存在,分配空间,
			int nCount = this->GetItemCount();
			int nRecordCount = m_pRecordSet->GetRecordCount();
			if (nRecordCount != nCount)
			{
				SetItemCount(nRecordCount);
			}
			if ( ADO::adEditAdd != m_pRecordSet->GetEditMode())
			{

			nCurRecord = m_pRecordSet->GetAbsolutePosition();
			if ((nCurRecord<m_nFrom) && (nCurRecord>m_nTo))
			{
				SetSelectionMark(nCurRecord);
			}else
			{
				SetSelectionMark(0);			
			}

			AllotSpace();
			InitData();

			UpdateWindow();
		}
	}
}


void CAdoGrid::virDataWrite()
{
}


VOID CAdoGrid::ChageStruct()
{
	TRACE(_T("CAdoGrid::ChageStruct()\n"));

	//SetItemCount(m_pRecordSet->GetRecordCount());
}


void CAdoGrid::DeleteAllFieldCaption()
{
	ASSERT(NULL != m_hWnd);
	VERIFY(ListView_DeleteAllColumn(m_hWnd));
}


BOOL CAdoGrid::AddAllField()
{
	HDC			hdc;
	SIZE		sz;
	LV_COLUMN	lvc;
	TEXTMETRIC	tm;
	CString		_Caption;
	_variant_t	_varIndex;
	FieldPtr	_FieldPtr;

	if (NULL != m_pRecordSet)
	{
		memset(&lvc, 0, sizeof(lvc));
		lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;

		hdc =  ::GetDC(m_hWnd);
		GetTextMetrics(hdc, &tm);
		GetTextExtentPoint(hdc, _Caption, _Caption.GetLength(), &sz);
		m_FieldsPtr = m_pRecordSet->GetFields();

		for (long nFieldIndex=0; nFieldIndex<m_FieldsPtr->GetCount(); nFieldIndex++)
		{
			_varIndex		= (long)nFieldIndex;
			_FieldPtr		= m_FieldsPtr->GetItem(_varIndex);
			_Caption		= (LPCSTR)_FieldPtr->GetName();
			lvc.pszText		= (LPTSTR)(LPCTSTR)_Caption;
			lvc.cchTextMax	= _Caption.GetLength();
			//lvc.iSubItem	= nFieldIndex+1;
			lvc.cx			= adoGetFieldSize(_FieldPtr, tm.tmMaxCharWidth);	//_FieldPtr->GetDefinedSize()*8;
			InsertColumn(nFieldIndex + 1, &lvc);

			TRACE(_Caption);
			TRACE(_T("\n"));
		}

		m_nVisibleColCount = GetHeaderCtrl()->GetItemCount();
		::ReleaseDC(m_hWnd, hdc);
		return TRUE;
	}

	return FALSE;
}


int CAdoGrid::AddFieldCaption(int nItem, LPCTSTR lpszFieldName, int nWidth)
{
	LV_COLUMN lvc;
	int nRetItem = 0;
	memset(&lvc, 0, sizeof(lvc));
	lvc.mask		= LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
	lvc.pszText		= (LPTSTR)(LPCTSTR)lpszFieldName;
	lvc.cchTextMax	= (int)_tcslen(lpszFieldName);
	lvc.cx			= nWidth;
	nRetItem = InsertColumn(nItem, &lvc);
	if (-1 != nRetItem)
	{
		m_nVisibleColCount = GetHeaderCtrl()->GetItemCount();
	}

	return nRetItem;
}


void CAdoGrid::SetStyle()
{
	DWORD dwStyle = 0;
	dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
	::SetWindowLong(m_hWnd, GWL_STYLE, dwStyle|LVS_REPORT | LVS_OWNERDATA |LVS_SHOWSELALWAYS);
	//dwStyle = GetExtendedStyle();dwStyle | 
	SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
}


BOOL CAdoGrid::SetActiveItem(int iItem, int iSubItem)
{
	TRACE(_T("CAdoGrid::SetActiveItem(int nItem, int nSubItem)\n"));

	LVCOLUMN lvc;
	CString strFieldName;
	ASSERT(m_pRecordSet);

	if (iSubItem>=0 && iItem>=0)
	{
		lvc.mask		= LVCF_TEXT;
		lvc.pszText		= strFieldName.GetBuffer(256);
		lvc.cchTextMax	= 256;
		VERIFY(GetColumn(iSubItem, &lvc));
		strFieldName.ReleaseBuffer();

		m_Field = m_pRecordSet->GetField(lvc.pszText);

		m_pRecordSet->GetAdoRecordset()->Move(iItem, _variant_t((long)adBookmarkFirst));
		m_pRecordSet->MoveView((CDBBaseControl*)this);
		m_pRecordSet->virDataChange();
		m_pRecordSet->AddView((CDBBaseControl*)this);

		TRACE(_T("在Grid中选择了项是: %d\n"), iItem);
		TRACE(_T("在Grid中选择了记录: %d\n"), m_pRecordSet->GetAbsolutePosition()); 

		return TRUE;
	}

	return FALSE;
}


void CAdoGrid::PreSubclassWindow()
{
	SetStyle();
	CListCtrl::PreSubclassWindow();
}


void CAdoGrid::OnLButtonDown(UINT nFlags, CPoint point)
{
	TRACE(_T("CAdoGrid::OnLButtonDown(UINT nFlags, CPoint point)\n"));

	LVHITTESTINFO hti;

	hti.pt = point;
	SubItemHitTest(&hti);
	m_nItem		= hti.iItem;
	m_nSubItem	= hti.iSubItem;

	if (0 <= m_nItem)
	{
		VERIFY(SetActiveItem(m_nItem, m_nSubItem));
	}

	CListCtrl::OnLButtonDown(nFlags, point);
}


void CAdoGrid::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	LVHITTESTINFO hti;

	hti.pt = point;
	SubItemHitTest(&hti);
	m_nItem		= hti.iItem;
	m_nSubItem	= hti.iSubItem;

	if (0 <= m_nItem)
	{
		VERIFY(SetActiveItem(m_nItem, m_nSubItem));
	}

	CListCtrl::OnRButtonDown(nFlags, point);
}


void CAdoGrid::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
{
	NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
	if (pDispInfo->item.mask & LVIF_TEXT)
	{
		m_nDispinfoItem = (pDispInfo->item.iItem-m_nRecordPos) * m_nVisibleColCount + pDispInfo->item.iSubItem;

		if (m_nDispinfoItem >= 0)
		{
			if (m_nDispinfoItem<m_ItemSize)
			{
				m_DataItemTemp  = m_DataItem + m_nDispinfoItem;
				pDispInfo->item.pszText		= (LPTSTR)(LPCTSTR)*m_DataItemTemp;
				pDispInfo->item.cchTextMax	= m_DataItemTemp->GetLength();
			}else
			{
				pDispInfo->item.pszText		= _T("");
				pDispInfo->item.cchTextMax	= 0;
			}
		}
	}

	*pResult = 0;
}


BOOL CAdoGrid::AllotSpace()
{
	int nSize		= 0;
	int nItemCount	= 0;
	int nRecordCount= 0;

	if ((NULL != m_pRecordSet) && m_pRecordSet->IsOpen())
	{
		//算出当前可视的行数,根据行分配空间
		nItemCount	= ListView_GetVisibleItemCount(m_hWnd) + 1;
		nRecordCount= m_pRecordSet->GetRecordCount();
		if (nItemCount>nRecordCount)
		{
			m_nVisibleItemCount = nRecordCount;
		}else
		{
			m_nVisibleItemCount = nItemCount;
		}
		nSize = (m_nVisibleItemCount+1) * (m_nVisibleColCount+1);

		if (nSize != m_ItemSize)
		{
			if (0<nSize)
			{
				if (NULL != m_DataItem)
				{
					delete []m_DataItem;
					m_DataItem = NULL;
				}

				m_DataItem	= new CString[nSize];
				m_ItemSize	= nSize;
				return TRUE;
			}
		}
	}

	return FALSE;
}


//把数据写入到数据空间中
void CAdoGrid::InitData()
{
	TCHAR lpszFieldName[MAX_PATH] = _T("");
	CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl();
	CString *ItemText = NULL;
	LVCOLUMN lv;

	if ((NULL != m_pRecordSet) && m_pRecordSet->IsOpen())
	{
		int m_OldRecordNo	= m_pRecordSet->GetAbsolutePosition();
		int nIndexItem		= 0;
		int nIndexCol		= 0;
		int nColCount		= pHeaderCtrl->GetItemCount();
		int nIndexRow		= 0;

		memset(&lv, 0, sizeof(lv));
		lv.mask			= LVCF_TEXT;
		lv.pszText		= lpszFieldName;
		lv.cchTextMax	= MAX_PATH;

		if (0 < m_nVisibleItemCount)
		{
			m_varBookmarkFirst	= (long)adBookmarkFirst;
			m_varColumn.vt		= VT_I4;
			m_pRecordSet->GetAdoRecordset()->Move(m_nRecordPos, m_varBookmarkFirst);

			//m_varBookmarkFirst = (long)adBookmarkCurrent;

			nIndexItem = 0;
			for (nIndexRow=0; nIndexRow<m_nVisibleItemCount; nIndexRow++)
			{
				for (nIndexCol = 0; nIndexCol<nColCount; nIndexCol++)
				{
					GetColumn(nIndexCol, &lv);
					ItemText	= m_DataItem + nIndexItem;
					*ItemText	= VariantToStr(m_FieldsPtr->GetItem(lv.pszText)->GetValue());
					nIndexItem++;
				}

				m_pRecordSet->GetAdoRecordset()->MoveNext();
			}

			m_pRecordSet->GetAdoRecordset()->Move(m_OldRecordNo, m_varBookmarkFirst);
		}
	}
}


void CAdoGrid::SetItemHeight(const int iHeight)
{
	m_nItemHeight = iHeight;

	if (GetSafeHwnd())
	{
		CRect rc;
		GetWindowRect( &rc );
		WINDOWPOS wp;
		wp.hwnd = m_hWnd;
		wp.cx	= rc.Width();
		wp.cy	= rc.Height();
		wp.flags= SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
		SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
	}
}


void CAdoGrid::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	lpMeasureItemStruct->itemHeight = m_nItemHeight;
	CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}


void CAdoGrid::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);

	int pos = ::GetScrollPos(m_hWnd, SB_VERT);
	if (m_nRecordPos != pos)
	{
		m_nRecordPos = pos;

		InitData();
		//UpdateWindow();
		InvalidateRect(NULL, TRUE);
	}
}


BOOL CAdoGrid::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: Add your message handler code here and/or call default
	BOOL b = CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
	int pos = ::GetScrollPos(m_hWnd, SB_VERT);
	if (m_nRecordPos != pos)
	{
		m_nRecordPos = pos;

		InitData();
		//UpdateWindow();
		InvalidateRect(NULL, TRUE);
	}

	return b;
}


void CAdoGrid::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}


void CAdoGrid::OnSize(UINT nType, int cx, int cy)
{
	CListCtrl::OnSize(nType, cx, cy);
}