An ini-like save system

Download demo 62K

This demo shows how to use a small class, CIni, to load and save documents using a ini-file
like system. The standard serialization way is nice and easy to use .. your nightmare starts
when you have to read files made with another application.
Sometimes, when the data to be saved are few and simple, it would be nicer to save them in a simple
text file. The old function to write/read from ini files are dangerous to use, since help says they
may be mapped in the registry. This class organize datas using Section, keywords and values and permits
to use bool, string, multiline string, double, float, long, int, CRect, CPoint and COLORREF.
A file made by the CIni class looks like that:

[Section name]
Test Point = POINT(100,200)
Test Rect = RECT(100,200,300,400)
Test Bool = true
Test Long = 1
Test Double = 0.000000
Test Text = the text value
Test MultiLine = first lineg|second lineg|third line

In multiline text, the r and n char are written as g and |.
You can have multiple section inside the same file and handle the CIni files either from the doc as
a new file save system or as a standalone class.

1. Inserting the CIni in the document class


If you want to use the CIni in the document class, you’ll have to include the Ini.h and Ini.cpp
files in your project. Then create an instance of CIni in the document header file, like:

class CCIniDemoDoc : public CDocument
{
public:
CIni ini;

Then get an handler for the document OnOpenDocument, OnSaveDocument and DeleteContent:


BOOL CCIniDemoDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
// This clear the cini class before loading the new document
ini.Clear();

// This read all the file into a stringarray in the cini class
if (ini.Read(lpszPathName))
{
// If you want to set default values, you can set them here
csMultiLine = “This to set a default valuernto a variable”;

// Now we are getting the values from the cini file to the document variables
ini.GetMultiValue(“Doc”, “Test MultiLine”, csMultiLine);
ini.GetValue(“Doc”, “Test Text”, csText);
ini.GetValue(“Doc”, “Test Double”, dbVal);
ini.GetValue(“Doc”, “Test Long”, lVal);
ini.GetValue(“Doc”, “Test Bool”, bVal);

return true;
}
return false;
}

BOOL CCIniDemoDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
SetModifiedFlag(FALSE);

// Here we set the values in the cini class from the document variables
// before saving it to disk
ini.SetMultiValue(“Doc”, “Test MultiLine”, csMultiLine);
ini.SetValue(“Doc”, “Test Text”, csText);
ini.SetValue(“Doc”, “Test Double”, dbVal);
ini.SetValue(“Doc”, “Test Long”, lVal);
ini.SetValue(“Doc”, “Test Bool”, bVal);

return ini.Write(lpszPathName);
}

void CCIniDemoDoc::DeleteContents()
{
ini.Clear();
}

2. Function reference


Here follows a brief description of the function you may use (the internal function are not explained here):

bool RemoveSection(const char * cSection);
This function remove a section and all the items of the section.

int FindSection(const char * cSection);
Use this function to find if a section named “cSection” exists in the cini class.
Returns -1 if the section doesn’t exist.


bool SetValue(const char * cSection, const char * cItem, const COLORREF crVal);
bool SetValue(const char * cSection, const char * cItem, const bool bVal);
bool SetValue(const char * cSection, const char * cItem, const char * cVal);
bool SetValue(const char * cSection, const char * cItem, const double dbVal);
bool SetValue(const char * cSection, const char * cItem, const float fVal);
bool SetValue(const char * cSection, const char * cItem, const long lVal);
bool SetValue(const char * cSection, const char * cItem, const int iVal);
bool SetValue(const char * cSection, const char * cItem, const CRect rcVal);
bool SetValue(const char * cSection, const char * cItem, const CPoint ptVal);

Those functions set the value for the item named “cItem” of the section “cSection” to the given value.
There are functions for all kinds of variables, from integer to COLORREF. It is easy to add new kind
of variables looking at the class source code.
If the item already exists, its value is setted, else
it’s added to the section.

bool SetMultiValue(const char * cSection, const char * cItem, const char * cVal);
This function works as above, but is needed for text variables which hold multiline text.
Don’t set text which contain newline and formfeed characters (r and n) with the SetValue function;
use this one instead.


bool GetValue(const char * cSection, const char * cItem, COLORREF &crVal);
bool GetValue(const char * cSection, const char * cItem, bool &bVal);
bool GetValue(const char * cSection, const char * cItem, CString &cVal);
bool GetValue(const char * cSection, const char * cItem, double &dbVal);
bool GetValue(const char * cSection, const char * cItem, float &fVal);
bool GetValue(const char * cSection, const char * cItem, long &lVal);
bool GetValue(const char * cSection, const char * cItem, int &iVal);
bool GetValue(const char * cSection, const char * cItem, CRect &rcVal);
bool GetValue(const char * cSection, const char * cItem, CPoint &ptVal);

Those functions get the value for the item named “cItem” of the section “cSection” in the given variable.
If the item doesn’t exists, the value is left untouched; so you can insert in the value the default value
before calling one of this functions.

bool GetMultiValue(const char * cSection, const char * cItem, CString &cVal);
This function works as above, but is needed for text variables which hold multiline text.
You can use this function to retrieve multiline text stored with the SetMultiValue function.

void Clear();
This function clears the cini class content.
bool Write(const char * cFileName);
Writes the content of the cini class to the “cFileName” file.

bool Read(const char * cFileName);
Read the content of the cini class from the “cFileName” file.

Last updated: 30 June 1998

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read