Introduction
This is a further exploration if the INI file class theme started by Xiangxiong Jian (xiaohe521) and Adam (aejw) on The Code Project. The main idea remains pretty much the same: the class is a thin wrapper around Win32 <stockticker>API for reading/writing INI files. However, I was trying to gear my class more towards the <stockticker>MFC.
This class may be useful if your application needs to access both registry and INI file, or multiple INI files. Otherwise, you could use AfxGetApp()->m_pszProfileName
and AfxGetApp()->GetProfileXXXX(…)
.
Class Declaration
class CIniFile : public CObject
{
public:
CIniFile(LPCTSTR lpIniFileName, INT iMaxStringLength);
virtual ~CIniFile();
protected:
CString m_strFileName; const INT m_MAXSTRLEN;
public:
CString GetIniFileName();
void SetIniFileName(LPCTSTR lpIniFileName);
BOOL GetStatus(CFileStatus& rStatus);
void GetString(LPCTSTR lpSection, LPCTSTR lpKey,
CString& strRet, LPCTSTR strDefault);
UINT GetInt(LPCTSTR lpSection, LPCTSTR lpKey, INT iDefaultValue);
FLOAT GetFloat(LPCTSTR lpSection, LPCTSTR lpKey, FLOAT fDefaultValue);
BOOL GetStruct(LPCTSTR lpSection, LPCTSTR lpKey,
LPVOID lpRetStruct, UINT iSizeStruct);
void GetSectionNames(CStringList& lstSectionNames);
BOOL WriteSection(LPCTSTR lpSection, LPCTSTR lpData);
BOOL WriteString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpString);
BOOL WriteNumber(LPCTSTR lpSection, LPCTSTR lpKey, INT iValue);
BOOL WriteNumber(LPCTSTR lpSection, LPCTSTR lpKey, FLOAT fValue);
BOOL WriteStruct(LPCTSTR lpSection, LPCTSTR lpKey,
LPVOID lpStruct, UINT iSizeStruct);
BOOL RemoveKey(LPCTSTR lpSection, LPCTSTR lpKey);
};
Class Implementation
The implementation is very straightforward. It’s based on the following <stockticker>API functions:
GetPrivateProfileSectionNames
GetPrivateProfileStruct
GetPrivateProfileString
GetPrivateProfileInt
WritePrivateProfileStruct
WritePrivateProfileString
WritePrivateProfileSection
Download the source code for details (it's fairly well commented).
Demo Application / Test Bed
Here’s the console application that exercises the methods of the class. The output goes to the afxDump
.
struct TestStruct : public POINT
{
char charr[8];
};
void TestIniClass()
{
CIniFile iniFile(".\\test1.ini", 1024);
iniFile.SetIniFileName(".\\test2.ini");
iniFile.WriteSection("section1", "key1=test1\x000key2=test2"); iniFile.WriteSection("section2", "key1=test1"); iniFile.WriteString("section1", "key3", "test3"); iniFile.WriteString("section1", "key2", "test4"); iniFile.WriteString("section1", "key1", NULL); iniFile.RemoveKey("section1", "key3"); iniFile.WriteNumber("section1", "key4", 123); iniFile.WriteNumber("section1", "key5", -123); iniFile.WriteNumber("section1", "key6", -123.456f); TestStruct writeTestStruct;
writeTestStruct.x = 6;
writeTestStruct.y = 7;
strcpy(writeTestStruct.charr, "abcdefg");
iniFile.WriteStruct("section1", "key7", &writeTestStruct, sizeof(TestStruct));
CString str; iniFile.GetString("section1", "key2", str, "default"); TRACE("key2=%s\n", str);
iniFile.GetString("section1", "nokey", str, "default");
TRACE("nokey=%s\n", str); iniFile.GetString("section3", "key1", str, "default"); TRACE("nokey=%s\n", str);
TRACE("key4=%d\n", iniFile.GetInt("section1", "key4", 0));
TRACE("key5=%d\n", iniFile.GetInt("section1", "key5", 0));
TRACE("key6=%f\n", iniFile.GetFloat("section1", "key6", 0));
TestStruct readTestStruct;
iniFile.GetStruct("section1", "key7", &readTestStruct, sizeof(TestStruct));
TRACE("key7= %ld %ld %s\n", readTestStruct.x,
readTestStruct.y, readTestStruct.charr);
CStringList lstSectionNames;
iniFile.GetSectionNames(lstSectionNames);
TRACE("Sections:\n");
for (POSITION pos = lstSectionNames.GetHeadPosition(); pos != NULL; )
{
TRACE("\t%s\n", lstSectionNames.GetNext(pos));
}
}
Is there anything that should be fixed, added or removed in this project? Please let me know!
References
[1] A Small Class to Read INI File
[2] INI Class for .NET
[3] CIni
Revision History
Rev 0.1 | Initial draft | Nick Alexeev | Nov 24, 2006 |
Rev 0.2 | Added exception handling | Nick Alexeev | Nov 30, 2006 |