// DBFView.cpp : implementation of the CDBFView class
//
#include "stdafx.h"
#include "DBFViewApp.h"
#include "DBFView.h"
#include "MemoDlg.h"
#include "FindDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDBFView
IMPLEMENT_DYNCREATE(CDBFView, CXGridView)
BEGIN_MESSAGE_MAP(CDBFView, CXGridView)
//{{AFX_MSG_MAP(CDBFView)
ON_UPDATE_COMMAND_UI(ID_VIEW__DOS, OnUpdateViewDos)
ON_UPDATE_COMMAND_UI(ID_VIEW__WIN, OnUpdateViewWin)
ON_COMMAND(ID_VIEW__DOS, OnViewDos)
ON_COMMAND(ID_VIEW__WIN, OnViewWin)
ON_COMMAND(IDC_ADVBUTTON, OnAdvButton)
ON_COMMAND(ID_EDIT_FIND, OnEditFind)
ON_UPDATE_COMMAND_UI(ID_EDIT_FIND, OnUpdateEditFind)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CXGridView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CXGridView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CXGridView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDBFView construction/destruction
CDBFView::CDBFView()
{
m_bDOScode = FALSE;
m_pctrlButton = NULL;
DefineColCtrl(AddCol(0,""), GA_CELLCTRL);
m_pSet = NULL;
m_ImageList.Create(IDB_BITMAP_DEL, 5, 5, (COLORREF)0x808000);
SetFrozenColCount(2, FALSE);
CSize sizeExArea(50,50);
SetExtAreaSize(sizeExArea, FALSE);
}
CDBFView::~CDBFView()
{
if(m_pctrlButton != NULL)
delete m_pctrlButton;
m_pctrlButton = NULL;
}
BOOL CDBFView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CXGridView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CDBFView drawing
void CDBFView::OnDraw(CDC* pDC)
{
CDBFViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CDBFView printing
BOOL CDBFView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CDBFView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CDBFView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CDBFView diagnostics
#ifdef _DEBUG
void CDBFView::AssertValid() const
{
CXGridView::AssertValid();
}
void CDBFView::Dump(CDumpContext& dc) const
{
CXGridView::Dump(dc);
}
CDBFViewDoc* CDBFView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDBFViewDoc)));
return (CDBFViewDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDBFView message handlers
void CDBFView::OnUpdateViewDos(CCmdUI* pCmdUI)
{
pCmdUI->SetRadio(m_bDOScode);
}
void CDBFView::OnUpdateViewWin(CCmdUI* pCmdUI)
{
pCmdUI->SetRadio(!m_bDOScode);
}
void CDBFView::OnViewDos()
{
if(m_bDOScode)
{
m_bDOScode = FALSE;
m_pSet->SetTextConvertFunction(NULL);
}
else
{
m_bDOScode = TRUE;
m_pSet->SetTextConvertFunction(alxOemToAnsiConvert);
}
CALXCellCtrl* pCellCtrl = GetCellCtrl(GetActiveCol(),GetActiveRow());
if(pCellCtrl != NULL)
{
CELL_DATA CellData = GetCellData(GetActiveCol(),GetActiveRow());
pCellCtrl->SetData(CellData);
}
Invalidate();
}
void CDBFView::OnViewWin()
{
m_bDOScode = FALSE;
m_pSet->SetTextConvertFunction(NULL);
CALXCellCtrl* pCellCtrl = GetCellCtrl(GetActiveCol(),GetActiveRow());
if(pCellCtrl != NULL)
{
CELL_DATA CellData = GetCellData(GetActiveCol(),GetActiveRow());
pCellCtrl->SetData(CellData);
}
Invalidate();
}
void CDBFView::OnInitialUpdate()
{
m_pSet = &GetDocument()->m_Set;
m_nActiveCol = GetFrozenColCount();
m_nActiveRow = GetHeadRowCount();
RemoveAllCol();
SetGridRowCount(0);
if(m_pSet->IsOpen())
{
TEXTMETRIC tm;
CDC* pDC = GetDC();
pDC->GetTextMetrics(&tm);
ReleaseDC(pDC);
for(int iFld = 0; iFld < m_pSet->m_DBFFields.GetFieldCount(); iFld++)
{
int width = (m_pSet->m_DBFFields[iFld].m_nLen + 3)*tm.tmAveCharWidth;
width = min(width, 1000);
switch(m_pSet->m_DBFFields[iFld].m_chType)
{
// Logical
case FLD_TYPE_LOGICAL:
// Date, DateTime, _NullFlags
case FLD_TYPE_DATE:
case FLD_TYPE_DATETIME:
case FLD_TYPE_NULLFLAGS:
DefineColCtrl(AddCol(width, m_pSet->m_DBFFields[iFld].m_strName, ACFF_CENTER, AHFF_CENTER, 0, 0, iFld+100), GA_EDITCTRL, WS_CHILD | ES_CENTER | ES_AUTOHSCROLL,iFld+100);
break;
// Currency, Numeric, Float, Double, Integer
case FLD_TYPE_CURRENCY:
case FLD_TYPE_NUMERIC:
case FLD_TYPE_FLOAT:
case FLD_TYPE_DOUBLE:
case FLD_TYPE_INTEGER:
DefineColCtrl(AddCol(width, m_pSet->m_DBFFields[iFld].m_strName, ACFF_RIGHT, AHFF_CENTER, 0, 0, iFld+100), GA_EDITCTRL, WS_CHILD | ES_RIGHT | ES_AUTOHSCROLL,iFld+100);
break;
case FLD_TYPE_CHARACTER:
DefineColCtrl(AddCol(width, m_pSet->m_DBFFields[iFld].m_strName, ACFF_LEFT, AHFF_CENTER, 0, 0, iFld+100), GA_EDITCTRL, WS_CHILD | ES_LEFT | ES_AUTOHSCROLL,iFld+100);
break;
case FLD_TYPE_MEMO:
DefineColCtrl(AddCol(width, m_pSet->m_DBFFields[iFld].m_strName, ACFF_LEFT, AHFF_CENTER, 0, 0, iFld+100), GA_BUTTONCTRL, WS_CHILD | WS_TABSTOP,iFld+100);
break;
// Unknow
default:
DefineColCtrl(AddCol(width, m_pSet->m_DBFFields[iFld].m_strName, ACFF_LEFT, AHFF_CENTER, 0, 0, iFld+100), GA_CELLCTRL);
}
}
}
else
{
DefineColCtrl(AddCol(0,""), GA_CELLCTRL);
}
CXGridView::OnInitialUpdate();
}
CELL_DATA CDBFView::GetCellData(int nCol, int nRow)
{
CELL_DATA CellData = CALXGrid::GetCellData(nCol,nRow);
m_pSet->SetAbsolutePosition(nRow);
COleVariant varValue;
long lLen = m_pSet->GetFieldValue(nCol,varValue); // lLen - len value in table (in byte)
switch(varValue.vt)
{
case VT_BSTR:
{
CellData.m_strText = varValue.bstrVal;
break;
}
case VT_R8:
{
CString strFormat;
strFormat.Format("%s.%uf","%",m_pSet->m_DBFFields[nCol].m_nDec);
CellData.m_strText.Format(strFormat,varValue.dblVal);
break;
}
case VT_BOOL:
{
if(varValue.boolVal)
CellData.m_strText = 'T';
else
CellData.m_strText = 'F';
break;
}
case VT_R4:
{
CString strFormat;
CellData.m_strText.Format("%d",varValue.lVal);
break;
}
case VT_CY:
{
COleCurrency curValue;
curValue.m_cur = varValue.cyVal;
CellData.m_strText = curValue.Format();
break;
}
case VT_DATE:
{
if(varValue.date > MIN_DATE && varValue.date < MAX_DATE)
{
COleDateTime dteValue(varValue);
CellData.m_strText = dteValue.Format("%Y.%m.%d");
}
break;
}
case VT_BYREF|VT_UI1:
{
long lLen = 40;
if(lLen > 0 && varValue.pbVal != NULL)
{
CString str;
for(int i = 0; i < min(lLen,100); i++)
{
str.Format("0%X",varValue.pbVal[i]);
CellData.m_strText = CellData.m_strText + " " + str.Right(2);
}
}
break;
}
}
return CellData;
}
BOOL CDBFView::OnSaveCellData(int nCol, int nRow)
{
CALXCellCtrl* pCellCtrl = GetCellCtrl(nCol,nRow);
// ���� ���� ��� ���������
if(pCellCtrl != NULL)
{
// �������� ������ �� ��. ���������� �������
CELL_DATA CellData = pCellCtrl->GetCellData();
// ��������� � ������ ������
m_pSet->SetAbsolutePosition(nRow);
COleVariant varValue;
varValue.Clear();
// � ����������� �� ���� ����
switch(m_pSet->m_DBFFields[nCol].m_chType)
{
case FLD_TYPE_CHARACTER: // ���������� ���� �������
{
varValue = CellData.m_strText;
break;
}
case FLD_TYPE_LOGICAL: // ����������
{
varValue.vt = VT_BOOL;
CString strText = CellData.m_strText.Left(10);
strText.TrimLeft();strText.TrimRight();
strText.MakeUpper();
if(strText == "T" || strText == "Y" || strText == "YES" || strText == "TRUE" || strText == "��" || strText == "������")
varValue.boolVal = TRUE;
else
varValue.boolVal = FALSE;
break;
}
case FLD_TYPE_NUMERIC: // ��������
case FLD_TYPE_FLOAT:
{
double db = atof(CellData.m_strText);
varValue = db;
break;
}
case FLD_TYPE_DATE: // ����
{
COleDateTime dte;
if(dte.ParseDateTime(CellData.m_strText))
varValue = dte;
break;
}
case FLD_TYPE_DATETIME: // ���� � �����
{
COleDateTime dte;
if(dte.ParseDateTime(CellData.m_strText))
varValue = dte;
break;
}
case FLD_TYPE_CURRENCY: // ������
{
COleCurrency cur;
if(cur.ParseCurrency(CellData.m_strText))
varValue = cur;
break;
}
case FLD_TYPE_INTEGER: // integer
{
long l = atol(CellData.m_strText);
varValue = l;
break;
}
case FLD_TYPE_DOUBLE: // double
{
double db = atof(CellData.m_strText);
varValue = db;
break;
}
default:
return FALSE;
}
// ���������� ���������
m_pSet->Edit();
m_pSet->SetFieldValue(nCol,varValue);
m_pSet->Update();
}
return TRUE;
}
CALXCellCtrl* CDBFView::GetCellCtrl(int nCol, int nRow)
{
if(m_pSet == NULL || !m_pSet->IsOpen())
return NULL;
if(m_pSet->m_DBFFields[nCol].m_chType == FLD_TYPE_MEMO)
{
if(m_pctrlButton == NULL)
{
m_pctrlButton = new CAdvButton;
m_pctrlButton->CreateCtrl(WS_CHILD | BS_OWNERDRAW | WS_TABSTOP,this,IDC_ADVBUTTON);
m_pctrlButton->EnableCtrl(FALSE);
m_pctrlButton->SetFontCtrl(GetGridFont());
// m_pctrlButton->SetFocusRect(&m_MetricsCells.m_FocusRect);
}
return m_pctrlButton;
}
else
return CXGridView::GetCellCtrl(nCol, nRow);
}
CALXCellMetrics* CDBFView::GetCellMetrics(int nCol, int nRow)
{
m_pSet->SetAbsolutePosition(nRow);
if(m_pSet->IsDeleted())
m_MetricsCells.m_DefaultCellColor.m_crText = ::GetSysColor(COLOR_3DSHADOW);
else
m_MetricsCells.m_DefaultCellColor.m_crText = ::GetSysColor(COLOR_WINDOWTEXT);
return &m_MetricsCells;
}
// Draw frozen cell.
void CDBFView::OnDrawFrozenCell(CDC *pDC, int nCol, int nRow, int x, int y)
{
int cx = GetColWidth(nCol) + 1;
int cy = m_nRowHeight + 1;
if(nCol == 0)
{
BOOL bPressed = (nCol == m_nFrozenColPressed && nRow == m_nFrozenRowPressed);
BOOL bDrawArrow = m_nActiveRow == nRow || (GetKeyState(VK_SHIFT) >= 0 && nRow == m_nFrozenRowPressed);
DrawFrozenBtn(pDC, x, y, cx, cy, bPressed, bDrawArrow);
}
else
{
DrawFrozenBtn(pDC, x, y, cx, cy, TRUE, FALSE);
// ��������� � ������ ������
m_pSet->SetAbsolutePosition(nRow - GetHeadRowCount());
// draw del flag
// �������� ������ ���������
CRect rectCell(x,y,max(x,x+cx),max(y,y+cy));
rectCell.DeflateRect(1,1,1,1);
if(!rectCell.IsRectEmpty())
{
if(m_pSet->IsDeleted())
{
IMAGELISTDRAWPARAMS imldp;
memset(&imldp, 0, sizeof(imldp));
imldp.cbSize = sizeof(imldp);
imldp.hdcDst = pDC->m_hDC;
imldp.rgbBk = CLR_DEFAULT;
imldp.rgbFg = CLR_DEFAULT;
imldp.fStyle = ILD_TRANSPARENT;
imldp.himl = m_ImageList.m_hImageList;
imldp.i = 0;
imldp.cx = min(5,rectCell.Width());
imldp.cy = min(5,rectCell.Height());
imldp.x = rectCell.left + max(0,rectCell.Width()-5)/2;
imldp.y = rectCell.top + max(0,rectCell.Height()-5)/2;
if(imldp.himl != NULL)
ImageList_DrawIndirect(&imldp);
}
}
}
}
void CDBFView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if(m_pSet != NULL && m_pSet->IsOpen() && m_pSet->GetRecordCount() > 0)
{
m_pSet->MoveFirst();
m_CurRec = 0;
SetGridRowCount(m_pSet->GetRecordCount());
}
else
SetGridRowCount(0);
Invalidate();
UpdateScrollSizes();
}
void CDBFView::OnAdvButton()
{
if(m_pSet->m_DBFFields[GetActiveCol()].m_chType == FLD_TYPE_MEMO)
{
CMemoDlg m_MemoDlg(this);
m_MemoDlg.m_pSet = m_pSet;
m_MemoDlg.m_iFld = GetActiveCol();
m_MemoDlg.m_iRec = GetActiveRow();
m_MemoDlg.m_pctrlButton = m_pctrlButton;
m_MemoDlg.DoModal();
}
}
void CDBFView::OnFrozenButtonDblClk(int nFrozenCol, int nFrozenRow)
{
OnFrozenButtonDown(nFrozenCol, nFrozenRow);
if(nFrozenCol == 1 && GetKeyState(VK_SHIFT) >= 0)
{
// ��������� � ������ ������
m_pSet->SetAbsolutePosition(nFrozenRow);
if(m_pSet->IsDeleted())
m_pSet->Undelete();
else
m_pSet->Delete();
InvalidateRow(nFrozenRow);
}
return;
}
void CDBFView::OnEditFind()
{
CFindDlg m_FindDlg;
m_FindDlg.m_strExpression = GetDocument()->m_strExpression;
try
{
if(m_FindDlg.DoModal() == IDOK)
{
GetDocument()->m_strExpression = m_FindDlg.m_strExpression;
BOOL bFind = FALSE;
switch(m_FindDlg.m_nFindType)
{
case IDFT_FINDFIRST:
bFind = m_pSet->FindFirst(m_FindDlg.m_strExpression);
break;
case IDFT_FINDNEXT:
m_pSet->SetAbsolutePosition(GetActiveRow());
bFind = m_pSet->FindNext(m_FindDlg.m_strExpression);
break;
case IDFT_FINDLAST:
bFind = m_pSet->FindLast(m_FindDlg.m_strExpression);
break;
case IDFT_FINDPREV:
m_pSet->SetAbsolutePosition(GetActiveRow());
bFind = m_pSet->FindPrev(m_FindDlg.m_strExpression);
break;
}
if(bFind)
SetActiveRow(m_pSet->GetAbsolutePosition());
else
AfxMessageBox("Not found");
}
}
catch(CDBFException* e)
{
e->ReportError();
e->Delete();
}
}
void CDBFView::OnUpdateEditFind(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pSet->IsOpen() && m_pSet->GetRecordCount() > 0);
}