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 value\r\nto 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



Comments

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: December 18, 2014 The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this webcast and join industry experts as …

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

Most Popular Programming Stories

More for Developers

RSS Feeds