Click here to Skip to main content
15,880,796 members
Articles / Desktop Programming / MFC

DTX - Database Toolbox For MFC Ver 1.8 (Freeware Version)

Rate me:
Please Sign up or sign in to vote.
3.88/5 (8 votes)
2 Apr 20024 min read 106.4K   3.6K   56  
DTX is a set of classes for editing and automatic read, write and display of datatabase fields, as well as 70+ ready to use classes
// 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();
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Turkey Turkey
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions