Serializable CListCtrl with check sum verify
Storing information in file.
First we will save a signature, as sample I chose this to be 'ListCtrl - ObjectStore', for a short check of file type. Then we will store a double word where at the end of the storing operation we will put the calculated check sum. After that, each column in stored, and finished with a -1 value to limit the definitions of columns in file.
Loading information from file.
Read signature. If this is what I stored, then I get the check sum from file, to verify with check sum of file. If all these are right,the loading continues as with the storing procedure.
The implementation contain a class CCheckArchive, and function Serialize. The CCheckArchive class has some virtual functions overridable ( like operator <<, used in Serialize functions) to complete the check sum.
For more detail, I invite the user to see the code. For store/load list control the user can call the function ::Serialize, with the folowing arguments. First is the destinatin list control, the second is the file name, and the last argument is the required operation; TRUE for storing, FALSE for loading. I think that the function Serialize and CCheckArchive, can be easly extended. Any kind of help, or information I will receive/send with pleasure.
Sincerely, Mihai Filimon
class CCheckArchive : public CArchive
{
DWORD m_wCheckSum;
protected:
// Function name : Sum
// Description : Add every byte from wData
// Return type : static DWORD
// Argument : DWORD wData
static DWORD Sum(DWORD wData)
{
return HIBYTE(HIWORD(wData)) + LOBYTE(HIWORD(wData)) +
HIBYTE(LOWORD(wData)) + LOBYTE(LOWORD(wData));
};
public:
// Function name : CCheckArchive
// Description : Contructor uses in Serialize() function
// Return type :
// Argument : CFile* pFile
// Argument : UINT nMode
CCheckArchive(CFile* pFile, UINT nMode) : CArchive( pFile, nMode, 4096, NULL )
{
m_wCheckSum = 0;
}
// Function name : ~CCheckArchive
// Description : Destructor
// Return type : virtual
virtual ~CCheckArchive() {};
// Function name : operator <<
// Description : This operator is call in Serialize function. Add
// every byte write in file, in m_wCheckSum
// Return type : virtual CArchive&
// Argument : DWORD wData
virtual CArchive& operator << (DWORD wData)
{
m_wCheckSum += Sum(wData);
return ((CArchive&)*this) << wData;
}
// Function name : operator <<
// Description : This operator is call in Serialize function. Add
// every byte write in file, in m_wCheckSum
// Return type : virtual CArchive&
// Argument : CString& sData
virtual CArchive& operator << (CString& sData)
{
LPTSTR lpszS = (LPTSTR)(LPCTSTR)sData;
while (*lpszS)
m_wCheckSum += BYTE(*lpszS++);
m_wCheckSum += Sum(sData.GetLength());
return ((CArchive&)*this) << sData;
}
// Function name : GetCheckSum
// Description : Return the calculated check sum
// Return type : DWORD
DWORD GetCheckSum()
{
return m_wCheckSum;
};
// Function name : GetLastPosition
// Description : Called for found the position of file in write
// operation
// Return type : DWORD
DWORD GetLastPosition()
{
return m_lpBufCur - m_lpBufStart;
};
// Function name : Verify
// Description : Check if chkSum verify the file, that must be in
// loading
// Return type : BOOL
// Argument : DWORD chkSum
BOOL Verify(DWORD chkSum)
{
static const max = 2048;
DWORD w = 0;
ASSERT (IsLoading());
TRY
{
CFile* pFile = GetFile();
DWORD bookmark = pFile->GetPosition();
pFile->SeekToBegin();
BYTE buffer[max], *pBuffer = NULL;
int nRead = 0;
while (nRead = pFile->Read(&buffer, max))
{
pBuffer = buffer;
for (int i = 0; i < nRead; i++, w += *pBuffer++);
}
w -= Sum(chkSum);
pFile->Seek(bookmark, CFile::begin);
}
CATCH_ALL(e)
{
return FALSE;
}
END_CATCH_ALL;
return w == chkSum;
}
};
// Function name : Serialize
// Description : Call this function to store/load a list control
// Return type : BOOL
// Argument : CListCtrl* pListCtrl
// Argument : LPCTSTR lpszFileName
// Argument : BOOL bStoring = TRUE
BOOL Serialize(CListCtrl* pListCtrl, LPCTSTR lpszFileName, BOOL bStoring = TRUE)
{
static const TCHAR* lpszSignature = _T("ListCtrl - StoreObject");
CFile file;
if (file.Open(lpszFileName, bStoring ? CFile::modeWrite | CFile::modeCreate: CFile::modeRead))
TRY
{
CString s; CCheckArchive ar(&file, bStoring ? CArchive::store :CArchive::load);
DWORD chkSum = 0;
if (bStoring)
{
ar << CString(lpszSignature);
DWORD sC = ar.GetLastPosition();
ar << chkSum;
LV_COLUMN column; TCHAR buffer[MAX_PATH]; int i = NULL, nColumn = 0;
column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
column.pszText = buffer;
column.cchTextMax = MAX_PATH;
for (i = 0; pListCtrl->GetColumn(i, &column); i++, nColumn++)
{
ar << column.fmt;
ar << column.cx;
ar << CString(column.pszText);
}
ar << UINT(-1);
int n = pListCtrl->GetItemCount();
ar << n;
for (i = 0; i < n; i++)
{
for (int j = 0; j < nColumn; j++)
ar << pListCtrl->GetItemText(i, j);
ar << pListCtrl->GetItemData(i);
}
ar.Flush();
ar.GetFile()->Seek(sC,CFile::begin);
chkSum = ar.GetCheckSum();
ar.GetFile()->Write(&chkSum, sizeof(chkSum));
}
else
{
ar >> s;
if (s.Compare(lpszSignature) == 0)
{
ar >> chkSum;
if (ar.Verify(chkSum))
{
CString text;
text.Format(_T("%i"),chkSum);
AfxMessageBox(text);
LV_COLUMN column; TCHAR buffer[MAX_PATH]; int i = NULL, nColumn = 0;
column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
column.pszText = buffer;
column.cchTextMax = MAX_PATH;
for (; TRUE; nColumn++)
{
ar >> column.fmt;
if (column.fmt < 0) break;
ar >> column.cx;
ar >> s;
column.pszText = (LPTSTR)(LPCTSTR)s;
pListCtrl->InsertColumn(nColumn, &column);
}
int n = NULL;
ar >> n;
for (i = 0; i < n; i++)
{
int nItem = pListCtrl->InsertItem(i, _T(""));
for (int j = 0; j < nColumn; j++)
{
ar >> s;
pListCtrl->SetItemText(nItem, j, s);
}
DWORD wData;
ar >> wData;
pListCtrl->SetItemData(nItem, wData);
}
}
}
}
ar.Close();
file.Close();
}
CATCH_ALL(e)
{
return FALSE;
}
END_CATCH_ALL
return TRUE;
}
Last updated: 29 July 1998 by Rob Osborne

Comments
Try CExtReport
Posted by Legacy on 08/18/2003 12:00amOriginally posted by: marcus gesing
Source and demo:
Replyhttp://home.arcor.de/footwear-box/various/coding/ExtLib.zip
I need help using the mfc serialize funktion width your code
Posted by Legacy on 05/12/2000 12:00amOriginally posted by: Andreas H
I have to tell you this cameas a dream. I m at the moment
involved in my first project involving serializing data to and from files.
However as you might have guest im not that good in programming vc++.
Ive only been doing this for 5 months and im learning not only by books
but also from taking codes from codeguru.com for use in my applications.
Unfortunatly i dont quite understand your code posted there.
Because instead of using a new class i want to used the MFC serialize function.
I tried to modify it without any bigger succes, since i didnt really know
where to put the checksum finctions and so on. So i was kind of hoping for
that you could help me out. I would really appreciate the help.
In my project I have a listview cointaing data in 2 cols and a unspecified
number of rows. I also have 2 edit boxes containing 3 strings of text.
I need al this serialized into the file.
The name of the variables:
CListCtrl = m_lstSourceFiles
Editbox1 = m_strFolder
Editbox2 = m_strContent
Editbox3 = m_strName
Please help me modify the code for my needs and be detailed in your
explanations so that i can learn it.
Thank you
Reply