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 API for reading/writing INI files. However, I was trying to gear my class more towards the 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 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 |