📄 tblview.cpp
字号:
// TblView.cpp : implementation of the CDaoTableView class
//
#include "stdafx.h"
#include "MSDIApp.h"
#include "MSDIDao.h"
#include "DaoSet.h"
#include "DaoDoc.h"
#include "TblView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define OFFITEM 1
#define OFFCHAR 2
#define BSIZE 256
// for printing only
#define HEADER_LINE 3
#define FOOTER_LINE 3
#define LABEL_LINE 2
#define OFFSET_PAGE 15
#define TOTAL_LINE (HEADER_LINE+FOOTER_LINE+LABEL_LINE)
int DaoListFormat(short Type)
{
switch (Type)
{
case dbBoolean: break;
case dbByte: break;
case dbInteger: return LVCFMT_RIGHT;
case dbLong: return LVCFMT_RIGHT;
case dbCurrency: return LVCFMT_RIGHT;
case dbSingle: return LVCFMT_RIGHT;
case dbDouble: return LVCFMT_RIGHT;
case dbDate: break;
case dbText: break;
case dbLongBinary: break;
case dbMemo: break;
case dbGUID: break;
}
return LVCFMT_LEFT;
}
/////////////////////////////////////////////////////////////////////////////
// CDaoTableView
IMPLEMENT_DYNCREATE(CDaoTableView, CListView)
BEGIN_MESSAGE_MAP(CDaoTableView, CListView)
//{{AFX_MSG_MAP(CDaoTableView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
ON_NOTIFY_REFLECT(NM_RETURN, OnReturn)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
//}}AFX_MSG_MAP
// Header command
ON_NOTIFY_REFLECT(HDN_BEGINTRACK, OnHeaderBeginTrack)
ON_NOTIFY_REFLECT(HDN_ENDTRACK, OnHeaderEndTrack)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDaoTableView construction/destruction
CDaoTableView::CDaoTableView()
{
m_colorText = ::GetSysColor(COLOR_WINDOWTEXT);
m_colorTextBk = ::GetSysColor(COLOR_WINDOW);
m_colorBkgnd = ::GetSysColor(COLOR_WINDOW);
m_bFitToPage = FALSE;
m_bPrintMarge = TRUE;
}
CDaoTableView::~CDaoTableView()
{
if (m_Font.m_hObject != NULL) m_Font.DeleteObject();
}
BOOL CDaoTableView::PreCreateWindow(CREATESTRUCT& cs)
{
// default is report view and full row selection
cs.style &= ~LVS_TYPEMASK;
cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED;
return CListView::PreCreateWindow(cs);
}
int CDaoTableView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
// Create the default font for the list
int Height = (3 * HIWORD(::GetDialogBaseUnits())) / 4;
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -Height;
lf.lfWeight = (Height > 13) ? 700: 400;
lf.lfPitchAndFamily = 0x31;
strcpy(lf.lfFaceName, "Courier New");
VERIFY(m_Font.CreateFontIndirect(&lf));
return 0;
}
void CDaoTableView::OnSize(UINT nType, int cx, int cy)
{
m_cxClient = cx; m_cyClient = cy;
CListView::OnSize(nType, cx, cy);
}
void CDaoTableView::OnPaint()
{
// in full row select mode, we need to extend the clipping region
// so we can paint a selection all the way to the right
CRect rectAllLabels;
GetListCtrl().GetItemRect(0, rectAllLabels, LVIR_BOUNDS);
if (rectAllLabels.right < m_cxClient)
{
// need to call BeginPaint (in CPaintDC constructor)
// to get correct clipping rect
CPaintDC dc(this);
CRect rectClip;
dc.GetClipBox(rectClip);
if (!rectClip.IsRectEmpty())
{
rectClip.left = min(rectAllLabels.right - 1, rectClip.left);
rectClip.right = m_cxClient;
InvalidateRect(rectClip, FALSE);
}
// EndPaint will be called in CPaintDC destructor
DrawRaster(&dc);
}
CListView::OnPaint();
}
void CDaoTableView::OnSetFocus(CWnd* pOldWnd)
{
CListView::OnSetFocus(pOldWnd);
// check if we are getting focus from label edit box
if (pOldWnd != NULL && pOldWnd->GetParent() == this)
return;
// repaint items that should change appearance
RepaintSelectedItems();
}
void CDaoTableView::OnKillFocus(CWnd* pNewWnd)
{
CListView::OnKillFocus(pNewWnd);
// check if we are losing focus to label edit box
if (pNewWnd != NULL && pNewWnd->GetParent() == this)
return;
// repaint items that should change appearance
RepaintSelectedItems();
}
void CDaoTableView::OnInitialUpdate()
{
// Initialise table
CListCtrl& ctrlList = GetListCtrl();
ctrlList.DeleteAllItems();
while (ctrlList.DeleteColumn(0));
UpdateWindow();
// get textmetric
ctrlList.SetFont(&m_Font);
m_tmAveCharWidth = ctrlList.GetStringWidth(" ");
// get recordset and update
CDaoRecordset* pSet = OnGetRecordset();
if (pSet == NULL) return;
ASSERT(pSet->m_pDatabase != NULL);
ASSERT(pSet->IsOpen());
CWaitCursor waitCursor;
// Set columns
CDaoFieldInfo fieldInfo;
CDaoTableDef tableDef(pSet->m_pDatabase);
try
{
CString strLabel;
int nMask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
tableDef.Open(pSet->GetName());
int m_nField = tableDef.GetFieldCount();
for (int i = 0; i < m_nField; i++)
{
tableDef.GetFieldInfo(i, fieldInfo, AFX_DAO_ALL_INFO);
strLabel = fieldInfo.m_strName;
AddColumn(strLabel, i, -1, nMask, DaoListFormat(fieldInfo.m_nType));
// the fist column is can only be left justified !
if (i == 0) m_nJustifyFirstCol = DaoListFormat(fieldInfo.m_nType);
}
}
catch (CDaoException* e)
{
DaoMessageBox(e);
e->Delete();
}
tableDef.Close();
CListView::OnInitialUpdate();
}
void CDaoTableView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// get recordset and update
CDaoRecordset* pSet = OnGetRecordset();
// for me ?
if (pHint && pHint != pSet) return;
// Clean up
GetListCtrl().DeleteAllItems();
if (pSet == NULL) return;
ASSERT(pSet->m_pDatabase != NULL);
ASSERT(pSet->IsOpen());
CWaitCursor waitCursor;
m_Record.RemoveAll();
m_Record.SetSize(GetRecordCount());
// set data
try
{
UINT iItem = 0;
pSet->MoveFirst();
COleVariant var;
while (!pSet->IsEOF())
{
var = pSet->GetBookmark();
m_Record.SetAt(iItem, var);
AddItem(iItem++);
pSet->MoveNext();
}
pSet->MoveFirst();
var = pSet->GetBookmark();
}
catch (CDaoException* e)
{
DaoMessageBox(e);
e->Delete();
}
UpdateWindow();
}
/////////////////////////////////////////////////////////////////////////////
// CDaoTableView virtual functions
CDaoRecordset* CDaoTableView::OnGetRecordset()
{
ASSERT(FALSE); // must be overrided
return NULL;
}
long CDaoTableView::GetRecordCount()
{
ASSERT(FALSE); // must be overrided
return 0L;
}
/////////////////////////////////////////////////////////////////////////////
// CDaoTableView helper functions
UINT CDaoTableView::JustifyText(int fmt, int c)
{
// the first column can only be left justified
if (c == 0) fmt = m_nJustifyFirstCol;
UINT nJustify = DT_LEFT;
switch(fmt & LVCFMT_JUSTIFYMASK)
{
case LVCFMT_RIGHT:
nJustify = DT_RIGHT;
break;
case LVCFMT_CENTER:
nJustify = DT_CENTER;
break;
}
return nJustify|DT_SINGLELINE|DT_NOPREFIX|DT_NOCLIP|DT_VCENTER;
}
void CDaoTableView::RepaintSelectedItems()
{
CListCtrl& ctrlList = GetListCtrl();
CRect rectItem, rectLabel;
// invalidate focused item so it can repaint properly
int nItem = ctrlList.GetNextItem(-1, LVNI_FOCUSED);
if (nItem != -1)
{
ctrlList.GetItemRect(nItem, rectItem, LVIR_BOUNDS);
ctrlList.GetItemRect(nItem, rectLabel, LVIR_LABEL);
rectItem.left = rectLabel.left;
InvalidateRect(rectItem, FALSE);
}
// if selected items should not be preserved, invalidate them
if (!(GetStyle() & LVS_SHOWSELALWAYS))
{
for (nItem = ctrlList.GetNextItem(-1, LVNI_SELECTED);
nItem != -1; nItem = ctrlList.GetNextItem(nItem, LVNI_SELECTED))
{
ctrlList.GetItemRect(nItem, rectItem, LVIR_BOUNDS);
ctrlList.GetItemRect(nItem, rectLabel, LVIR_LABEL);
rectItem.left = rectLabel.left;
InvalidateRect(rectItem, FALSE);
}
}
// update changes
UpdateWindow();
}
void CDaoTableView::UpdateViews()
{
// Find the focused item
CListCtrl& ctrlList = GetListCtrl();
int nItem = ctrlList.GetNextItem(-1, LVNI_FOCUSED);
if (nItem != -1)
{
// read the record and update all views
CDaoRecordset* pSet = OnGetRecordset();
COleVariant var = pSet->GetBookmark();
if (var != m_Record.GetAt(nItem))
{
try
{
pSet->SetBookmark(m_Record.GetAt(nItem));
}
catch (CDaoException* e)
{
DaoMessageBox(e);
e->Delete();
}
}
// Send message to all views with the recordset pointer
GetDocument()->UpdateAllViews(this, 0, pSet);
}
}
BOOL CDaoTableView::AddColumn(LPCTSTR strItem, int nItem, int nSubItem, int nMask, int nFmt)
{
LV_COLUMN lvc;
lvc.mask = nMask;
lvc.fmt = nFmt;
lvc.pszText = (LPTSTR)strItem;
CListCtrl& ctrlList = GetListCtrl();
lvc.cx = ctrlList.GetStringWidth(" ");
lvc.cx *= strlen(strItem) + OFFCHAR;
if (nMask & LVCF_SUBITEM)
{
if (nSubItem != -1)
lvc.iSubItem = nSubItem;
else
lvc.iSubItem = nItem;
}
return ctrlList.InsertColumn(nItem, &lvc);
}
BOOL CDaoTableView::AddItem(int nItem, LPARAM lParam)
{
CListCtrl& ctrlList = GetListCtrl();
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT|LVIF_PARAM;
lvItem.iItem = nItem;
lvItem.iSubItem = 0;
lvItem.pszText = LPSTR_TEXTCALLBACK;
lvItem.lParam = lParam;
if (nItem == 0)
{
lvItem.mask |= LVIF_STATE;
lvItem.state = LVIS_SELECTED;
}
return ctrlList.InsertItem(&lvItem);
}
LPCTSTR CDaoTableView::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
{
static const _TCHAR szThreeDots[] = _T("...");
int nStringLen = lstrlen(lpszLong);
if (nStringLen == 0 || pDC->GetTextExtent(lpszLong, nStringLen).cx + nOffset <= nColumnLen)
return(lpszLong);
static _TCHAR szShort[MAX_PATH];
lstrcpy(szShort, lpszLong);
int nAddLen = pDC->GetTextExtent(szThreeDots, sizeof(szThreeDots)).cx;
for (int i = nStringLen - 1; i > 0; i--)
{
szShort[i] = 0;
if (pDC->GetTextExtent(szShort, i).cx + nOffset + nAddLen <= nColumnLen)
break;
}
lstrcat(szShort, szThreeDots);
return(szShort);
}
void CDaoTableView::DrawRaster(CDC* pDC)
{
CListCtrl& ctrlList = GetListCtrl();
CRect rectItem; ctrlList.GetItemRect(0, &rectItem, LVIR_BOUNDS);
LV_COLUMN lvc; int x = rectItem.left;
lvc.mask = LVCF_FMT | LVCF_WIDTH;
for (int c = 0; ctrlList.GetColumn(c, &lvc); c++)
{
x += lvc.cx;
pDC->MoveTo(x-1, 0);
pDC->LineTo(x-1, m_cyClient);
}
}
/////////////////////////////////////////////////////////////////////////////
// CDaoTableView printing helpers
void CDaoTableView::GetPrintTitle(CString& strTitle)
{
ASSERT(FALSE);
strTitle = _T("");
}
void CDaoTableView::SetPrintRectangle(CDC* pDC, CPrintInfo* pInfo)
{
LPDEVMODE pDM = pInfo->m_pPD->GetDevMode();
pInfo->m_rectDraw.SetRect(0, 0, pDC->GetDeviceCaps(HORZRES),
pDC->GetDeviceCaps(VERTRES));
if (m_bPrintMarge)
{
if (pDM->dmOrientation == DMORIENT_PORTRAIT)
pInfo->m_rectDraw.left +=
MulDiv(pDC->GetDeviceCaps(LOGPIXELSX), OFFSET_PAGE, 25);
else
pInfo->m_rectDraw.top +=
MulDiv(pDC->GetDeviceCaps(LOGPIXELSX), OFFSET_PAGE, 25);
}
if (pDM->dmDefaultSource == DMBIN_TRACTOR)
{
pInfo->m_rectDraw.top += pDC->GetDeviceCaps(LOGPIXELSY);
pInfo->m_rectDraw.bottom -= pDC->GetDeviceCaps(LOGPIXELSY);
}
}
int CDaoTableView::PrintCharPerLine()
{
int cx = 0;
LV_COLUMN lvc;
CListCtrl& ctrlList = GetListCtrl();
lvc.mask = LVCF_WIDTH;
for (int c = 0; ctrlList.GetColumn(c, &lvc); c++)
cx += lvc.cx;
return cx / m_tmAveCharWidth;
}
int CDaoTableView::GetListLine(int Line, CString& strLine)
{
int nLen;
LV_COLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH;
char szBuffer[BSIZE+2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -