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); }