// dtxtable.cpp : implementation file
//
#include "stdafx.h"
#include "dtxtable.h"
#include <afxwin.h>
UINT WM_DTXRECORDCHANGE = ::RegisterWindowMessage (_T("WM_DTXRECORDCHANGE"));
UINT WM_DTXTABLEOPEN = ::RegisterWindowMessage (_T("WM_DTXTABLEOPEN"));
UINT WM_DTXTABLECLOSE = ::RegisterWindowMessage (_T("WM_DTXTABLECLOSE"));
UINT WM_CALCULATERECORD = ::RegisterWindowMessage (_T("WM_CALCULATERECORD"));
void WriteBlobToFile(CString nFileName, DTXField* fld)
{
if(fld && fld->blobVal && fld->blobVal->m_dwDataLength > 0)
{
CFile outFile(nFileName, CFile::modeCreate|CFile::modeWrite);
outFile.WriteHuge(fld->blobVal->m_hData, fld->blobVal->m_dwDataLength);
outFile.Close();
}
}
void VariantToLongBinary(COleVariant var, DTXField* fld)
{
if(fld->blobVal->m_hData)
delete fld->blobVal->m_hData;
fld->blobVal->m_dwDataLength = var.parray->rgsabound[0].cElements;
fld->blobVal->m_hData = new BYTE[fld->blobVal->m_dwDataLength];
ASSERT(fld->blobVal->m_hData);
if(fld->blobVal->m_hData != NULL)
{
void* pArrayData;
SafeArrayAccessData(var.parray, &pArrayData);
CopyMemory(fld->blobVal->m_hData, pArrayData, fld->blobVal->m_dwDataLength);
SafeArrayUnaccessData(var.parray);
}
}
COleVariant DTXFieldToVariant(DTXField* fld)
{
COleVariant var;
switch(fld->m_Type)
{
case dtxfBool : var.vt = VT_BOOL; var.boolVal = fld->boolVal; break;
case dtxfInteger: var.vt = VT_I4; var.intVal = fld->intVal; break;
case dtxfLong : var.vt = VT_I8; var.intVal = fld->longVal; break;
case dtxfFloat : var.vt = VT_R4; var.fltVal = fld->fltVal; break;
case dtxfDouble : var.vt = VT_R8; var.dblVal = fld->dblVal; break;
case dtxfDate :
case dtxfDateTime:
case dtxfTime : var.vt = VT_DATE; var.date = fld->date->m_dt; break;
case dtxfBlob :
VariantClear(&var);
SAFEARRAYBOUND bound;
bound.cElements = fld->blobVal->m_dwDataLength;
bound.lLbound = 0;
var.parray = ::SafeArrayCreate(VT_UI1, 1, &bound);
if(var.parray)
{
var.vt = VT_ARRAY|VT_UI1;
void* pArrayData;
SafeArrayAccessData(var.parray, &pArrayData);
CopyMemory(pArrayData, fld->blobVal->m_hData, fld->blobVal->m_dwDataLength);
SafeArrayUnaccessData(var.parray);
}
else
var.vt = VT_NULL;
break;
}
return var;
}
void VariantToDTXField(COleVariant var, DTXField* fld)
{
switch(var.vt)
{
case VT_BOOL: fld->boolVal = var.boolVal; break;
case VT_I1 : fld->intVal = var.iVal; break;
case VT_I2 : fld->intVal = var.iVal; break;
case VT_I4 :
case VT_I8 : fld->longVal = var.lVal; break;
case VT_CY :
{
COleCurrency cy(var.cyVal);
fld->cyVal->Format(_T("%s"), cy.Format());
}
break;
case VT_R4 : fld->fltVal = var.fltVal; break;
case VT_R8 : fld->dblVal = var.dblVal; break;
case VT_CLSID:
case VT_BSTR:
{
CString n = (LPCSTR) var.bstrVal;
fld->strVal->Format(_T("%s"), n);
}
break;
case VT_DATE:
{
COleDateTime dt(var.date);
CString n(dt.Format());
fld->date->ParseDateTime(n);
}
break;
case VT_BLOB:
case VT_ARRAY|VT_UI1:
VariantToLongBinary(var, fld);
break;
}
}
void StringToDTXField(CString str, DTXField* var)
{
switch (var->m_Type)
{
case dtxfMemo:
var->strVal->Format(_T("%s"), str);
break;
case dtxfString:
if(str.GetLength() > var->m_Length)
str.ReleaseBuffer(var->m_Length);
var->strVal->Format(_T("%s"), str);
break;
case dtxfInteger:
var->intVal = atoi(str);
break;
case dtxfLong:
var->longVal = atol(str);
break;
case dtxfFloat:
var->fltVal = (float) atof(str);
break;
case dtxfDouble:
var->dblVal = atof(str);
break;
case dtxfCurrency:
var->cyVal->Format(_T("%s"), str);
break;
case dtxfTime:
case dtxfDateTime:
case dtxfDate:
var->date->ParseDateTime(str);
break;
case dtxfBool:
str.MakeUpper();
var->boolVal = str == _T("TRUE") ? 1 : 0;
break;
default:
var->strVal->Format(_T("Bilinmeyen tip %s\n"), var->m_FieldName);
TRACE(*var->strVal);
}
}
CString DTXFieldToString(DTXField* var)
{
CString str;
switch (var->m_Type)
{
case dtxfMemo:
case dtxfString:
str = *var->strVal;
break;
case dtxfInteger:
str.Format(_T("%d"), (int) var->intVal);
break;
case dtxfLong:
str.Format(_T("%d"), (int) var->longVal);
break;
case dtxfFloat:
str.Format(_T("%.2f"), (double) var->fltVal);
break;
case dtxfDouble:
str.Format(_T("%.2f"), (double) var->dblVal);
break;
case dtxfCurrency:
str = *var->cyVal;
break;
case dtxfTime:
case dtxfDateTime:
case dtxfDate:
if(var->date->m_status != COleDateTime::invalid)
str = var->date->Format();
else
str.Empty();
break;
case dtxfBool:
str = (var->boolVal == 0) ? _T("FALSE") : _T("TRUE");
break;
default:
str.Format(_T("Bilinmeyen tip %s\n"), var->m_FieldName);
TRACE(str);
}
return str;
}
DTXField* NewField(DTXFieldType m_Type, DTXFieldKind m_Kind, CString m_FieldName,
UINT m_Start, UINT m_Length, int nOrigType)
{
DTXField* nRet = new DTXField(m_Type);
nRet->m_Type = m_Type;
nRet->m_Kind = m_Kind;
nRet->m_FieldName = m_FieldName;
nRet->m_Start = m_Start;
nRet->m_Length = m_Length;
nRet->m_OrigType = nOrigType;
return nRet;
}
DBColumn* NewDBColumn(CString m_FldName, CString m_Header, int m_Width, dbCollAlign m_Align)
{
DBColumn* nCol = new DBColumn();
nCol->m_FieldName = m_FldName;
nCol->m_Header = m_Header;
nCol->m_ColWidth = m_Width;
nCol->m_Align = m_Align;
return nCol;
}
/////////////////////////////////////////////////////////////////////////////
// CDBColArray
CDBColArray::CDBColArray()
{
}
CDBColArray::~CDBColArray()
{
FreeAll();
}
void CDBColArray::AddColumn(DBColumn* nNewColumn)
{
Add(nNewColumn);
}
void CDBColArray::FreeAll()
{
for(int i = 0; i < GetSize(); i++)
{
DBColumn * nCol = GetAt(i);
if(nCol)
delete nCol;
}
RemoveAll();
}
/////////////////////////////////////////////////////////////////////////////
// DTXField
DTXField::DTXField(DTXFieldType nType)
{
cyVal = strVal = NULL;
blobVal = NULL;
if(nType == dtxfString || nType == dtxfMemo)
strVal = new CString;
else if(nType == dtxfCurrency)
cyVal = new CString(_T("0"));
else if(nType == dtxfBlob)
blobVal = new CLongBinary;
else if(nType == dtxfDate || nType == dtxfTime || nType == dtxfDateTime)
{
COleDateTime t;
date = new COleDateTime(t.GetCurrentTime());
}
}
void DTXField::SetValueToNull()
{
switch(m_Type)
{
case dtxfInteger: intVal = 0; break;
case dtxfLong : longVal = 0; break;
case dtxfFloat : fltVal = 0.0; break;
case dtxfDouble : dblVal = 0.0; break;
case dtxfMemo :
case dtxfString : strVal->Format(_T("")); break;
case dtxfTime:
case dtxfDate:
case dtxfDateTime:
{
if(date) delete (COleDateTime*) date;
COleDateTime t;
date = new COleDateTime(t.GetCurrentTime());
}
break;
case dtxfCurrency: cyVal->Format(_T("0")); break;
case dtxfBool : boolVal = false; break;
case dtxfBlob :
if(blobVal)
delete (CLongBinary*) blobVal;
blobVal = new CLongBinary;
blobVal->m_dwDataLength = 0;
break;
}
}
DTXField::~DTXField()
{
if((m_Type == dtxfString || m_Type == dtxfMemo) && strVal)
delete (CString*) strVal;
else if(m_Type == dtxfCurrency && cyVal)
delete (CString*) cyVal;
else if(m_Type == dtxfBlob && blobVal)
delete (CLongBinary*) blobVal;
else if(date && (m_Type == dtxfDate || m_Type == dtxfTime || m_Type == dtxfDateTime))
delete (COleDateTime*) date;
}
/////////////////////////////////////////////////////////////////////////////
// CDTXFieldArray
CDTXFieldArray::CDTXFieldArray()
{
m_HaveCalculated = FALSE;
}
CDTXFieldArray::~CDTXFieldArray()
{
FreeAll();
}
void CDTXFieldArray::AddField(DTXField* nNewField)
{
Add(nNewField);
if(!m_HaveCalculated)
m_HaveCalculated = nNewField->m_Kind == dtxfkCalculated;
}
void CDTXFieldArray::FreeAll()
{
for(int i = 0; i < GetSize(); i++)
{
DTXField* nField = GetAt(i);
if(nField)
delete nField;
}
RemoveAll();
}
/////////////////////////////////////////////////////////////////////////////
// CDTXTable
CDTXTable::CDTXTable(CWnd* nOwner, CString nTableName)
{
m_Owner = nOwner;
m_TableName = nTableName;
m_isOpen = m_IsModified = FALSE;
m_EnableControls = m_AutoUpdate = TRUE;
}
CDTXTable::~CDTXTable()
{
m_FieldArray.FreeAll();
m_EditorList.RemoveAll();
}
DTXField* CDTXTable::operator [](int nIndex)
{
return m_FieldArray[nIndex];
}
DTXField* CDTXTable::GetField(CString nName)
{
nName.MakeUpper();
for(int i = 0; i < m_FieldArray.GetSize(); i++)
{
CString nArrName = m_FieldArray[i]->m_FieldName;
nArrName.MakeUpper();
if (nArrName == nName)
return m_FieldArray[i];
}
return NULL;
}
DTXField* CDTXTable::operator [](CString nName)
{
return GetField(nName);
}
BOOL CDTXTable::OpenTable()
{
BOOL nRet = intOpen();
if(nRet)
{
ReadFieldArray();
m_RecordSize = 0;
m_isOpen = TRUE;
for(int i = 0; i < m_FieldArray.GetSize(); i++)
{
m_FieldArray[i]->SetValueToNull();
if (m_FieldArray[i]->m_Kind != dtxfkCalculated)
m_RecordSize += m_FieldArray[i]->m_Length;
}
if(m_Owner && m_Owner->GetSafeHwnd())
m_Owner->PostMessage(WM_DTXTABLEOPEN, 0, (LPARAM)this);
for(i = 0; i < m_EditorList.GetSize(); i++)
m_EditorList[i]->TableOpened();
GoFirst();
}
return nRet;
}
BOOL CDTXTable::CloseTable()
{
if(TableOpened())
{
for(int i = 0; i < m_EditorList.GetSize(); i++)
m_EditorList[i]->TableClosed();
if(m_Owner && m_Owner->GetSafeHwnd())
m_Owner->PostMessage(WM_DTXTABLECLOSE, 0, (LPARAM)this);
m_FieldArray.FreeAll();
BOOL nRet = intClose();
m_isOpen = false;
return nRet;
}
return FALSE;
}
void CDTXTable::SendRecChangeMessage()
{
if(m_Owner && m_Owner->GetSafeHwnd())
{
m_Owner->PostMessage(WM_CALCULATERECORD,
(WPARAM) GetRecordPos(), (LPARAM)this);
m_Owner->PostMessage(WM_DTXRECORDCHANGE,
(WPARAM) GetRecordPos(), (LPARAM)this);
Refresh();
}
}
void CDTXTable::GoFirst()
{
if(!intIsBOF())
{
intGoFirst();
ReadCurrentRecord();
}
}
void CDTXTable::GoLast()
{
if(!intIsEOF())
{
intGoLast();
ReadCurrentRecord();
}
}
void CDTXTable::GoNext()
{
if(!intIsEOF())
{
intGoNext();
ReadCurrentRecord();
}
}
void CDTXTable::GoPrev()
{
if(!intIsBOF())
{
intGoPrev();
ReadCurrentRecord();
}
}
void CDTXTable::Go(UINT nRec)
{
intGo(nRec);
ReadCurrentRecord();
}
BOOL CDTXTable::IsEOF()
{
return intIsEOF();
}
BOOL CDTXTable::IsBOF()
{
return intIsBOF();
}
UINT CDTXTable::GetRecordCount()
{
return intGetRecordCount();
}
UINT CDTXTable::GetRecordPos()
{
return intGetRecordPos();
}
void CDTXTable::Refresh()
{
if(m_EnableControls)
for(int i = 0; i < m_EditorList.GetSize(); i++)
m_EditorList[i]->TableDataChange();
}
void CDTXTable::ReadCurrentRecord()
{
intGetCurrentRecord();
SendRecChangeMessage();
}
void CDTXTable::AddCalculatedField(CString nName, UINT nSize, DTXFieldType nType)
{
DTXField* nRet = new DTXField(nType);
nRet->m_Type = nType;
nRet->m_Kind = dtxfkCalculated;
nRet->m_FieldName = nName;
nRet->m_Start = 0;
nRet->m_Length = nSize;
nRet->m_OrigType = 0;
m_FieldArray.AddField(nRet);
if(TableOpened())
Refresh();
}
void CDTXTable::AddField(DTXField* nNewField)
{
m_FieldArray.AddField(nNewField);
}
void CDTXTable::RecChange()
{
if(m_AutoUpdate)
UpdateRecord();
if(m_Owner && m_Owner->GetSafeHwnd())
{
m_Owner->PostMessage(WM_CALCULATERECORD,
(WPARAM) GetRecordPos(), (LPARAM)this);
}
Refresh();
}
void CDTXTable::UpdateRecord()
{
intUpdateRecord();
m_IsModified = false;
}
void CDTXTable::InsertRecord()
{
intInsertRecord();
m_IsModified = true;
ReadCurrentRecord();
}
void CDTXTable::DeleteRecord()
{
UINT nRecPos = GetRecordPos();
intDeleteRecord();
if(nRecPos < GetRecordCount())
Go(nRecPos + 1);
else if(nRecPos > 1)
Go(nRecPos - 1);
ReadCurrentRecord();
Refresh();
}
void CDTXTable::SetModified(BOOL nModified)
{
m_IsModified = nModified;
if(m_IsModified)
{
RecChange();
}
}
void CDTXTable::AddEditor(CDTXEditBase* nEditor)
{
if(nEditor)
{
m_EditorList.Add(nEditor);
if(TableOpened())
nEditor->TableOpened();
}
}
void CDTXTable::DeleteEditor(CString nFieldName)
{
for(int i = 0; i < m_EditorList.GetSize(); i++)
if(m_EditorList[i]->GetFieldName() == nFieldName)
{
m_EditorList.RemoveAt(i);
break;
}
}
void CDTXTable::EnableControls(BOOL nRefreshEditors)
{
m_EnableControls = TRUE;
if(TableOpened() && nRefreshEditors)
Refresh();
}
void CDTXTable::DisableControls()
{
m_EnableControls = FALSE;
}
/////////////////////////////////////////////////////////////////////
//// CDTXEditBase
CDTXEditBase::CDTXEditBase(CWnd* pWnd)
{
#ifdef DTX_DEMO_
static BOOL nMessageBox = FALSE;
if(!nMessageBox)
{
AfxMessageBox(_T("DTX - Database Toolbox For MFC Ver 1.8\n") \
_T("Freeware version\n\nCopyright 2001 by C�neyt EL�BOL\n\n") \
_T("http://server33.hypermart.net/celibol\n\n") \
_T("celibol@alibaba.com or celibol@hotmail.com\n\n") \
_T("Thanks for using DTX"));
nMessageBox = TRUE;
}
#endif
m_Wnd = pWnd;
m_EditField = _T("");
m_OwnerTable = NULL;
}
CDTXEditBase::~CDTXEditBase()
{
if(m_OwnerTable)
m_OwnerTable->DeleteEditor(m_EditField);
}
CString CDTXEditBase::GetDisplayString()
{
if(m_OwnerTable)
return DTXFieldToString(GetField());
return _T("");
}
void CDTXEditBase::SetTable(CDTXTable* nTable)
{
m_OwnerTable = nTable;
if(m_OwnerTable)
m_OwnerTable->AddEditor(this);
}
void CDTXEditBase::SetEditField(CString nField)
{
m_EditField.Format(_T("%s"), nField);
}
DTXField* CDTXEditBase::GetField()
{
if(m_OwnerTable)
{
for(int i = 0; i < m_OwnerTable->m_FieldArray.GetSize(); i++)
{
if (m_OwnerTable->m_FieldArray[i]->m_FieldName == m_EditField)
return m_OwnerTable->m_FieldArray[i];
}
}
return NULL;
}
void CDTXEditBase::SetFieldValue(CString nValue)
{
if(m_OwnerTable)
{
for(int i = 0; i < m_OwnerTable->m_FieldArray.GetSize(); i++)
{
if (m_OwnerTable->m_FieldArray[i]->m_FieldName == m_EditField)
{
DTXField* nField = m_OwnerTable->m_FieldArray[i];
StringToDTXField(nValue, nField);
m_OwnerTable->m_FieldArray.SetAt(i, nField);
m_OwnerTable->SetModified(true);
break;
}
}
}
}
void CDTXEditBase::TableDataChange()
{
if(m_Wnd && m_Wnd->GetSafeHwnd() && !m_EditField.IsEmpty())
{
DTXField* nField = GetField();
if(nField && !nField->m_FieldName.IsEmpty())
{
CString m_FieldText = DTXFieldToString(nField);
CString m_WinText;
m_Wnd->GetWindowText(m_WinText);
if(m_WinText != m_FieldText)
{
m_Wnd->SetWindowText(m_FieldText);
m_Wnd->Invalidate();
}
if(nField->m_Kind == dtxfkCalculated)
m_Wnd->EnableWindow(false);
}
}
}
void CDTXEditBase::TableClosed()
{
if(m_Wnd && m_Wnd->GetSafeHwnd())
{
m_Wnd->SetWindowText(_T(""));
m_Wnd->EnableWindow(false);
}
}
void CDTXEditBase::TableOpened()
{
if(m_Wnd && m_Wnd->GetSafeHwnd())
{
m_Wnd->EnableWindow();
TableDataChange();
}
}