// ex32avw.cpp : implementation of the CEx32aView class // #include "stdafx.h" #include "ex32a.h" #include "ex32adoc.h" #include "ex32aView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CEx32aView IMPLEMENT_DYNCREATE(CEx32aView, CRowView) BEGIN_MESSAGE_MAP(CEx32aView, CRowView) //{{AFX_MSG_MAP(CEx32aView) ON_WM_SETFOCUS() ON_WM_MOUSEACTIVATE() ON_WM_TIMER() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CRowView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRowView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CEx32aView construction/destruction CEx32aView::CEx32aView() { m_pSet = NULL; } CEx32aView::~CEx32aView() { } ///////////////////////////////////////////////////////////////////////////// void CEx32aView::OnUpdate(CView*, LPARAM lHint, CObject* pHint) { // called when the user executes a new query // can't set m_pSet in OnInitialUpdate because it's NULL then ScrollToPosition(CPoint(0, 0)); Invalidate(TRUE); m_nSelectedRow = -1; CEx32aDoc* pDoc = GetDocument(); if((m_pSet = pDoc->m_pRecordset) != NULL) { UpdateScrollSizes(); } } ///////////////////////////////////////////////////////////////////////////// // CRowView overrides ///////////////////////////////////////////////////////////////////////////// void CEx32aView::OnDrawRow(CDC* pDC, int nRow, int y, BOOL bSelected) { int x = 0; int i; CEx32aDoc* pDoc = GetDocument(); if (m_pSet == NULL) return; if (nRow == 0) { // title row for (i = 0; i < pDoc->m_nFields; i++) { pDC->TextOut(x, y, pDoc->m_arrayFieldName[i]); x += pDoc->m_arrayFieldSize[i] * m_nCharWidth; } } else { try { m_pSet->SetAbsolutePosition(nRow - 1); // adjust for title row // SetAbsolutePosition doesn't throw exception until AFTER // end of set if (m_pSet->GetAbsolutePosition() == (nRow - 1)) { DrawDataRow(pDC, y); } } catch (CDaoException* e) { // might be a time delay before delete is seen in this program if (e->m_pErrorInfo->m_lErrorCode == 3167) { pDC->TextOut(0, y, "**RECORD DELETED**"); } else { m_pSet->MoveLast(); // in case m_nRowCount is too big pDoc->m_nRowCount = m_pSet->GetAbsolutePosition() + 2; } e->Delete(); } } } void CEx32aView::DrawDataRow(CDC* pDC, int y) { int x = 0; CString strTime; COleVariant var; CString str; CEx32aDoc* pDoc = GetDocument(); for (int i = 0; i < pDoc->m_nFields; i++) { var = m_pSet->GetFieldValue(i); switch (var.vt) { case VT_BSTR: str = (LPCSTR) var.bstrVal; // narrow characters in DAO break; case VT_I2: str.Format("%d", (int) var.iVal); break; case VT_I4: str.Format("%d", var.lVal); break; case VT_R4: str.Format("%10.2f", (double) var.fltVal); break; case VT_R8: str.Format("%10.2f", var.dblVal); break; case VT_CY: str = COleCurrency(var).Format(); break; case VT_DATE: str = COleDateTime(var).Format(); break; case VT_BOOL: str = (var.boolVal == 0) ? "FALSE" : "TRUE"; break; case VT_NULL: str = "----"; break; default: str.Format("Unk type %d\n", var.vt); TRACE("Unknown type %d\n", var.vt); } pDC->TextOut(x, y, str); x += pDoc->m_arrayFieldSize[i] * m_nCharWidth; } } ///////////////////////////////////////////////////////////////////////////// void CEx32aView::GetRowWidthHeight(CDC* pDC, int& nRowWidth, int& nRowHeight, int& nCharWidth) { TEXTMETRIC tm; CEx32aDoc* pDoc = GetDocument(); pDC->GetTextMetrics(&tm); nCharWidth = tm.tmAveCharWidth + 1; nRowWidth = 0; for(int i = 0; i < pDoc->m_nFields; i++) { nRowWidth += pDoc->m_arrayFieldSize[i]; } nRowWidth *= nCharWidth; nRowHeight = tm.tmHeight; } ///////////////////////////////////////////////////////////////////////////// int CEx32aView::GetActiveRow() { return m_nSelectedRow; } ///////////////////////////////////////////////////////////////////////////// int CEx32aView::GetRowCount() { return GetDocument()->m_nRowCount; } ///////////////////////////////////////////////////////////////////////////// void CEx32aView::ChangeSelectionNextRow(BOOL bNext) { if (bNext && (m_nSelectedRow < min(GetRowCount() - 1, LastViewableRow() - 2))) { m_nSelectedRow++; } if (!bNext && m_nSelectedRow) { m_nSelectedRow--; } UpdateRow(m_nSelectedRow); } ///////////////////////////////////////////////////////////////////////////// void CEx32aView::ChangeSelectionToRow(int nRow) { if ((nRow >= 0) && (nRow < min(GetRowCount(), LastViewableRow() - 1))) { m_nSelectedRow = nRow; } UpdateRow(m_nSelectedRow); } ///////////////////////////////////////////////////////////////////////////// // CEx32aView diagnostics #ifdef _DEBUG void CEx32aView::AssertValid() const { CRowView::AssertValid(); } void CEx32aView::Dump(CDumpContext& dc) const { CRowView::Dump(dc); } ///////////////////////////////////////////////////////////////////////////// CEx32aDoc* CEx32aView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEx32aDoc))); return (CEx32aDoc*) m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CEx32aView message handlers ///////////////////////////////////////////////////////////////////////////// void CEx32aView::OnSetFocus(CWnd* pOldWnd) { // updates dialog bar query strings GetDocument()->PutQuery(); CRowView::OnSetFocus(pOldWnd); } ///////////////////////////////////////////////////////////////////////////// int CEx32aView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { // resets the focus from the dialog bar SetFocus(); return CRowView::OnMouseActivate(pDesktopWnd, nHitTest, message); } void CEx32aView::OnInitialUpdate() { CRowView::OnInitialUpdate(); } void CEx32aView::OnTimer(UINT nIDEvent) { Invalidate(); // update view from database }