// MatDlg.cpp : implementation file // #include "stdafx.h" #include "resource.h" #include "GridView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static COleVariant * g_lstSortFieldContents=NULL; static BOOL g_bSortAscend=TRUE; extern int CompareBookmark(COleVariant *pArray, const long *bookmark1, const long *bookmark2); // bookmark is record number static int CompareBookmarksForSort(const long *bookmark1, const long *bookmark2) { int nRes=CompareBookmark(g_lstSortFieldContents, bookmark1, bookmark2); if (!g_bSortAscend) { //Reverse the result if (nRes>0) nRes=-1; else if (nRes<0) nRes=1; } return nRes; } // modify by xlc on 090902 消除tg5lib影响 //#if ADS<18 #if 0 ///////////////////////////////////////////////////////////////////////////// // CGridView dialog IMPLEMENT_DYNCREATE(CGridView, CFormView) CGridView::CGridView(UINT id) : CFormView(id), m_pTable(NULL), m_nCurIndex(-1), m_bAscend(TRUE) { //{{AFX_DATA_INIT(CGridView) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT AfxEnableControlContainer(); // OleInit m_bReadEnable = FALSE; } BOOL CGridView::MoveTo(long bookmark) { for(int i=0; im_lstBookmarks.Length()) m_nCurIndex=m_lstBookmarks.Length(); else if (m_nCurIndex<-1) m_nCurIndex=-1; } void CGridView::DoDataExchange(CDataExchange* pDX) { CFormView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CGridView) DDX_Control(pDX, IDC_GRID, m_grid); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CGridView, CFormView) //{{AFX_MSG_MAP(CGridView) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CGridView message handlers void CGridView::OnInitialUpdate() { CFormView::OnInitialUpdate(); CRect rect; GetClientRect( &rect ); m_grid.SetWindowPos( NULL, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,SWP_SHOWWINDOW); OnDocFileChanged(); } void CGridView::OnDocFileChanged() { // TODO: Add extra initialization here m_sSortFieldName.Empty(); m_pTable = OpenDbfTable(); if (!m_pTable) return; CTrueDBGrid50_Columns Cols = m_grid.GetColumns(); Cols.RemoveAll(); GetBookmarks(TRUE); ConfigGrid(); } // 取得所有行的Bookmark或/并排序 void CGridView::GetBookmarks(BOOL bRetriveFromDbf) { if (!m_pTable) return; if (bRetriveFromDbf) { m_lstBookmarks.Reset(); for(m_pTable->MoveFirst(); !m_pTable->IsEOF(); m_pTable->MoveNext()) m_lstBookmarks.Append(new long(m_pTable->GetPosition())); } if (!m_sSortFieldName.IsEmpty()) { if (g_lstSortFieldContents) delete [] g_lstSortFieldContents; g_lstSortFieldContents = new COleVariant[(int) m_pTable->GetRecordCount(FALSE)]; int i=0; for(m_pTable->MoveFirst(FALSE); !m_pTable->IsEOF(); m_pTable->MoveNext(FALSE)) { XFieldContent *pContent=m_pTable->GetFieldContent(m_sSortFieldName); ASSERT(pContent); g_lstSortFieldContents[i]=pContent->AsVariant(); i++; } m_lstBookmarks.QuickSort(CompareBookmarksForSort); delete [] g_lstSortFieldContents; g_lstSortFieldContents=NULL; } } //布置Grid的界面 void CGridView::ConfigGrid() { if (!m_pTable) return; m_bReadEnable = FALSE; //禁止Grid从数据源读取数据, 锁定 // Set other miscellaneous properties for the BookList grid // Set properties for grid columns -- first remove the two default // grid columns and add four more CTrueDBGrid50_Columns Cols = m_grid.GetColumns(); Cols.RemoveAll(); m_grid.SuppressTransforms(TRUE); int nLine=1; int nColumn=m_lstHeadInfo.Length(); for(int i=0; im_sDesc, 1, s1); CT_strnth(m_lstHeadInfo[i]->m_sDesc, 2, s2); if (!!s2) { s1 << "\n" << s2; nLine=2; } Col.SetCaption(s1); Col.SetWidth(m_lstHeadInfo[i]->m_nWidth); } CTrueDBGrid50_Style headStyle=m_grid.GetHeadingStyle(); headStyle.SetAlignment(dbgCenter); m_grid.SetHeadingStyle(headStyle); m_grid.SetHeadLines(float(1.2*nLine)); m_grid.SetApproxCount(m_lstBookmarks.Length()); if (!m_lstBookmarks) { COleVariant var; V_VT(&var) = VT_NULL; m_grid.SetBookmark(var); } else m_grid.SetBookmark(COleVariant(*m_lstBookmarks[0])); m_bReadEnable = TRUE; //解开Grid从数据源读取数据的锁定 m_grid.ReBind(); } BEGIN_EVENTSINK_MAP(CGridView, CFormView) //{{AFX_EVENTSINK_MAP(CGridView) ON_EVENT(CGridView, IDC_GRID, 41 /* UnboundReadDataEx */, OnUnboundReadDataExMatgrid, VTS_DISPATCH VTS_PVARIANT VTS_I4 VTS_PI4) ON_EVENT(CGridView, IDC_GRID, 19 /* UnboundWriteData */, OnUnboundWriteDataMatgrid, VTS_DISPATCH VTS_PVARIANT) ON_EVENT(CGridView, IDC_GRID, 20 /* UnboundAddData */, OnUnboundAddDataMatgrid, VTS_DISPATCH VTS_PVARIANT) ON_EVENT(CGridView, IDC_GRID, 21 /* UnboundDeleteRow */, OnUnboundDeleteRowMatgrid, VTS_PVARIANT) ON_EVENT(CGridView, IDC_GRID, 10 /* HeadClick */, OnHeadClickMatgrid, VTS_I2) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() void CGridView::ReadData(CTrueDBGrid50_RowBuffer &RowBuffer, VARIANT FAR* StartLocation, long offset, long FAR* ApproximatePosition) { long RowsFetched = 0; if (!m_pTable || !m_lstBookmarks || !m_bReadEnable) { RowBuffer.SetRowCount(0); return; } // If StartLocation is a Null VARIANT, it means we are positioning // relative to BOF (if offset > 0) or EOF (if offset < 0) if (V_VT(StartLocation) == VT_NULL) { if (offset > 0) { m_nCurIndex=-1; } else { // Position to EOF m_nCurIndex=m_lstBookmarks.Length(); } } else { // StartLocation refers to a valid bookmark, so just go there. ASSERT(V_VT(StartLocation)==VT_I4); long nPos=V_I4(StartLocation); if (!MoveTo(nPos)) { V_VT(StartLocation)=VT_NULL; } } Move(offset); if (!IsBOF() && !IsEOF()) { *ApproximatePosition = m_nCurIndex; } // Here we store the number of rows and columns requested by the grid // for this event, so we don't have to ask for them over and over again. long lRowCount = RowBuffer.GetRowCount(); short sColCount = RowBuffer.GetColumnCount(); // This is a big loop that fetches data and/or bookmarks that the // grid requests. The number of rows we need to provide data for // is given by RowBuffer.GetRowCount() for(long row = 0; row < lRowCount; row++) { if (IsBOF() || IsEOF()) { RowBuffer.SetRowCount(RowsFetched); return; } m_pTable->MoveTo(*m_lstBookmarks[m_nCurIndex]); for(short col = 0; col < sColCount; col++) { short sColIndex = RowBuffer.GetColumnIndex(row, col); ASSERT(sColIndexGetFieldContent(m_lstHeadInfo[sColIndex]->m_sName)->AsVariant(); RowBuffer.SetValue(row, col, vValue); } // Now that data for all columns have been fetched (if any), supply // the bookmark of this row of data to the grid. All we need to do // is supply the bookmark of the current record in the recordset. long nPos=*m_lstBookmarks[m_nCurIndex]; RowBuffer.SetBookmark(row, COleVariant(nPos)); // Increment the number of rows successfully fetched, and do a // MoveNext on the recordset so we are ready to read the next record. RowsFetched++; MoveNext(); } // Place the number of rows we were able to fetch into the RowBuffer's // RowCount property RowBuffer.SetRowCount(RowsFetched); } // 往grid送数据 void CGridView::OnUnboundReadDataExMatgrid(LPDISPATCH RowBuf, VARIANT FAR* StartLocation, long offset, long FAR* ApproximatePosition) { CTrueDBGrid50_RowBuffer RowBuffer(RowBuf); static BOOL bLocked = FALSE; //进行锁定,即下一次的读数消息必须在本次消息结束之后方可以处理 if (bLocked) { #if !defined(NDEBUG) adsout << _T("\nGrid违背了锁定规则!"); #endif return; } bLocked=TRUE; ReadData(RowBuffer, StartLocation, offset, ApproximatePosition); bLocked=FALSE; } // 更新材料库 void CGridView::OnUnboundWriteDataMatgrid(LPDISPATCH RowBuf, VARIANT FAR* WriteLocation) { // TODO: Add your control notification handler code here CTrueDBGrid50_RowBuffer RowBuffer(RowBuf); // Here we store the number of rows and columns requested by the grid // for this event, so we don't have to ask for them over and over again. ASSERT(V_VT(WriteLocation)==VT_I4); long lBookmark=V_I4(WriteLocation); m_pTable->MoveTo(lBookmark); long lRowCount = RowBuffer.GetRowCount(); ASSERT(lRowCount==1); short sColCount = RowBuffer.GetColumnCount(); for(short col = 0; col < sColCount; col++) { short sColIndex = RowBuffer.GetColumnIndex(0, col); COleVariant vValue = RowBuffer.GetValue(0, col); XFieldContent *pField=m_pTable->GetFieldContent(m_lstHeadInfo[sColIndex]->m_sName); ASSERT(pField); *pField = vValue; } } //增加一行记录 void CGridView::OnUnboundAddDataMatgrid(LPDISPATCH RowBuf, VARIANT FAR* NewRowBookmark) { // Construct a RowBuffer class object from the supplied LPDISPATCH (RowBuf). This // allows us to use the RowBuffer wrapper class's functions to manipulate the // RowBuffer object. CTrueDBGrid50_RowBuffer RowBuffer(RowBuf); XDbfTable *rs = m_pTable; // If the recordset is invalid or is not open, exit the event. Setting the RowCount // property to 0 indicates to the grid that the Add failed in the data source. if (!rs) { RowBuffer.SetRowCount(0); return; } // Place the recordset into AddNew mode rs->AppendBegin(); // For each column in the row buffer, copy the value into the new record short sColCount = RowBuffer.GetColumnCount(); for(short col = 0; col < sColCount; col++) { short sColIndex = RowBuffer.GetColumnIndex(0, col); COleVariant vValue = RowBuffer.GetValue(0, col); XFieldContent *pField=rs->GetFieldContent(m_lstHeadInfo[sColIndex]->m_sName); ASSERT(pField); *pField = vValue; } // Save the changes made to the new record rs->AppendEnd(); m_lstBookmarks.Append(new long(rs->GetPosition())); // Copy the bookmark of the newly added record into the NewRowBookmark parameter VariantCopy(NewRowBookmark, &COleVariant(rs->GetPosition())); // Calibrate the vertical scrollbar by informing the grid of the new record count m_grid.SetApproxCount(m_lstBookmarks.Length()); } //删除一行 void CGridView::OnUnboundDeleteRowMatgrid(VARIANT FAR* Bookmark) { XDbfTable *rs = m_pTable; if (!rs || !m_lstBookmarks) { V_VT(Bookmark) = VT_NULL; return; } // Move to the record to be deleted in the recordset, then delete it ASSERT(V_VT(Bookmark)==VT_I4); long nBookmark=V_I4(Bookmark); int nLen=m_lstBookmarks.Length(); for(int i=0; iMoveTo(nBookmark); rs->Delete(); // Calibrate the vertical scrollbar by informing the grid of the new record count m_grid.SetApproxCount(m_lstBookmarks.Length()); } // 单击列的头部进行排序 void CGridView::OnHeadClickMatgrid(short ColIndex) { CTrueDBGrid50_Columns Cols = m_grid.GetColumns(); CString sField = m_lstHeadInfo[ColIndex]->m_sName; if (sField==m_sSortFieldName) { if (m_bAscend) m_bAscend=FALSE; else m_bAscend=TRUE; } else { m_sSortFieldName = sField; m_bAscend = TRUE; } g_bSortAscend = m_bAscend; GetBookmarks(FALSE); m_grid.ReBind(); } #endif