1 |
///////////////////////////////////////////////////////////////////////////////// |
1 |
///////////////////////////////////////////////////////////////////////////////// |
2 |
// Cini Class Implementation |
2 |
// Cini Class Implementation |
3 |
///////////////////////////////////////////////////////////////////////////////// |
3 |
///////////////////////////////////////////////////////////////////////////////// |
4 |
#include "stdafx.h" // include if you got "fatal error C1010: unexpected end of file..." |
4 |
#include "stdafx.h" // include if you got "fatal error C1010: unexpected end of file..." |
5 |
#include "Ini.h" |
5 |
#include "Ini.h" |
6 |
#include <string.h> |
6 |
#include <string.h> |
7 |
#include <stdio.h> |
7 |
#include <stdio.h> |
8 |
#include <assert.h> |
8 |
#include <assert.h> |
9 |
|
9 |
|
10 |
#define DEF_PROFILE_NUM_LEN 64 // numeric string length, could be quite long for binary format |
10 |
#define DEF_PROFILE_NUM_LEN 64 // numeric string length, could be quite long for binary format |
11 |
#define DEF_PROFILE_THRESHOLD 512 // temporary string length |
11 |
#define DEF_PROFILE_THRESHOLD 512 // temporary string length |
12 |
#define DEF_PROFILE_DELIMITER _T(",") // default string delimiter |
12 |
#define DEF_PROFILE_DELIMITER _T(",") // default string delimiter |
13 |
#define DEF_PROFILE_TESTSTRING _T("{63788286-AE30-4D6B-95DF-3B451C1C79F9}") // Uuid for internal use |
13 |
#define DEF_PROFILE_TESTSTRING _T("{63788286-AE30-4D6B-95DF-3B451C1C79F9}") // Uuid for internal use |
14 |
|
14 |
|
15 |
// struct used to be passed to __KeyPairProc as a LPVOID parameter |
15 |
// struct used to be passed to __KeyPairProc as a LPVOID parameter |
16 |
struct STR_LIMIT |
16 |
struct STR_LIMIT |
17 |
{ |
17 |
{ |
18 |
LPTSTR lpTarget; |
18 |
LPTSTR lpTarget; |
19 |
DWORD dwRemain; |
19 |
DWORD dwRemain; |
20 |
DWORD dwTotalCopied; |
20 |
DWORD dwTotalCopied; |
21 |
}; |
21 |
}; |
22 |
|
22 |
|
23 |
///////////////////////////////////////////////////////////////////////////////// |
23 |
///////////////////////////////////////////////////////////////////////////////// |
24 |
// Constructors & Destructor |
24 |
// Constructors & Destructor |
25 |
///////////////////////////////////////////////////////////////////////////////// |
25 |
///////////////////////////////////////////////////////////////////////////////// |
26 |
CIni::CIni() |
26 |
CIni::CIni() |
27 |
{ |
27 |
{ |
28 |
m_pszPathName = NULL; |
28 |
m_pszPathName = NULL; |
29 |
} |
29 |
} |
30 |
|
30 |
|
31 |
CIni::CIni(LPCTSTR lpPathName) |
31 |
CIni::CIni(LPCTSTR lpPathName) |
32 |
{ |
32 |
{ |
33 |
m_pszPathName = NULL; |
33 |
m_pszPathName = NULL; |
34 |
SetPathName(lpPathName); |
34 |
SetPathName(lpPathName); |
35 |
} |
35 |
} |
36 |
|
36 |
|
37 |
CIni::~CIni() |
37 |
CIni::~CIni() |
38 |
{ |
38 |
{ |
39 |
if (m_pszPathName != NULL) |
39 |
if (m_pszPathName != NULL) |
40 |
delete [] m_pszPathName; |
40 |
delete [] m_pszPathName; |
41 |
} |
41 |
} |
42 |
|
42 |
|
43 |
///////////////////////////////////////////////////////////////////////////////// |
43 |
///////////////////////////////////////////////////////////////////////////////// |
44 |
// Ini File Path Access |
44 |
// Ini File Path Access |
45 |
///////////////////////////////////////////////////////////////////////////////// |
45 |
///////////////////////////////////////////////////////////////////////////////// |
46 |
|
46 |
|
47 |
// Assign ini file path name |
47 |
// Assign ini file path name |
48 |
void CIni::SetPathName(LPCTSTR lpPathName) |
48 |
void CIni::SetPathName(LPCTSTR lpPathName) |
49 |
{ |
49 |
{ |
50 |
if (lpPathName == NULL) |
50 |
if (lpPathName == NULL) |
51 |
{ |
51 |
{ |
52 |
if (m_pszPathName != NULL) |
52 |
if (m_pszPathName != NULL) |
53 |
*m_pszPathName = _T('\0'); |
53 |
*m_pszPathName = _T('\0'); |
54 |
} |
54 |
} |
55 |
else |
55 |
else |
56 |
{ |
56 |
{ |
57 |
if (m_pszPathName != NULL) |
57 |
if (m_pszPathName != NULL) |
58 |
delete [] m_pszPathName; |
58 |
delete [] m_pszPathName; |
59 |
|
59 |
|
60 |
m_pszPathName = _tcsdup(lpPathName); |
60 |
m_pszPathName = _tcsdup(lpPathName); |
61 |
} |
61 |
} |
62 |
} |
62 |
} |
63 |
|
63 |
|
64 |
// Retrieve ini file path name |
64 |
// Retrieve ini file path name |
65 |
DWORD CIni::GetPathName(LPTSTR lpBuffer, DWORD dwBufSize) const |
65 |
DWORD CIni::GetPathName(LPTSTR lpBuffer, DWORD dwBufSize) const |
66 |
{ |
66 |
{ |
67 |
*lpBuffer = _T('\0'); |
67 |
*lpBuffer = _T('\0'); |
68 |
DWORD dwLen = 0; |
68 |
DWORD dwLen = 0; |
69 |
if (lpBuffer != NULL) |
69 |
if (lpBuffer != NULL) |
70 |
{ |
70 |
{ |
71 |
_tcsncpy(lpBuffer, m_pszPathName, dwBufSize); |
71 |
_tcsncpy(lpBuffer, m_pszPathName, dwBufSize); |
72 |
dwLen = _tcslen(lpBuffer); |
72 |
dwLen = _tcslen(lpBuffer); |
73 |
} |
73 |
} |
74 |
else |
74 |
else |
75 |
{ |
75 |
{ |
76 |
// just calculate the required buffer size |
76 |
// just calculate the required buffer size |
77 |
dwLen = _tcslen(m_pszPathName); |
77 |
dwLen = _tcslen(m_pszPathName); |
78 |
} |
78 |
} |
79 |
return dwLen; |
79 |
return dwLen; |
80 |
} |
80 |
} |
81 |
|
81 |
|
82 |
#ifdef __AFXWIN_H__ |
82 |
#ifdef __AFXWIN_H__ |
83 |
CString CIni::GetPathName() const |
83 |
CString CIni::GetPathName() const |
84 |
{ |
84 |
{ |
85 |
return CString(m_pszPathName); |
85 |
return CString(m_pszPathName); |
86 |
} |
86 |
} |
87 |
#endif |
87 |
#endif |
88 |
|
88 |
|
89 |
///////////////////////////////////////////////////////////////////////////////// |
89 |
///////////////////////////////////////////////////////////////////////////////// |
90 |
// Raw String Access |
90 |
// Raw String Access |
91 |
///////////////////////////////////////////////////////////////////////////////// |
91 |
///////////////////////////////////////////////////////////////////////////////// |
92 |
|
92 |
|
93 |
// Get a profile string value, if the buffer size is not large enough, the result |
93 |
// Get a profile string value, if the buffer size is not large enough, the result |
94 |
// may be truncated. |
94 |
// may be truncated. |
95 |
DWORD CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDefault) const |
95 |
DWORD CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDefault) const |
96 |
{ |
96 |
{ |
97 |
if (lpBuffer != NULL) |
97 |
if (lpBuffer != NULL) |
98 |
*lpBuffer = _T('\0'); |
98 |
*lpBuffer = _T('\0'); |
99 |
|
99 |
|
100 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault); |
100 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault); |
101 |
DWORD dwLen = _tcslen(psz); |
101 |
DWORD dwLen = _tcslen(psz); |
102 |
|
102 |
|
103 |
if (lpBuffer != NULL) |
103 |
if (lpBuffer != NULL) |
104 |
{ |
104 |
{ |
105 |
_tcsncpy(lpBuffer, psz, dwBufSize); |
105 |
_tcsncpy(lpBuffer, psz, dwBufSize); |
106 |
dwLen = min(dwLen, dwBufSize); |
106 |
dwLen = min(dwLen, dwBufSize); |
107 |
} |
107 |
} |
108 |
|
108 |
|
109 |
delete [] psz; |
109 |
delete [] psz; |
110 |
return dwLen; |
110 |
return dwLen; |
111 |
} |
111 |
} |
112 |
|
112 |
|
113 |
#ifdef __AFXWIN_H__ |
113 |
#ifdef __AFXWIN_H__ |
114 |
CString CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const |
114 |
CString CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const |
115 |
{ |
115 |
{ |
116 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault); |
116 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault); |
117 |
CString str(psz); |
117 |
CString str(psz); |
118 |
delete [] psz; |
118 |
delete [] psz; |
119 |
return str; |
119 |
return str; |
120 |
} |
120 |
} |
121 |
#endif |
121 |
#endif |
122 |
|
122 |
|
123 |
// Write a string value to the ini file |
123 |
// Write a string value to the ini file |
124 |
BOOL CIni::WriteString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue) const |
124 |
BOOL CIni::WriteString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue) const |
125 |
{ |
125 |
{ |
126 |
if (lpSection == NULL || lpKey == NULL) |
126 |
if (lpSection == NULL || lpKey == NULL) |
127 |
return FALSE; |
127 |
return FALSE; |
128 |
|
128 |
|
129 |
return ::WritePrivateProfileString(lpSection, lpKey, lpValue == NULL ? _T("") : lpValue, m_pszPathName); |
129 |
return ::WritePrivateProfileString(lpSection, lpKey, lpValue == NULL ? _T("") : lpValue, m_pszPathName); |
130 |
} |
130 |
} |
131 |
|
131 |
|
132 |
// Read a string value from the ini file, append another string after it and then write it |
132 |
// Read a string value from the ini file, append another string after it and then write it |
133 |
// back to the ini file |
133 |
// back to the ini file |
134 |
BOOL CIni::AppendString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpString) const |
134 |
BOOL CIni::AppendString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpString) const |
135 |
{ |
135 |
{ |
136 |
if (lpString == NULL) |
136 |
if (lpString == NULL) |
137 |
return FALSE; |
137 |
return FALSE; |
138 |
|
138 |
|
139 |
TCHAR* psz = __GetStringDynamic(lpSection, lpKey); |
139 |
TCHAR* psz = __GetStringDynamic(lpSection, lpKey); |
140 |
TCHAR* pNewString = new TCHAR[_tcslen(psz) + _tcslen(lpString) + 1]; |
140 |
TCHAR* pNewString = new TCHAR[_tcslen(psz) + _tcslen(lpString) + 1]; |
141 |
_stprintf(pNewString, _T("%s%s"), psz, lpString); |
141 |
_stprintf(pNewString, _T("%s%s"), psz, lpString); |
142 |
const BOOL RES = WriteString(lpSection, lpKey, pNewString); |
142 |
const BOOL RES = WriteString(lpSection, lpKey, pNewString); |
143 |
delete [] pNewString; |
143 |
delete [] pNewString; |
144 |
delete [] psz; |
144 |
delete [] psz; |
145 |
return RES; |
145 |
return RES; |
146 |
} |
146 |
} |
147 |
|
147 |
|
148 |
///////////////////////////////////////////////////////////////////////////////// |
148 |
///////////////////////////////////////////////////////////////////////////////// |
149 |
// Ini File String Array Access |
149 |
// Ini File String Array Access |
150 |
///////////////////////////////////////////////////////////////////////////////// |
150 |
///////////////////////////////////////////////////////////////////////////////// |
151 |
|
151 |
|
152 |
// Get an array of string |
152 |
// Get an array of string |
153 |
DWORD CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) const |
153 |
DWORD CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) const |
154 |
{ |
154 |
{ |
155 |
if (lpBuffer != NULL) |
155 |
if (lpBuffer != NULL) |
156 |
*lpBuffer = _T('\0'); |
156 |
*lpBuffer = _T('\0'); |
157 |
|
157 |
|
158 |
if (lpSection == NULL || lpKey == NULL) |
158 |
if (lpSection == NULL || lpKey == NULL) |
159 |
return 0; |
159 |
return 0; |
160 |
|
160 |
|
161 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey); |
161 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey); |
162 |
|
162 |
|
163 |
DWORD dwCopied = 0; |
163 |
DWORD dwCopied = 0; |
164 |
|
164 |
|
165 |
if (*psz != _T('\0')) |
165 |
if (*psz != _T('\0')) |
166 |
{ |
166 |
{ |
167 |
if (lpBuffer == NULL) |
167 |
if (lpBuffer == NULL) |
168 |
{ |
168 |
{ |
169 |
// just calculate the required buffer size |
169 |
// just calculate the required buffer size |
170 |
const DWORD MAX_LEN = _tcslen(psz) + 2; |
170 |
const DWORD MAX_LEN = _tcslen(psz) + 2; |
171 |
LPTSTR p = new TCHAR[MAX_LEN + 1]; |
171 |
LPTSTR p = new TCHAR[MAX_LEN + 1]; |
172 |
dwCopied = __StringSplit(psz, p, MAX_LEN, lpDelimiter, bTrimString); |
172 |
dwCopied = __StringSplit(psz, p, MAX_LEN, lpDelimiter, bTrimString); |
173 |
delete [] p; |
173 |
delete [] p; |
174 |
} |
174 |
} |
175 |
else |
175 |
else |
176 |
{ |
176 |
{ |
177 |
dwCopied = __StringSplit(psz, lpBuffer, dwBufSize, lpDelimiter, bTrimString); |
177 |
dwCopied = __StringSplit(psz, lpBuffer, dwBufSize, lpDelimiter, bTrimString); |
178 |
} |
178 |
} |
179 |
} |
179 |
} |
180 |
|
180 |
|
181 |
delete [] psz; |
181 |
delete [] psz; |
182 |
return dwCopied; |
182 |
return dwCopied; |
183 |
} |
183 |
} |
184 |
|
184 |
|
185 |
#ifdef __AFXWIN_H__ |
185 |
#ifdef __AFXWIN_H__ |
186 |
void CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, CStringArray *pArray, LPCTSTR lpDelimiter, BOOL bTrimString) const |
186 |
void CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, CStringArray *pArray, LPCTSTR lpDelimiter, BOOL bTrimString) const |
187 |
{ |
187 |
{ |
188 |
if (pArray != NULL) |
188 |
if (pArray != NULL) |
189 |
pArray->RemoveAll(); |
189 |
pArray->RemoveAll(); |
190 |
|
190 |
|
191 |
const DWORD LEN = GetArray(lpSection, lpKey, NULL, 0, lpDelimiter); |
191 |
const DWORD LEN = GetArray(lpSection, lpKey, NULL, 0, lpDelimiter); |
192 |
if (LEN == 0) |
192 |
if (LEN == 0) |
193 |
return; |
193 |
return; |
194 |
|
194 |
|
195 |
LPTSTR psz = new TCHAR[LEN + 3]; |
195 |
LPTSTR psz = new TCHAR[LEN + 3]; |
196 |
GetArray(lpSection, lpKey, psz, LEN + 2, lpDelimiter); |
196 |
GetArray(lpSection, lpKey, psz, LEN + 2, lpDelimiter); |
197 |
ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray); |
197 |
ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray); |
198 |
delete [] psz; |
198 |
delete [] psz; |
199 |
} |
199 |
} |
200 |
#endif |
200 |
#endif |
201 |
|
201 |
|
202 |
#ifdef __AFXWIN_H__ |
202 |
#ifdef __AFXWIN_H__ |
203 |
BOOL CIni::WriteArray(LPCTSTR lpSection, LPCTSTR lpKey, const CStringArray *pArray, int nWriteCount, LPCTSTR lpDelimiter) const |
203 |
BOOL CIni::WriteArray(LPCTSTR lpSection, LPCTSTR lpKey, const CStringArray *pArray, int nWriteCount, LPCTSTR lpDelimiter) const |
204 |
{ |
204 |
{ |
205 |
if (pArray == NULL) |
205 |
if (pArray == NULL) |
206 |
return FALSE; |
206 |
return FALSE; |
207 |
|
207 |
|
208 |
if (nWriteCount < 0) |
208 |
if (nWriteCount < 0) |
209 |
nWriteCount = pArray->GetSize(); |
209 |
nWriteCount = pArray->GetSize(); |
210 |
else |
210 |
else |
211 |
nWriteCount = min(nWriteCount, pArray->GetSize()); |
211 |
nWriteCount = min(nWriteCount, pArray->GetSize()); |
212 |
|
212 |
|
213 |
const CString DELIMITER = (lpDelimiter == NULL || *lpDelimiter == _T('\0')) ? _T(",") : lpDelimiter; |
213 |
const CString DELIMITER = (lpDelimiter == NULL || *lpDelimiter == _T('\0')) ? _T(",") : lpDelimiter; |
214 |
CString sLine; |
214 |
CString sLine; |
215 |
for (int i = 0; i < nWriteCount; i++) |
215 |
for (int i = 0; i < nWriteCount; i++) |
216 |
{ |
216 |
{ |
217 |
sLine += pArray->GetAt(i); |
217 |
sLine += pArray->GetAt(i); |
218 |
if (i != nWriteCount - 1) |
218 |
if (i != nWriteCount - 1) |
219 |
sLine += DELIMITER; |
219 |
sLine += DELIMITER; |
220 |
} |
220 |
} |
221 |
return WriteString(lpSection, lpKey, sLine); |
221 |
return WriteString(lpSection, lpKey, sLine); |
222 |
} |
222 |
} |
223 |
#endif |
223 |
#endif |
224 |
|
224 |
|
225 |
///////////////////////////////////////////////////////////////////////////////// |
225 |
///////////////////////////////////////////////////////////////////////////////// |
226 |
// Primitive Data Type Access |
226 |
// Primitive Data Type Access |
227 |
///////////////////////////////////////////////////////////////////////////////// |
227 |
///////////////////////////////////////////////////////////////////////////////// |
228 |
|
228 |
|
229 |
// Get a signed integral value |
229 |
// Get a signed integral value |
230 |
int CIni::GetInt(LPCTSTR lpSection, LPCTSTR lpKey, int nDefault, int nBase) const |
230 |
int CIni::GetInt(LPCTSTR lpSection, LPCTSTR lpKey, int nDefault, int nBase) const |
231 |
{ |
231 |
{ |
232 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
232 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
233 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
233 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
234 |
return *sz == _T('\0') ? nDefault : int(_tcstoul(sz, NULL, __ValidateBase(nBase))); |
234 |
return *sz == _T('\0') ? nDefault : int(_tcstoul(sz, NULL, __ValidateBase(nBase))); |
235 |
} |
235 |
} |
236 |
|
236 |
|
237 |
// Get an unsigned integral value |
237 |
// Get an unsigned integral value |
238 |
UINT CIni::GetUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nDefault, int nBase) const |
238 |
UINT CIni::GetUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nDefault, int nBase) const |
239 |
{ |
239 |
{ |
240 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
240 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
241 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
241 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
242 |
return *sz == _T('\0') ? nDefault : UINT(_tcstoul(sz, NULL, __ValidateBase(nBase))); |
242 |
return *sz == _T('\0') ? nDefault : UINT(_tcstoul(sz, NULL, __ValidateBase(nBase))); |
243 |
} |
243 |
} |
244 |
|
244 |
|
245 |
// Get a boolean value |
245 |
// Get a boolean value |
246 |
BOOL CIni::GetBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bDefault) const |
246 |
BOOL CIni::GetBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bDefault) const |
247 |
{ |
247 |
{ |
248 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
248 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
249 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
249 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
250 |
return StringToBool(sz, bDefault); |
250 |
return StringToBool(sz, bDefault); |
251 |
} |
251 |
} |
252 |
|
252 |
|
253 |
// Get a double floating value |
253 |
// Get a double floating value |
254 |
double CIni::GetDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fDefault) const |
254 |
double CIni::GetDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fDefault) const |
255 |
{ |
255 |
{ |
256 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
256 |
TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
257 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
257 |
GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); |
258 |
return *sz == _T('\0') ? fDefault : _tcstod(sz, NULL); |
258 |
return *sz == _T('\0') ? fDefault : _tcstod(sz, NULL); |
259 |
} |
259 |
} |
260 |
|
260 |
|
261 |
// Write a signed integral value to the ini file |
261 |
// Write a signed integral value to the ini file |
262 |
BOOL CIni::WriteInt(LPCTSTR lpSection, LPCTSTR lpKey, int nValue, int nBase) const |
262 |
BOOL CIni::WriteInt(LPCTSTR lpSection, LPCTSTR lpKey, int nValue, int nBase) const |
263 |
{ |
263 |
{ |
264 |
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
264 |
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
265 |
__IntToString(nValue, szValue, nBase); |
265 |
__IntToString(nValue, szValue, nBase); |
266 |
return WriteString(lpSection, lpKey, szValue); |
266 |
return WriteString(lpSection, lpKey, szValue); |
267 |
} |
267 |
} |
268 |
|
268 |
|
269 |
// Write an unsigned value to the ini file |
269 |
// Write an unsigned value to the ini file |
270 |
BOOL CIni::WriteUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nValue, int nBase) const |
270 |
BOOL CIni::WriteUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nValue, int nBase) const |
271 |
{ |
271 |
{ |
272 |
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
272 |
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
273 |
__UIntToString(nValue, szValue, nBase); |
273 |
__UIntToString(nValue, szValue, nBase); |
274 |
return WriteString(lpSection, lpKey, szValue); |
274 |
return WriteString(lpSection, lpKey, szValue); |
275 |
} |
275 |
} |
276 |
|
276 |
|
277 |
// Write a double floating value to the ini file |
277 |
// Write a double floating value to the ini file |
278 |
BOOL CIni::WriteDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fValue, int nPrecision) const |
278 |
BOOL CIni::WriteDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fValue, int nPrecision) const |
279 |
{ |
279 |
{ |
280 |
TCHAR szFmt[16] = _T("%f"); |
280 |
TCHAR szFmt[16] = _T("%f"); |
281 |
|
281 |
|
282 |
if (nPrecision > 0) |
282 |
if (nPrecision > 0) |
283 |
_stprintf(szFmt, _T("%%.%df"), nPrecision); |
283 |
_stprintf(szFmt, _T("%%.%df"), nPrecision); |
284 |
|
284 |
|
285 |
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
285 |
TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); |
286 |
_stprintf(szValue, szFmt, fValue); |
286 |
_stprintf(szValue, szFmt, fValue); |
287 |
return WriteString(lpSection, lpKey, szValue); |
287 |
return WriteString(lpSection, lpKey, szValue); |
288 |
} |
288 |
} |
289 |
|
289 |
|
290 |
// Read a double value from the ini file, increase it then write it back |
290 |
// Read a double value from the ini file, increase it then write it back |
291 |
BOOL CIni::IncreaseDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fIncrease, int nPrecision) const |
291 |
BOOL CIni::IncreaseDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fIncrease, int nPrecision) const |
292 |
{ |
292 |
{ |
293 |
double f = GetDouble(lpSection, lpKey, 0.0); |
293 |
double f = GetDouble(lpSection, lpKey, 0.0); |
294 |
f += fIncrease; |
294 |
f += fIncrease; |
295 |
return WriteDouble(lpSection, lpKey, f, nPrecision); |
295 |
return WriteDouble(lpSection, lpKey, f, nPrecision); |
296 |
} |
296 |
} |
297 |
|
297 |
|
298 |
// Write a boolean value to the ini file |
298 |
// Write a boolean value to the ini file |
299 |
BOOL CIni::WriteBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bValue) const |
299 |
BOOL CIni::WriteBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bValue) const |
300 |
{ |
300 |
{ |
301 |
return WriteInt(lpSection, lpKey, bValue ? 1 : 0, BASE_DECIMAL); |
301 |
return WriteInt(lpSection, lpKey, bValue ? 1 : 0, BASE_DECIMAL); |
302 |
} |
302 |
} |
303 |
|
303 |
|
304 |
// Read a boolean value from the ini file, invert it(true becomes false, false becomes true), |
304 |
// Read a boolean value from the ini file, invert it(true becomes false, false becomes true), |
305 |
// then write it back |
305 |
// then write it back |
306 |
BOOL CIni::InvertBool(LPCTSTR lpSection, LPCTSTR lpKey) const |
306 |
BOOL CIni::InvertBool(LPCTSTR lpSection, LPCTSTR lpKey) const |
307 |
{ |
307 |
{ |
308 |
return WriteBool(lpSection, lpKey, !GetBool(lpSection, lpKey, FALSE)); |
308 |
return WriteBool(lpSection, lpKey, !GetBool(lpSection, lpKey, FALSE)); |
309 |
} |
309 |
} |
310 |
|
310 |
|
311 |
// Read a int from the ini file, increase it and then write it back to the ini file |
311 |
// Read a int from the ini file, increase it and then write it back to the ini file |
312 |
BOOL CIni::IncreaseInt(LPCTSTR lpSection, LPCTSTR lpKey, int nIncrease, int nBase) const |
312 |
BOOL CIni::IncreaseInt(LPCTSTR lpSection, LPCTSTR lpKey, int nIncrease, int nBase) const |
313 |
{ |
313 |
{ |
314 |
int nVal = GetInt(lpSection, lpKey, 0, nBase); |
314 |
int nVal = GetInt(lpSection, lpKey, 0, nBase); |
315 |
nVal += nIncrease; |
315 |
nVal += nIncrease; |
316 |
return WriteInt(lpSection, lpKey, nVal, nBase); |
316 |
return WriteInt(lpSection, lpKey, nVal, nBase); |
317 |
} |
317 |
} |
318 |
|
318 |
|
319 |
// Read an UINT from the ini file, increase it and then write it back to the ini file |
319 |
// Read an UINT from the ini file, increase it and then write it back to the ini file |
320 |
BOOL CIni::IncreaseUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nIncrease, int nBase) const |
320 |
BOOL CIni::IncreaseUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nIncrease, int nBase) const |
321 |
{ |
321 |
{ |
322 |
UINT nVal = GetUInt(lpSection, lpKey, 0, nBase); |
322 |
UINT nVal = GetUInt(lpSection, lpKey, 0, nBase); |
323 |
nVal += nIncrease; |
323 |
nVal += nIncrease; |
324 |
return WriteUInt(lpSection, lpKey, nVal, nBase); |
324 |
return WriteUInt(lpSection, lpKey, nVal, nBase); |
325 |
} |
325 |
} |
326 |
|
326 |
|
327 |
TCHAR CIni::GetChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR cDefault) const |
327 |
TCHAR CIni::GetChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR cDefault) const |
328 |
{ |
328 |
{ |
329 |
TCHAR sz[2] = _T(""); |
329 |
TCHAR sz[2] = _T(""); |
330 |
GetString(lpSection, lpKey, sz, 1); |
330 |
GetString(lpSection, lpKey, sz, 1); |
331 |
return *sz == _T('\0') ? cDefault : sz[0]; |
331 |
return *sz == _T('\0') ? cDefault : sz[0]; |
332 |
} |
332 |
} |
333 |
|
333 |
|
334 |
BOOL CIni::WriteChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR c) const |
334 |
BOOL CIni::WriteChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR c) const |
335 |
{ |
335 |
{ |
336 |
TCHAR sz[2] = { c, _T('\0') }; |
336 |
TCHAR sz[2] = { c, _T('\0') }; |
337 |
return WriteString(lpSection, lpKey, sz); |
337 |
return WriteString(lpSection, lpKey, sz); |
338 |
} |
338 |
} |
339 |
|
339 |
|
340 |
///////////////////////////////////////////////////////////////////////////////// |
340 |
///////////////////////////////////////////////////////////////////////////////// |
341 |
// User-Defined Data Type Access |
341 |
// User-Defined Data Type Access |
342 |
///////////////////////////////////////////////////////////////////////////////// |
342 |
///////////////////////////////////////////////////////////////////////////////// |
343 |
|
343 |
|
344 |
// Get a block of raw data from the ini file |
344 |
// Get a block of raw data from the ini file |
345 |
DWORD CIni::GetDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPVOID lpBuffer, DWORD dwBufSize, DWORD dwOffset) const |
345 |
DWORD CIni::GetDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPVOID lpBuffer, DWORD dwBufSize, DWORD dwOffset) const |
346 |
{ |
346 |
{ |
347 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey); |
347 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey); |
348 |
DWORD dwLen = _tcslen(psz) / 2; |
348 |
DWORD dwLen = _tcslen(psz) / 2; |
349 |
if (dwLen <= dwOffset) |
349 |
if (dwLen <= dwOffset) |
350 |
{ |
350 |
{ |
351 |
delete [] psz; |
351 |
delete [] psz; |
352 |
return 0; |
352 |
return 0; |
353 |
} |
353 |
} |
354 |
|
354 |
|
355 |
// verify psz, must be all in hex format |
355 |
// verify psz, must be all in hex format |
356 |
for (int i = 0; psz[i] != _T('\0'); i++) |
356 |
for (int i = 0; psz[i] != _T('\0'); i++) |
357 |
{ |
357 |
{ |
358 |
TCHAR c = psz[i]; |
358 |
TCHAR c = psz[i]; |
359 |
if ((c >= _T('0') && c <= _T('9')) |
359 |
if ((c >= _T('0') && c <= _T('9')) |
360 |
|| (c >= _T('a') && c <= _T('f')) |
360 |
|| (c >= _T('a') && c <= _T('f')) |
361 |
|| (c >= _T('A') && c <= _T('F'))) |
361 |
|| (c >= _T('A') && c <= _T('F'))) |
362 |
{ |
362 |
{ |
363 |
// valid |
363 |
// valid |
364 |
} |
364 |
} |
365 |
else |
365 |
else |
366 |
{ |
366 |
{ |
367 |
delete [] psz; |
367 |
delete [] psz; |
368 |
return 0; |
368 |
return 0; |
369 |
} |
369 |
} |
370 |
} |
370 |
} |
371 |
|
371 |
|
372 |
DWORD dwProcLen = 0; |
372 |
DWORD dwProcLen = 0; |
373 |
LPBYTE lpb = (LPBYTE)lpBuffer; |
373 |
LPBYTE lpb = (LPBYTE)lpBuffer; |
374 |
|
374 |
|
375 |
if (lpb != NULL) |
375 |
if (lpb != NULL) |
376 |
{ |
376 |
{ |
377 |
dwProcLen = min(dwLen - dwOffset, dwBufSize); |
377 |
dwProcLen = min(dwLen - dwOffset, dwBufSize); |
378 |
LPCTSTR p = &psz[dwOffset * 2]; |
378 |
LPCTSTR p = &psz[dwOffset * 2]; |
379 |
for (DWORD i = 0; i < dwProcLen; i++) |
379 |
for (DWORD i = 0; i < dwProcLen; i++) |
380 |
{ |
380 |
{ |
381 |
TCHAR sz[3] = _T(""); |
381 |
TCHAR sz[3] = _T(""); |
382 |
_tcsncpy(sz, p, 2); |
382 |
_tcsncpy(sz, p, 2); |
383 |
lpb[i] = BYTE(_tcstoul(sz, NULL, 16)); |
383 |
lpb[i] = BYTE(_tcstoul(sz, NULL, 16)); |
384 |
p = &p[2]; |
384 |
p = &p[2]; |
385 |
} |
385 |
} |
386 |
} |
386 |
} |
387 |
else |
387 |
else |
388 |
{ |
388 |
{ |
389 |
dwProcLen = dwLen - dwOffset; |
389 |
dwProcLen = dwLen - dwOffset; |
390 |
} |
390 |
} |
391 |
delete [] psz; |
391 |
delete [] psz; |
392 |
return dwProcLen; |
392 |
return dwProcLen; |
393 |
} |
393 |
} |
394 |
|
394 |
|
395 |
// Write a block of raw data to the ini file |
395 |
// Write a block of raw data to the ini file |
396 |
BOOL CIni::WriteDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const |
396 |
BOOL CIni::WriteDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const |
397 |
{ |
397 |
{ |
398 |
const BYTE* lpb = (const BYTE*)lpData; |
398 |
const BYTE* lpb = (const BYTE*)lpData; |
399 |
if (lpb == NULL) |
399 |
if (lpb == NULL) |
400 |
return FALSE; |
400 |
return FALSE; |
401 |
|
401 |
|
402 |
LPTSTR psz = new TCHAR[dwDataSize * 2 + 1]; |
402 |
LPTSTR psz = new TCHAR[dwDataSize * 2 + 1]; |
403 |
for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2) |
403 |
for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2) |
404 |
_stprintf(&psz[j], _T("%02X"), lpb[i]); |
404 |
_stprintf(&psz[j], _T("%02X"), lpb[i]); |
405 |
const BOOL RES = WriteString(lpSection, lpKey, psz); |
405 |
const BOOL RES = WriteString(lpSection, lpKey, psz); |
406 |
delete [] psz; |
406 |
delete [] psz; |
407 |
return RES; |
407 |
return RES; |
408 |
} |
408 |
} |
409 |
|
409 |
|
410 |
// Append a block of raw data to a specified key in the ini file |
410 |
// Append a block of raw data to a specified key in the ini file |
411 |
BOOL CIni::AppendDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const |
411 |
BOOL CIni::AppendDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const |
412 |
{ |
412 |
{ |
413 |
const BYTE* lpb = (const BYTE*)lpData; |
413 |
const BYTE* lpb = (const BYTE*)lpData; |
414 |
if (lpb == NULL) |
414 |
if (lpb == NULL) |
415 |
return FALSE; |
415 |
return FALSE; |
416 |
|
416 |
|
417 |
LPTSTR psz = new TCHAR[dwDataSize * 2 + 1]; |
417 |
LPTSTR psz = new TCHAR[dwDataSize * 2 + 1]; |
418 |
for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2) |
418 |
for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2) |
419 |
_stprintf(&psz[j], _T("%02X"), lpb[i]); |
419 |
_stprintf(&psz[j], _T("%02X"), lpb[i]); |
420 |
const BOOL RES = AppendString(lpSection, lpKey, psz); |
420 |
const BOOL RES = AppendString(lpSection, lpKey, psz); |
421 |
delete [] psz; |
421 |
delete [] psz; |
422 |
return RES; |
422 |
return RES; |
423 |
} |
423 |
} |
424 |
|
424 |
|
425 |
// Get a POINT value |
425 |
// Get a POINT value |
426 |
POINT CIni::GetPoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT ptDefault) const |
426 |
POINT CIni::GetPoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT ptDefault) const |
427 |
{ |
427 |
{ |
428 |
POINT pt; |
428 |
POINT pt; |
429 |
if (GetDataBlock(lpSection, lpKey, &pt, sizeof(POINT)) != sizeof(POINT)) |
429 |
if (GetDataBlock(lpSection, lpKey, &pt, sizeof(POINT)) != sizeof(POINT)) |
430 |
pt = ptDefault; |
430 |
pt = ptDefault; |
431 |
return pt; |
431 |
return pt; |
432 |
} |
432 |
} |
433 |
|
433 |
|
434 |
// Get a RECT value |
434 |
// Get a RECT value |
435 |
RECT CIni::GetRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rcDefault) const |
435 |
RECT CIni::GetRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rcDefault) const |
436 |
{ |
436 |
{ |
437 |
RECT rc; |
437 |
RECT rc; |
438 |
if (GetDataBlock(lpSection, lpKey, &rc, sizeof(RECT)) != sizeof(RECT)) |
438 |
if (GetDataBlock(lpSection, lpKey, &rc, sizeof(RECT)) != sizeof(RECT)) |
439 |
rc = rcDefault; |
439 |
rc = rcDefault; |
440 |
return rc; |
440 |
return rc; |
441 |
} |
441 |
} |
442 |
|
442 |
|
443 |
// Write a POINT to the ini file |
443 |
// Write a POINT to the ini file |
444 |
BOOL CIni::WritePoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT pt) const |
444 |
BOOL CIni::WritePoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT pt) const |
445 |
{ |
445 |
{ |
446 |
return WriteDataBlock(lpSection, lpKey, &pt, sizeof(POINT)); |
446 |
return WriteDataBlock(lpSection, lpKey, &pt, sizeof(POINT)); |
447 |
} |
447 |
} |
448 |
|
448 |
|
449 |
// Write a RECT to the ini file |
449 |
// Write a RECT to the ini file |
450 |
BOOL CIni::WriteRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rc) const |
450 |
BOOL CIni::WriteRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rc) const |
451 |
{ |
451 |
{ |
452 |
return WriteDataBlock(lpSection, lpKey, &rc, sizeof(RECT)); |
452 |
return WriteDataBlock(lpSection, lpKey, &rc, sizeof(RECT)); |
453 |
} |
453 |
} |
454 |
|
454 |
|
455 |
///////////////////////////////////////////////////////////////////////////////// |
455 |
///////////////////////////////////////////////////////////////////////////////// |
456 |
// Sections & Keys Access |
456 |
// Sections & Keys Access |
457 |
///////////////////////////////////////////////////////////////////////////////// |
457 |
///////////////////////////////////////////////////////////////////////////////// |
458 |
|
458 |
|
459 |
// Retrieve a list of key-lines(key-pairs) of the specified section |
459 |
// Retrieve a list of key-lines(key-pairs) of the specified section |
460 |
DWORD CIni::GetKeyLines(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const |
460 |
DWORD CIni::GetKeyLines(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const |
461 |
{ |
461 |
{ |
462 |
if (lpBuffer != NULL) |
462 |
if (lpBuffer != NULL) |
463 |
*lpBuffer = _T('\0'); |
463 |
*lpBuffer = _T('\0'); |
464 |
|
464 |
|
465 |
if (lpSection == NULL) |
465 |
if (lpSection == NULL) |
466 |
return 0; |
466 |
return 0; |
467 |
|
467 |
|
468 |
if (lpBuffer == NULL) |
468 |
if (lpBuffer == NULL) |
469 |
{ |
469 |
{ |
470 |
// just calculate the required buffer size |
470 |
// just calculate the required buffer size |
471 |
DWORD dwLen = DEF_PROFILE_THRESHOLD; |
471 |
DWORD dwLen = DEF_PROFILE_THRESHOLD; |
472 |
LPTSTR psz = new TCHAR[dwLen + 1]; |
472 |
LPTSTR psz = new TCHAR[dwLen + 1]; |
473 |
DWORD dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName); |
473 |
DWORD dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName); |
474 |
|
474 |
|
475 |
while (dwCopied + 2 >= dwLen) |
475 |
while (dwCopied + 2 >= dwLen) |
476 |
{ |
476 |
{ |
477 |
dwLen += DEF_PROFILE_THRESHOLD; |
477 |
dwLen += DEF_PROFILE_THRESHOLD; |
478 |
delete [] psz; |
478 |
delete [] psz; |
479 |
psz = new TCHAR[dwLen + 1]; |
479 |
psz = new TCHAR[dwLen + 1]; |
480 |
dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName); |
480 |
dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName); |
481 |
} |
481 |
} |
482 |
|
482 |
|
483 |
delete [] psz; |
483 |
delete [] psz; |
484 |
return dwCopied + 2; |
484 |
return dwCopied + 2; |
485 |
} |
485 |
} |
486 |
else |
486 |
else |
487 |
{ |
487 |
{ |
488 |
return ::GetPrivateProfileSection(lpSection, lpBuffer, dwBufSize, m_pszPathName); |
488 |
return ::GetPrivateProfileSection(lpSection, lpBuffer, dwBufSize, m_pszPathName); |
489 |
} |
489 |
} |
490 |
} |
490 |
} |
491 |
|
491 |
|
492 |
// Retrieve a list of key names of the specified section |
492 |
// Retrieve a list of key names of the specified section |
493 |
DWORD CIni::GetKeyNames(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const |
493 |
DWORD CIni::GetKeyNames(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const |
494 |
{ |
494 |
{ |
495 |
if (lpBuffer != NULL) |
495 |
if (lpBuffer != NULL) |
496 |
*lpBuffer = _T('\0'); |
496 |
*lpBuffer = _T('\0'); |
497 |
|
497 |
|
498 |
if (lpSection == NULL) |
498 |
if (lpSection == NULL) |
499 |
return 0; |
499 |
return 0; |
500 |
|
500 |
|
501 |
STR_LIMIT sl; |
501 |
STR_LIMIT sl; |
502 |
sl.lpTarget = lpBuffer; |
502 |
sl.lpTarget = lpBuffer; |
503 |
sl.dwRemain = dwBufSize; |
503 |
sl.dwRemain = dwBufSize; |
504 |
sl.dwTotalCopied = 0; |
504 |
sl.dwTotalCopied = 0; |
505 |
|
505 |
|
506 |
const DWORD LEN = GetKeyLines(lpSection, NULL, 0); |
506 |
const DWORD LEN = GetKeyLines(lpSection, NULL, 0); |
507 |
if (LEN == 0) |
507 |
if (LEN == 0) |
508 |
return 0; |
508 |
return 0; |
509 |
|
509 |
|
510 |
LPTSTR psz = new TCHAR[LEN + 1]; |
510 |
LPTSTR psz = new TCHAR[LEN + 1]; |
511 |
GetKeyLines(lpSection, psz, LEN); |
511 |
GetKeyLines(lpSection, psz, LEN); |
512 |
ParseDNTString(psz, __KeyPairProc, (LPVOID)(&sl)); |
512 |
ParseDNTString(psz, __KeyPairProc, (LPVOID)(&sl)); |
513 |
delete [] psz; |
513 |
delete [] psz; |
514 |
if (lpBuffer != NULL) |
514 |
if (lpBuffer != NULL) |
515 |
lpBuffer[sl.dwTotalCopied] = _T('\0'); |
515 |
lpBuffer[sl.dwTotalCopied] = _T('\0'); |
516 |
return sl.dwTotalCopied; |
516 |
return sl.dwTotalCopied; |
517 |
} |
517 |
} |
518 |
|
518 |
|
519 |
// Get all section names from an ini file |
519 |
// Get all section names from an ini file |
520 |
DWORD CIni::GetSectionNames(LPTSTR lpBuffer, DWORD dwBufSize) const |
520 |
DWORD CIni::GetSectionNames(LPTSTR lpBuffer, DWORD dwBufSize) const |
521 |
{ |
521 |
{ |
522 |
if (lpBuffer == NULL) |
522 |
if (lpBuffer == NULL) |
523 |
{ |
523 |
{ |
524 |
// just calculate the required buffer size |
524 |
// just calculate the required buffer size |
525 |
DWORD dwLen = DEF_PROFILE_THRESHOLD; |
525 |
DWORD dwLen = DEF_PROFILE_THRESHOLD; |
526 |
LPTSTR psz = new TCHAR[dwLen + 1]; |
526 |
LPTSTR psz = new TCHAR[dwLen + 1]; |
527 |
DWORD dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName); |
527 |
DWORD dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName); |
528 |
while (dwCopied + 2 >= dwLen) |
528 |
while (dwCopied + 2 >= dwLen) |
529 |
{ |
529 |
{ |
530 |
dwLen += DEF_PROFILE_THRESHOLD; |
530 |
dwLen += DEF_PROFILE_THRESHOLD; |
531 |
delete [] psz; |
531 |
delete [] psz; |
532 |
psz = new TCHAR[dwLen + 1]; |
532 |
psz = new TCHAR[dwLen + 1]; |
533 |
dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName); |
533 |
dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName); |
534 |
} |
534 |
} |
535 |
|
535 |
|
536 |
delete [] psz; |
536 |
delete [] psz; |
537 |
return dwCopied + 2; |
537 |
return dwCopied + 2; |
538 |
} |
538 |
} |
539 |
else |
539 |
else |
540 |
{ |
540 |
{ |
541 |
return ::GetPrivateProfileSectionNames(lpBuffer, dwBufSize, m_pszPathName); |
541 |
return ::GetPrivateProfileSectionNames(lpBuffer, dwBufSize, m_pszPathName); |
542 |
} |
542 |
} |
543 |
} |
543 |
} |
544 |
|
544 |
|
545 |
#ifdef __AFXWIN_H__ |
545 |
#ifdef __AFXWIN_H__ |
546 |
void CIni::GetSectionNames(CStringArray *pArray) const |
546 |
void CIni::GetSectionNames(CStringArray *pArray) const |
547 |
{ |
547 |
{ |
548 |
if (pArray != NULL) |
548 |
if (pArray != NULL) |
549 |
pArray->RemoveAll(); |
549 |
pArray->RemoveAll(); |
550 |
|
550 |
|
551 |
const DWORD LEN = GetSectionNames(NULL, 0); |
551 |
const DWORD LEN = GetSectionNames(NULL, 0); |
552 |
if (LEN == 0) |
552 |
if (LEN == 0) |
553 |
return; |
553 |
return; |
554 |
|
554 |
|
555 |
LPTSTR psz = new TCHAR[LEN + 1]; |
555 |
LPTSTR psz = new TCHAR[LEN + 1]; |
556 |
GetSectionNames(psz, LEN); |
556 |
GetSectionNames(psz, LEN); |
557 |
ParseDNTString(psz, __SubStrAdd, pArray); |
557 |
ParseDNTString(psz, __SubStrAdd, pArray); |
558 |
delete [] psz; |
558 |
delete [] psz; |
559 |
} |
559 |
} |
560 |
#endif |
560 |
#endif |
561 |
|
561 |
|
562 |
#ifdef __AFXWIN_H__ |
562 |
#ifdef __AFXWIN_H__ |
563 |
// Retrieve a list of key-lines(key-pairs) of the specified section |
563 |
// Retrieve a list of key-lines(key-pairs) of the specified section |
564 |
void CIni::GetKeyLines(LPCTSTR lpSection, CStringArray *pArray) const |
564 |
void CIni::GetKeyLines(LPCTSTR lpSection, CStringArray *pArray) const |
565 |
{ |
565 |
{ |
566 |
if (pArray != NULL) |
566 |
if (pArray != NULL) |
567 |
pArray->RemoveAll(); |
567 |
pArray->RemoveAll(); |
568 |
|
568 |
|
569 |
const DWORD LEN = GetKeyLines(lpSection, NULL, 0); |
569 |
const DWORD LEN = GetKeyLines(lpSection, NULL, 0); |
570 |
if (LEN == 0) |
570 |
if (LEN == 0) |
571 |
return; |
571 |
return; |
572 |
|
572 |
|
573 |
LPTSTR psz = new TCHAR[LEN + 1]; |
573 |
LPTSTR psz = new TCHAR[LEN + 1]; |
574 |
GetKeyLines(lpSection, psz, LEN); |
574 |
GetKeyLines(lpSection, psz, LEN); |
575 |
ParseDNTString(psz, __SubStrAdd, pArray); |
575 |
ParseDNTString(psz, __SubStrAdd, pArray); |
576 |
delete [] psz; |
576 |
delete [] psz; |
577 |
} |
577 |
} |
578 |
#endif |
578 |
#endif |
579 |
|
579 |
|
580 |
#ifdef __AFXWIN_H__ |
580 |
#ifdef __AFXWIN_H__ |
581 |
// Retrieve a list of key names of the specified section |
581 |
// Retrieve a list of key names of the specified section |
582 |
void CIni::GetKeyNames(LPCTSTR lpSection, CStringArray *pArray) const |
582 |
void CIni::GetKeyNames(LPCTSTR lpSection, CStringArray *pArray) const |
583 |
{ |
583 |
{ |
584 |
if (pArray == NULL) |
584 |
if (pArray == NULL) |
585 |
return; |
585 |
return; |
586 |
|
586 |
|
587 |
pArray->RemoveAll(); |
587 |
pArray->RemoveAll(); |
588 |
#ifndef _VS_USED |
588 |
#ifndef _VS_USED |
589 |
const int LEN = GetKeyNames(lpSection, NULL, 0); |
589 |
const int LEN = GetKeyNames(lpSection, NULL, 0); |
590 |
#else |
590 |
#else |
591 |
const LEN = GetKeyNames(lpSection, NULL, 0); |
591 |
const LEN = GetKeyNames(lpSection, NULL, 0); |
592 |
#endif |
592 |
#endif |
593 |
LPTSTR psz = new TCHAR[LEN + 1]; |
593 |
LPTSTR psz = new TCHAR[LEN + 1]; |
594 |
GetKeyNames(lpSection, psz, LEN); |
594 |
GetKeyNames(lpSection, psz, LEN); |
595 |
ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray); |
595 |
ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray); |
596 |
delete [] psz; |
596 |
delete [] psz; |
597 |
} |
597 |
} |
598 |
#endif |
598 |
#endif |
599 |
|
599 |
|
600 |
// Remove whole section from the ini file |
600 |
// Remove whole section from the ini file |
601 |
BOOL CIni::DeleteSection(LPCTSTR lpSection) const |
601 |
BOOL CIni::DeleteSection(LPCTSTR lpSection) const |
602 |
{ |
602 |
{ |
603 |
return ::WritePrivateProfileString(lpSection, NULL, _T(""), m_pszPathName); |
603 |
return ::WritePrivateProfileString(lpSection, NULL, _T(""), m_pszPathName); |
604 |
} |
604 |
} |
605 |
|
605 |
|
606 |
// Remove a key from a section |
606 |
// Remove a key from a section |
607 |
BOOL CIni::DeleteKey(LPCTSTR lpSection, LPCTSTR lpKey) const |
607 |
BOOL CIni::DeleteKey(LPCTSTR lpSection, LPCTSTR lpKey) const |
608 |
{ |
608 |
{ |
609 |
return ::WritePrivateProfileString(lpSection, lpKey, NULL, m_pszPathName); |
609 |
return ::WritePrivateProfileString(lpSection, lpKey, NULL, m_pszPathName); |
610 |
} |
610 |
} |
611 |
|
611 |
|
612 |
BOOL CIni::IsSectionExist(LPCTSTR lpSection) const |
612 |
BOOL CIni::IsSectionExist(LPCTSTR lpSection) const |
613 |
{ |
613 |
{ |
614 |
if (lpSection == NULL) |
614 |
if (lpSection == NULL) |
615 |
return FALSE; |
615 |
return FALSE; |
616 |
|
616 |
|
617 |
// first get the section name list, then check if lpSection exists |
617 |
// first get the section name list, then check if lpSection exists |
618 |
// in the list. |
618 |
// in the list. |
619 |
const DWORD LEN = GetSectionNames(NULL, 0); |
619 |
const DWORD LEN = GetSectionNames(NULL, 0); |
620 |
if (LEN == 0) |
620 |
if (LEN == 0) |
621 |
return FALSE; |
621 |
return FALSE; |
622 |
|
622 |
|
623 |
LPTSTR psz = new TCHAR[LEN + 1]; |
623 |
LPTSTR psz = new TCHAR[LEN + 1]; |
624 |
GetSectionNames(psz, LEN); |
624 |
GetSectionNames(psz, LEN); |
625 |
BOOL RES = !ParseDNTString(psz, __SubStrCompare, (LPVOID)lpSection); |
625 |
BOOL RES = !ParseDNTString(psz, __SubStrCompare, (LPVOID)lpSection); |
626 |
delete [] psz; |
626 |
delete [] psz; |
627 |
return RES; |
627 |
return RES; |
628 |
} |
628 |
} |
629 |
|
629 |
|
630 |
BOOL CIni::IsKeyExist(LPCTSTR lpSection, LPCTSTR lpKey) const |
630 |
BOOL CIni::IsKeyExist(LPCTSTR lpSection, LPCTSTR lpKey) const |
631 |
{ |
631 |
{ |
632 |
if (lpSection == NULL || lpKey == NULL) |
632 |
if (lpSection == NULL || lpKey == NULL) |
633 |
return FALSE; |
633 |
return FALSE; |
634 |
|
634 |
|
635 |
// Test it with the default unique string |
635 |
// Test it with the default unique string |
636 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, DEF_PROFILE_TESTSTRING); |
636 |
LPTSTR psz = __GetStringDynamic(lpSection, lpKey, DEF_PROFILE_TESTSTRING); |
637 |
const BOOL RES = (_tcscmp(psz, DEF_PROFILE_TESTSTRING) != 0); |
637 |
const BOOL RES = (_tcscmp(psz, DEF_PROFILE_TESTSTRING) != 0); |
638 |
delete [] psz; |
638 |
delete [] psz; |
639 |
return RES; |
639 |
return RES; |
640 |
} |
640 |
} |
641 |
|
641 |
|
642 |
BOOL CIni::CopySection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const |
642 |
BOOL CIni::CopySection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const |
643 |
{ |
643 |
{ |
644 |
if (lpSrcSection == NULL || lpDestSection == NULL) |
644 |
if (lpSrcSection == NULL || lpDestSection == NULL) |
645 |
return FALSE; |
645 |
return FALSE; |
646 |
|
646 |
|
647 |
if (_tcsicmp(lpSrcSection, lpDestSection) == 0) |
647 |
if (_tcsicmp(lpSrcSection, lpDestSection) == 0) |
648 |
return FALSE; |
648 |
return FALSE; |
649 |
|
649 |
|
650 |
if (!IsSectionExist(lpSrcSection)) |
650 |
if (!IsSectionExist(lpSrcSection)) |
651 |
return FALSE; |
651 |
return FALSE; |
652 |
|
652 |
|
653 |
if (bFailIfExist && IsSectionExist(lpDestSection)) |
653 |
if (bFailIfExist && IsSectionExist(lpDestSection)) |
654 |
return FALSE; |
654 |
return FALSE; |
655 |
|
655 |
|
656 |
DeleteSection(lpDestSection); |
656 |
DeleteSection(lpDestSection); |
657 |
|
657 |
|
658 |
const DWORD SRC_LEN = GetKeyLines(lpSrcSection, NULL, 0); |
658 |
const DWORD SRC_LEN = GetKeyLines(lpSrcSection, NULL, 0); |
659 |
LPTSTR psz = new TCHAR[SRC_LEN + 2]; |
659 |
LPTSTR psz = new TCHAR[SRC_LEN + 2]; |
660 |
//memset(psz, 0, sizeof(TCHAR) * (SRC_LEN + 2)); |
660 |
//memset(psz, 0, sizeof(TCHAR) * (SRC_LEN + 2)); |
661 |
GetKeyLines(lpSrcSection, psz, SRC_LEN); |
661 |
GetKeyLines(lpSrcSection, psz, SRC_LEN); |
662 |
const BOOL RES = ::WritePrivateProfileSection(lpDestSection, psz, m_pszPathName); |
662 |
const BOOL RES = ::WritePrivateProfileSection(lpDestSection, psz, m_pszPathName); |
663 |
delete [] psz; |
663 |
delete [] psz; |
664 |
|
664 |
|
665 |
return RES; |
665 |
return RES; |
666 |
} |
666 |
} |
667 |
|
667 |
|
668 |
BOOL CIni::CopyKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const |
668 |
BOOL CIni::CopyKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const |
669 |
{ |
669 |
{ |
670 |
if (lpSrcSection == NULL || lpSrcKey == NULL || lpDestKey == NULL) |
670 |
if (lpSrcSection == NULL || lpSrcKey == NULL || lpDestKey == NULL) |
671 |
return FALSE; |
671 |
return FALSE; |
672 |
|
672 |
|
673 |
if (_tcsicmp(lpSrcSection, lpDestSection) == 0 |
673 |
if (_tcsicmp(lpSrcSection, lpDestSection) == 0 |
674 |
&& _tcsicmp(lpSrcKey, lpDestKey) == 0) |
674 |
&& _tcsicmp(lpSrcKey, lpDestKey) == 0) |
675 |
return FALSE; |
675 |
return FALSE; |
676 |
|
676 |
|
677 |
if (!IsKeyExist(lpSrcSection, lpSrcKey)) |
677 |
if (!IsKeyExist(lpSrcSection, lpSrcKey)) |
678 |
return FALSE; |
678 |
return FALSE; |
679 |
|
679 |
|
680 |
if (bFailIfExist && IsKeyExist(lpDestSection, lpDestKey)) |
680 |
if (bFailIfExist && IsKeyExist(lpDestSection, lpDestKey)) |
681 |
return FALSE; |
681 |
return FALSE; |
682 |
|
682 |
|
683 |
LPTSTR psz = __GetStringDynamic(lpSrcSection, lpSrcKey); |
683 |
LPTSTR psz = __GetStringDynamic(lpSrcSection, lpSrcKey); |
684 |
const BOOL RES = WriteString(lpDestSection, lpDestKey, psz); |
684 |
const BOOL RES = WriteString(lpDestSection, lpDestKey, psz); |
685 |
delete [] psz; |
685 |
delete [] psz; |
686 |
return RES; |
686 |
return RES; |
687 |
} |
687 |
} |
688 |
|
688 |
|
689 |
BOOL CIni::MoveSection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const |
689 |
BOOL CIni::MoveSection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const |
690 |
{ |
690 |
{ |
691 |
return CopySection(lpSrcSection, lpDestSection, bFailIfExist) |
691 |
return CopySection(lpSrcSection, lpDestSection, bFailIfExist) |
692 |
&& DeleteSection(lpSrcSection); |
692 |
&& DeleteSection(lpSrcSection); |
693 |
} |
693 |
} |
694 |
|
694 |
|
695 |
BOOL CIni::MoveKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const |
695 |
BOOL CIni::MoveKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const |
696 |
{ |
696 |
{ |
697 |
return CopyKey(lpSrcSection, lpSrcKey, lpDestSection, lpDestKey, bFailIfExist) |
697 |
return CopyKey(lpSrcSection, lpSrcKey, lpDestSection, lpDestKey, bFailIfExist) |
698 |
&& DeleteKey(lpSrcSection, lpSrcKey); |
698 |
&& DeleteKey(lpSrcSection, lpSrcKey); |
699 |
} |
699 |
} |
700 |
|
700 |
|
701 |
///////////////////////////////////////////////////////////////////////////////// |
701 |
///////////////////////////////////////////////////////////////////////////////// |
702 |
// Helper Functions |
702 |
// Helper Functions |
703 |
///////////////////////////////////////////////////////////////////////////////// |
703 |
///////////////////////////////////////////////////////////////////////////////// |
704 |
|
704 |
|
705 |
// Get a profile string value, return a heap pointer so we do not have to worry |
705 |
// Get a profile string value, return a heap pointer so we do not have to worry |
706 |
// about the buffer size, however, this function requires the caller to manually |
706 |
// about the buffer size, however, this function requires the caller to manually |
707 |
// free the memory. |
707 |
// free the memory. |
708 |
// This function is the back-bone of all "Getxxx" functions of this class. |
708 |
// This function is the back-bone of all "Getxxx" functions of this class. |
709 |
LPTSTR CIni::__GetStringDynamic(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const |
709 |
LPTSTR CIni::__GetStringDynamic(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const |
710 |
{ |
710 |
{ |
711 |
TCHAR* psz = NULL; |
711 |
TCHAR* psz = NULL; |
712 |
if (lpSection == NULL || lpKey == NULL) |
712 |
if (lpSection == NULL || lpKey == NULL) |
713 |
{ |
713 |
{ |
714 |
// Invalid section or key name, just return the default string |
714 |
// Invalid section or key name, just return the default string |
715 |
if (lpDefault == NULL) |
715 |
if (lpDefault == NULL) |
716 |
{ |
716 |
{ |
717 |
// Empty string |
717 |
// Empty string |
718 |
psz = new TCHAR[1]; |
718 |
psz = new TCHAR[1]; |
719 |
*psz = _T('\0'); |
719 |
*psz = _T('\0'); |
720 |
} |
720 |
} |
721 |
else |
721 |
else |
722 |
{ |
722 |
{ |
723 |
psz = new TCHAR[_tcslen(lpDefault) + 1]; |
723 |
psz = new TCHAR[_tcslen(lpDefault) + 1]; |
724 |
_tcscpy(psz, lpDefault); |
724 |
_tcscpy(psz, lpDefault); |
725 |
} |
725 |
} |
726 |
|
726 |
|
727 |
return psz; |
727 |
return psz; |
728 |
} |
728 |
} |
729 |
|
729 |
|
730 |
// Keep enlarging the buffer size until being certain on that the string we |
730 |
// Keep enlarging the buffer size until being certain on that the string we |
731 |
// retrieved was original(not truncated). |
731 |
// retrieved was original(not truncated). |
732 |
DWORD dwLen = DEF_PROFILE_THRESHOLD; |
732 |
DWORD dwLen = DEF_PROFILE_THRESHOLD; |
733 |
psz = new TCHAR[dwLen + 1]; |
733 |
psz = new TCHAR[dwLen + 1]; |
734 |
DWORD dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName); |
734 |
DWORD dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName); |
735 |
while (dwCopied + 1 >= dwLen) |
735 |
while (dwCopied + 1 >= dwLen) |
736 |
{ |
736 |
{ |
737 |
dwLen += DEF_PROFILE_THRESHOLD; |
737 |
dwLen += DEF_PROFILE_THRESHOLD; |
738 |
delete [] psz; |
738 |
delete [] psz; |
739 |
psz = new TCHAR[dwLen + 1]; |
739 |
psz = new TCHAR[dwLen + 1]; |
740 |
dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName); |
740 |
dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName); |
741 |
} |
741 |
} |
742 |
|
742 |
|
743 |
return psz; // !!! Requires the caller to free this memory !!! |
743 |
return psz; // !!! Requires the caller to free this memory !!! |
744 |
} |
744 |
} |
745 |
|
745 |
|
746 |
// Split a string usinf a particular delimiter, split result are copied into lpBuffer |
746 |
// Split a string usinf a particular delimiter, split result are copied into lpBuffer |
747 |
// in the "double null terminated string" format as the following figure shows: |
747 |
// in the "double null terminated string" format as the following figure shows: |
748 |
// xxx\0xxxx\0xx\0xxx\0\0 |
748 |
// xxx\0xxxx\0xx\0xxx\0\0 |
749 |
// |
749 |
// |
750 |
// For example, if the delimiter is ",", then string "ab,cd,e" will be |
750 |
// For example, if the delimiter is ",", then string "ab,cd,e" will be |
751 |
// splitted into "ab\0cd\0e\0\0", this string format can be parsed into an array |
751 |
// splitted into "ab\0cd\0e\0\0", this string format can be parsed into an array |
752 |
// of sub strings easily using user defined functions or CIni::ParseStringArray. |
752 |
// of sub strings easily using user defined functions or CIni::ParseStringArray. |
753 |
DWORD CIni::__StringSplit(LPCTSTR lpString, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) |
753 |
DWORD CIni::__StringSplit(LPCTSTR lpString, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) |
754 |
{ |
754 |
{ |
755 |
if (lpString == NULL || lpBuffer == NULL || dwBufSize == 0) |
755 |
if (lpString == NULL || lpBuffer == NULL || dwBufSize == 0) |
756 |
return 0; |
756 |
return 0; |
757 |
|
757 |
|
758 |
DWORD dwCopied = 0; |
758 |
DWORD dwCopied = 0; |
759 |
*lpBuffer = _T('\0'); |
759 |
*lpBuffer = _T('\0'); |
760 |
if (*lpString == _T('\0')) |
760 |
if (*lpString == _T('\0')) |
761 |
return 0; |
761 |
return 0; |
762 |
|
762 |
|
763 |
// If lpDelimiter is NULL, use the default delimiter ",", if delimiter length |
763 |
// If lpDelimiter is NULL, use the default delimiter ",", if delimiter length |
764 |
// is 0, then return whole string |
764 |
// is 0, then return whole string |
765 |
if (lpDelimiter != NULL && *lpDelimiter == _T('\0')) |
765 |
if (lpDelimiter != NULL && *lpDelimiter == _T('\0')) |
766 |
{ |
766 |
{ |
767 |
_tcsncpy(lpBuffer, lpString, dwBufSize - 1); |
767 |
_tcsncpy(lpBuffer, lpString, dwBufSize - 1); |
768 |
return _tcslen(lpBuffer); |
768 |
return _tcslen(lpBuffer); |
769 |
} |
769 |
} |
770 |
|
770 |
|
771 |
LPTSTR pszDel = (lpDelimiter == NULL) ? _tcsdup(DEF_PROFILE_DELIMITER) : _tcsdup(lpDelimiter); |
771 |
LPTSTR pszDel = (lpDelimiter == NULL) ? _tcsdup(DEF_PROFILE_DELIMITER) : _tcsdup(lpDelimiter); |
772 |
const DWORD DEL_LEN = _tcslen(pszDel); |
772 |
const DWORD DEL_LEN = _tcslen(pszDel); |
773 |
LPTSTR lpTarget = lpBuffer; |
773 |
LPTSTR lpTarget = lpBuffer; |
774 |
|
774 |
|
775 |
// Search through lpString for delimiter matches, and extract sub strings out |
775 |
// Search through lpString for delimiter matches, and extract sub strings out |
776 |
LPCTSTR lpPos = lpString; |
776 |
LPCTSTR lpPos = lpString; |
777 |
LPCTSTR lpEnd = _tcsstr(lpPos, pszDel); |
777 |
LPCTSTR lpEnd = _tcsstr(lpPos, pszDel); |
778 |
|
778 |
|
779 |
while (lpEnd != NULL) |
779 |
while (lpEnd != NULL) |
780 |
{ |
780 |
{ |
781 |
LPTSTR pszSeg = __StrDupEx(lpPos, lpEnd); |
781 |
LPTSTR pszSeg = __StrDupEx(lpPos, lpEnd); |
782 |
if (bTrimString) |
782 |
if (bTrimString) |
783 |
__TrimString(pszSeg); |
783 |
__TrimString(pszSeg); |
784 |
|
784 |
|
785 |
const DWORD SEG_LEN = _tcslen(pszSeg); |
785 |
const DWORD SEG_LEN = _tcslen(pszSeg); |
786 |
const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied); |
786 |
const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied); |
787 |
|
787 |
|
788 |
// Need to avoid buffer overflow |
788 |
// Need to avoid buffer overflow |
789 |
if (COPY_LEN > 0) |
789 |
if (COPY_LEN > 0) |
790 |
{ |
790 |
{ |
791 |
dwCopied += COPY_LEN + 1; |
791 |
dwCopied += COPY_LEN + 1; |
792 |
_tcsncpy(lpTarget, pszSeg, COPY_LEN); |
792 |
_tcsncpy(lpTarget, pszSeg, COPY_LEN); |
793 |
lpTarget[COPY_LEN] = _T('\0'); |
793 |
lpTarget[COPY_LEN] = _T('\0'); |
794 |
lpTarget = &lpTarget[SEG_LEN + 1]; |
794 |
lpTarget = &lpTarget[SEG_LEN + 1]; |
795 |
} |
795 |
} |
796 |
delete [] pszSeg; |
796 |
delete [] pszSeg; |
797 |
lpPos = &lpEnd[DEL_LEN]; // Advance the pointer for next search |
797 |
lpPos = &lpEnd[DEL_LEN]; // Advance the pointer for next search |
798 |
lpEnd = _tcsstr(lpPos, pszDel); |
798 |
lpEnd = _tcsstr(lpPos, pszDel); |
799 |
} |
799 |
} |
800 |
|
800 |
|
801 |
// The last part of string, there may not be the trailing delimiter, so we |
801 |
// The last part of string, there may not be the trailing delimiter, so we |
802 |
// need to take care of this part, too |
802 |
// need to take care of this part, too |
803 |
LPTSTR pszSeg = _tcsdup(lpPos); |
803 |
LPTSTR pszSeg = _tcsdup(lpPos); |
804 |
if (bTrimString) |
804 |
if (bTrimString) |
805 |
__TrimString(pszSeg); |
805 |
__TrimString(pszSeg); |
806 |
|
806 |
|
807 |
const DWORD SEG_LEN = _tcslen(pszSeg); |
807 |
const DWORD SEG_LEN = _tcslen(pszSeg); |
808 |
const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied); |
808 |
const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied); |
809 |
|
809 |
|
810 |
if (COPY_LEN > 0) |
810 |
if (COPY_LEN > 0) |
811 |
{ |
811 |
{ |
812 |
dwCopied += COPY_LEN + 1; |
812 |
dwCopied += COPY_LEN + 1; |
813 |
_tcsncpy(lpTarget, pszSeg, COPY_LEN); |
813 |
_tcsncpy(lpTarget, pszSeg, COPY_LEN); |
814 |
lpTarget[COPY_LEN] = _T('\0'); |
814 |
lpTarget[COPY_LEN] = _T('\0'); |
815 |
} |
815 |
} |
816 |
|
816 |
|
817 |
delete [] pszSeg; |
817 |
delete [] pszSeg; |
818 |
lpBuffer[dwCopied] = _T('\0'); |
818 |
lpBuffer[dwCopied] = _T('\0'); |
819 |
delete [] pszDel; |
819 |
delete [] pszDel; |
820 |
return dwCopied; |
820 |
return dwCopied; |
821 |
} |
821 |
} |
822 |
|
822 |
|
823 |
// Parse a "double null terminated string", pass each sub string to a user-defined |
823 |
// Parse a "double null terminated string", pass each sub string to a user-defined |
824 |
// callback function |
824 |
// callback function |
825 |
BOOL CIni::ParseDNTString(LPCTSTR lpString, SUBSTRPROC lpFnStrProc, LPVOID lpParam) |
825 |
BOOL CIni::ParseDNTString(LPCTSTR lpString, SUBSTRPROC lpFnStrProc, LPVOID lpParam) |
826 |
{ |
826 |
{ |
827 |
if (lpString == NULL || lpFnStrProc == NULL) |
827 |
if (lpString == NULL || lpFnStrProc == NULL) |
828 |
return FALSE; |
828 |
return FALSE; |
829 |
|
829 |
|
830 |
LPCTSTR p = lpString; |
830 |
LPCTSTR p = lpString; |
831 |
DWORD dwLen = _tcslen(p); |
831 |
DWORD dwLen = _tcslen(p); |
832 |
|
832 |
|
833 |
while (dwLen > 0) |
833 |
while (dwLen > 0) |
834 |
{ |
834 |
{ |
835 |
if (!lpFnStrProc(p, lpParam)) |
835 |
if (!lpFnStrProc(p, lpParam)) |
836 |
return FALSE; |
836 |
return FALSE; |
837 |
|
837 |
|
838 |
p = &p[dwLen + 1]; |
838 |
p = &p[dwLen + 1]; |
839 |
dwLen = _tcslen(p); |
839 |
dwLen = _tcslen(p); |
840 |
} |
840 |
} |
841 |
return TRUE; |
841 |
return TRUE; |
842 |
} |
842 |
} |
843 |
|
843 |
|
844 |
// Callback function used to compare elements inside of a |
844 |
// Callback function used to compare elements inside of a |
845 |
// "double null terminated string" with a given string. Useful for |
845 |
// "double null terminated string" with a given string. Useful for |
846 |
// searching in the section names list. |
846 |
// searching in the section names list. |
847 |
BOOL CALLBACK CIni::__SubStrCompare(LPCTSTR lpString1, LPVOID lpParam) |
847 |
BOOL CALLBACK CIni::__SubStrCompare(LPCTSTR lpString1, LPVOID lpParam) |
848 |
{ |
848 |
{ |
849 |
assert(lpString1 != NULL); |
849 |
assert(lpString1 != NULL); |
850 |
LPCTSTR lpString2 = (LPCTSTR)lpParam; |
850 |
LPCTSTR lpString2 = (LPCTSTR)lpParam; |
851 |
assert(lpString2 != NULL); |
851 |
assert(lpString2 != NULL); |
852 |
// if two string matches, return zero to stop the parsing |
852 |
// if two string matches, return zero to stop the parsing |
853 |
return _tcsicmp(lpString1, lpString2) != 0; |
853 |
return _tcsicmp(lpString1, lpString2) != 0; |
854 |
} |
854 |
} |
855 |
|
855 |
|
856 |
// Callback function used to process a key-pair, it extracts the |
856 |
// Callback function used to process a key-pair, it extracts the |
857 |
// key name from the key-pair string |
857 |
// key name from the key-pair string |
858 |
BOOL CALLBACK CIni:: __KeyPairProc(LPCTSTR lpString, LPVOID lpParam) |
858 |
BOOL CALLBACK CIni:: __KeyPairProc(LPCTSTR lpString, LPVOID lpParam) |
859 |
{ |
859 |
{ |
860 |
STR_LIMIT* psl = (STR_LIMIT*)lpParam; |
860 |
STR_LIMIT* psl = (STR_LIMIT*)lpParam; |
861 |
if (lpString == NULL || psl== NULL) |
861 |
if (lpString == NULL || psl== NULL) |
862 |
return FALSE; |
862 |
return FALSE; |
863 |
|
863 |
|
864 |
LPCTSTR p = _tcschr(lpString, _T('=')); |
864 |
LPCTSTR p = _tcschr(lpString, _T('=')); |
865 |
if (p == NULL || p == lpString) |
865 |
if (p == NULL || p == lpString) |
866 |
return TRUE; |
866 |
return TRUE; |
867 |
|
867 |
|
868 |
// extract the sub-string on left side of the '=' |
868 |
// extract the sub-string on left side of the '=' |
869 |
LPTSTR psz = new TCHAR[_tcslen(lpString) + 1]; |
869 |
LPTSTR psz = new TCHAR[_tcslen(lpString) + 1]; |
870 |
|
870 |
|
871 |
//#ifndef _VS6_USED |
871 |
#ifndef _VS6_USED |
872 |
int i; |
872 |
int i; |
873 |
//#endif |
873 |
#endif |
874 |
|
874 |
|
875 |
for (int i = 0; &lpString[i] < p; i++) |
875 |
for (int i = 0; &lpString[i] < p; i++) |
876 |
psz[i] = lpString[i]; |
876 |
psz[i] = lpString[i]; |
877 |
psz[i] = _T('\0'); |
877 |
psz[i] = _T('\0'); |
878 |
|
878 |
|
879 |
// trim |
879 |
// trim |
880 |
__TrimString(psz); |
880 |
__TrimString(psz); |
881 |
DWORD dwNameLen = _tcslen(psz); |
881 |
DWORD dwNameLen = _tcslen(psz); |
882 |
DWORD dwCopyLen = 0; |
882 |
DWORD dwCopyLen = 0; |
883 |
|
883 |
|
884 |
//copy to the buffer |
884 |
//copy to the buffer |
885 |
if (psl->lpTarget != NULL) |
885 |
if (psl->lpTarget != NULL) |
886 |
{ |
886 |
{ |
887 |
dwCopyLen = (psl->dwRemain > 1) ? min(dwNameLen, psl->dwRemain - 1) : 0; |
887 |
dwCopyLen = (psl->dwRemain > 1) ? min(dwNameLen, psl->dwRemain - 1) : 0; |
888 |
_tcsncpy(psl->lpTarget, psz, dwCopyLen); |
888 |
_tcsncpy(psl->lpTarget, psz, dwCopyLen); |
889 |
psl->lpTarget[dwCopyLen] = _T('\0'); |
889 |
psl->lpTarget[dwCopyLen] = _T('\0'); |
890 |
psl->lpTarget = &(psl->lpTarget[dwCopyLen + 1]); |
890 |
psl->lpTarget = &(psl->lpTarget[dwCopyLen + 1]); |
891 |
psl->dwRemain -= dwCopyLen + 1; |
891 |
psl->dwRemain -= dwCopyLen + 1; |
892 |
} |
892 |
} |
893 |
else |
893 |
else |
894 |
{ |
894 |
{ |
895 |
dwCopyLen = dwNameLen; |
895 |
dwCopyLen = dwNameLen; |
896 |
} |
896 |
} |
897 |
|
897 |
|
898 |
delete [] psz; |
898 |
delete [] psz; |
899 |
psl->dwTotalCopied += dwCopyLen + 1; |
899 |
psl->dwTotalCopied += dwCopyLen + 1; |
900 |
return TRUE; |
900 |
return TRUE; |
901 |
} |
901 |
} |
902 |
|
902 |
|
903 |
#ifdef __AFXWIN_H__ |
903 |
#ifdef __AFXWIN_H__ |
904 |
// Callback function used to add elements that are extracted from a |
904 |
// Callback function used to add elements that are extracted from a |
905 |
// "double null terminated string" to an MFC CStringArray. |
905 |
// "double null terminated string" to an MFC CStringArray. |
906 |
BOOL CALLBACK CIni::__SubStrAdd(LPCTSTR lpString, LPVOID lpParam) |
906 |
BOOL CALLBACK CIni::__SubStrAdd(LPCTSTR lpString, LPVOID lpParam) |
907 |
{ |
907 |
{ |
908 |
CStringArray* pArray = (CStringArray*)lpParam; |
908 |
CStringArray* pArray = (CStringArray*)lpParam; |
909 |
if (pArray == NULL || lpString == NULL) |
909 |
if (pArray == NULL || lpString == NULL) |
910 |
return FALSE; |
910 |
return FALSE; |
911 |
|
911 |
|
912 |
pArray->Add(lpString); |
912 |
pArray->Add(lpString); |
913 |
return TRUE; |
913 |
return TRUE; |
914 |
} |
914 |
} |
915 |
#endif |
915 |
#endif |
916 |
|
916 |
|
917 |
// Convert an integer into binary string format |
917 |
// Convert an integer into binary string format |
918 |
void CIni::__ToBinaryString(UINT nNumber, LPTSTR lpBuffer, DWORD dwBufSize) |
918 |
void CIni::__ToBinaryString(UINT nNumber, LPTSTR lpBuffer, DWORD dwBufSize) |
919 |
{ |
919 |
{ |
920 |
if (dwBufSize == 0) |
920 |
if (dwBufSize == 0) |
921 |
return; |
921 |
return; |
922 |
|
922 |
|
923 |
DWORD dwIndex = 0; |
923 |
DWORD dwIndex = 0; |
924 |
do |
924 |
do |
925 |
{ |
925 |
{ |
926 |
lpBuffer[dwIndex++] = (nNumber % 2) ? _T('1') : _T('0'); |
926 |
lpBuffer[dwIndex++] = (nNumber % 2) ? _T('1') : _T('0'); |
927 |
nNumber /= 2; |
927 |
nNumber /= 2; |
928 |
} while (nNumber > 0 && dwIndex < dwBufSize); |
928 |
} while (nNumber > 0 && dwIndex < dwBufSize); |
929 |
|
929 |
|
930 |
lpBuffer[dwIndex] = _T('\0'); |
930 |
lpBuffer[dwIndex] = _T('\0'); |
931 |
_tcsrev(lpBuffer); |
931 |
_tcsrev(lpBuffer); |
932 |
} |
932 |
} |
933 |
|
933 |
|
934 |
// Make sure the base will be expected value |
934 |
// Make sure the base will be expected value |
935 |
int CIni::__ValidateBase(int nBase) |
935 |
int CIni::__ValidateBase(int nBase) |
936 |
{ |
936 |
{ |
937 |
switch (nBase) |
937 |
switch (nBase) |
938 |
{ |
938 |
{ |
939 |
case BASE_BINARY: |
939 |
case BASE_BINARY: |
940 |
case BASE_OCTAL: |
940 |
case BASE_OCTAL: |
941 |
case BASE_HEXADECIMAL: |
941 |
case BASE_HEXADECIMAL: |
942 |
break; |
942 |
break; |
943 |
|
943 |
|
944 |
default: |
944 |
default: |
945 |
nBase = BASE_DECIMAL; |
945 |
nBase = BASE_DECIMAL; |
946 |
} |
946 |
} |
947 |
|
947 |
|
948 |
return nBase; |
948 |
return nBase; |
949 |
} |
949 |
} |
950 |
|
950 |
|
951 |
// Convert a signed integer into string representation, based on its base |
951 |
// Convert a signed integer into string representation, based on its base |
952 |
void CIni::__IntToString(int nNumber, LPTSTR lpBuffer, int nBase) |
952 |
void CIni::__IntToString(int nNumber, LPTSTR lpBuffer, int nBase) |
953 |
{ |
953 |
{ |
954 |
switch (nBase) |
954 |
switch (nBase) |
955 |
{ |
955 |
{ |
956 |
case BASE_BINARY: |
956 |
case BASE_BINARY: |
957 |
case BASE_OCTAL: |
957 |
case BASE_OCTAL: |
958 |
case BASE_HEXADECIMAL: |
958 |
case BASE_HEXADECIMAL: |
959 |
__UIntToString((UINT)nNumber, lpBuffer, nBase); |
959 |
__UIntToString((UINT)nNumber, lpBuffer, nBase); |
960 |
break; |
960 |
break; |
961 |
|
961 |
|
962 |
default: |
962 |
default: |
963 |
_stprintf(lpBuffer, _T("%d"), nNumber); |
963 |
_stprintf(lpBuffer, _T("%d"), nNumber); |
964 |
break; |
964 |
break; |
965 |
} |
965 |
} |
966 |
} |
966 |
} |
967 |
|
967 |
|
968 |
// Convert an unsigned integer into string representation, based on its base |
968 |
// Convert an unsigned integer into string representation, based on its base |
969 |
void CIni::__UIntToString(UINT nNumber, LPTSTR lpBuffer, int nBase) |
969 |
void CIni::__UIntToString(UINT nNumber, LPTSTR lpBuffer, int nBase) |
970 |
{ |
970 |
{ |
971 |
switch (nBase) |
971 |
switch (nBase) |
972 |
{ |
972 |
{ |
973 |
case BASE_BINARY: |
973 |
case BASE_BINARY: |
974 |
__ToBinaryString(nNumber, lpBuffer, DEF_PROFILE_NUM_LEN); |
974 |
__ToBinaryString(nNumber, lpBuffer, DEF_PROFILE_NUM_LEN); |
975 |
break; |
975 |
break; |
976 |
|
976 |
|
977 |
case BASE_OCTAL: |
977 |
case BASE_OCTAL: |
978 |
_stprintf(lpBuffer, _T("%o"), nNumber); |
978 |
_stprintf(lpBuffer, _T("%o"), nNumber); |
979 |
break; |
979 |
break; |
980 |
|
980 |
|
981 |
case BASE_HEXADECIMAL: |
981 |
case BASE_HEXADECIMAL: |
982 |
_stprintf(lpBuffer, _T("%X"), nNumber); |
982 |
_stprintf(lpBuffer, _T("%X"), nNumber); |
983 |
break; |
983 |
break; |
984 |
|
984 |
|
985 |
default: |
985 |
default: |
986 |
_stprintf(lpBuffer, _T("%u"), nNumber); |
986 |
_stprintf(lpBuffer, _T("%u"), nNumber); |
987 |
break; |
987 |
break; |
988 |
} |
988 |
} |
989 |
} |
989 |
} |
990 |
|
990 |
|
991 |
BOOL CIni::StringToBool(LPCTSTR lpString, BOOL bDefault) |
991 |
BOOL CIni::StringToBool(LPCTSTR lpString, BOOL bDefault) |
992 |
{ |
992 |
{ |
993 |
// Default: empty string |
993 |
// Default: empty string |
994 |
// TRUE: "true", "yes", non-zero decimal numner |
994 |
// TRUE: "true", "yes", non-zero decimal numner |
995 |
// FALSE: all other cases |
995 |
// FALSE: all other cases |
996 |
if (lpString == NULL || *lpString == _T('\0')) |
996 |
if (lpString == NULL || *lpString == _T('\0')) |
997 |
return bDefault; |
997 |
return bDefault; |
998 |
|
998 |
|
999 |
return (_tcsicmp(lpString, _T("true")) == 0 |
999 |
return (_tcsicmp(lpString, _T("true")) == 0 |
1000 |
|| _tcsicmp(lpString, _T("yes")) == 0 |
1000 |
|| _tcsicmp(lpString, _T("yes")) == 0 |
1001 |
|| _tcstol(lpString, NULL, BASE_DECIMAL) != 0); |
1001 |
|| _tcstol(lpString, NULL, BASE_DECIMAL) != 0); |
1002 |
} |
1002 |
} |
1003 |
|
1003 |
|
1004 |
BOOL CIni::__TrimString(LPTSTR lpString) |
1004 |
BOOL CIni::__TrimString(LPTSTR lpString) |
1005 |
{ |
1005 |
{ |
1006 |
if (lpString == NULL) |
1006 |
if (lpString == NULL) |
1007 |
return FALSE; |
1007 |
return FALSE; |
1008 |
|
1008 |
|
1009 |
BOOL bTrimmed = FALSE; |
1009 |
BOOL bTrimmed = FALSE; |
1010 |
int nLen = _tcslen(lpString); |
1010 |
int nLen = _tcslen(lpString); |
1011 |
|
1011 |
|
1012 |
// '\n' and '\r' are actually not possible in this case, but anyway... |
1012 |
// '\n' and '\r' are actually not possible in this case, but anyway... |
1013 |
|
1013 |
|
1014 |
// Trim right side |
1014 |
// Trim right side |
1015 |
while (nLen >= 0 |
1015 |
while (nLen >= 0 |
1016 |
&& (lpString[nLen - 1] == _T(' ') |
1016 |
&& (lpString[nLen - 1] == _T(' ') |
1017 |
|| lpString[nLen - 1] == _T('\t') |
1017 |
|| lpString[nLen - 1] == _T('\t') |
1018 |
|| lpString[nLen - 1] == _T('\r') |
1018 |
|| lpString[nLen - 1] == _T('\r') |
1019 |
|| lpString[nLen - 1] == _T('\n'))) |
1019 |
|| lpString[nLen - 1] == _T('\n'))) |
1020 |
{ |
1020 |
{ |
1021 |
lpString[--nLen] = _T('\0'); |
1021 |
lpString[--nLen] = _T('\0'); |
1022 |
bTrimmed = TRUE; |
1022 |
bTrimmed = TRUE; |
1023 |
} |
1023 |
} |
1024 |
|
1024 |
|
1025 |
// Trim left side |
1025 |
// Trim left side |
1026 |
LPCTSTR p = lpString; |
1026 |
LPCTSTR p = lpString; |
1027 |
while (*p == _T(' ') |
1027 |
while (*p == _T(' ') |
1028 |
|| *p == _T('\t') |
1028 |
|| *p == _T('\t') |
1029 |
|| *p == _T('\r') |
1029 |
|| *p == _T('\r') |
1030 |
|| *p == _T('\n')) |
1030 |
|| *p == _T('\n')) |
1031 |
{ |
1031 |
{ |
1032 |
p = &p[1]; |
1032 |
p = &p[1]; |
1033 |
bTrimmed = TRUE; |
1033 |
bTrimmed = TRUE; |
1034 |
} |
1034 |
} |
1035 |
|
1035 |
|
1036 |
if (p != lpString) |
1036 |
if (p != lpString) |
1037 |
{ |
1037 |
{ |
1038 |
LPTSTR psz = _tcsdup(p); |
1038 |
LPTSTR psz = _tcsdup(p); |
1039 |
_tcscpy(lpString, psz); |
1039 |
_tcscpy(lpString, psz); |
1040 |
delete [] psz; |
1040 |
delete [] psz; |
1041 |
} |
1041 |
} |
1042 |
|
1042 |
|
1043 |
return bTrimmed; |
1043 |
return bTrimmed; |
1044 |
} |
1044 |
} |
1045 |
|
1045 |
|
1046 |
LPTSTR CIni::__StrDupEx(LPCTSTR lpStart, LPCTSTR lpEnd) |
1046 |
LPTSTR CIni::__StrDupEx(LPCTSTR lpStart, LPCTSTR lpEnd) |
1047 |
{ |
1047 |
{ |
1048 |
const DWORD LEN = ((DWORD)lpEnd - (DWORD)lpStart) / sizeof(TCHAR); |
1048 |
const DWORD LEN = ((DWORD)lpEnd - (DWORD)lpStart) / sizeof(TCHAR); |
1049 |
LPTSTR psz = new TCHAR[LEN + 1]; |
1049 |
LPTSTR psz = new TCHAR[LEN + 1]; |
1050 |
_tcsncpy(psz, lpStart, LEN); |
1050 |
_tcsncpy(psz, lpStart, LEN); |
1051 |
psz[LEN] = _T('\0'); |
1051 |
psz[LEN] = _T('\0'); |
1052 |
return psz; // !!! Requires the caller to free this memory !!! |
1052 |
return psz; // !!! Requires the caller to free this memory !!! |
1053 |
} |
1053 |
} |
1054 |
|
1054 |
|
1055 |
///////////////////////////////////////////////////////////////////////////////// |
1055 |
///////////////////////////////////////////////////////////////////////////////// |
1056 |
// End of Cini Class Implementation |
1056 |
// End of Cini Class Implementation |
1057 |
///////////////////////////////////////////////////////////////////////////////// |
1057 |
///////////////////////////////////////////////////////////////////////////////// |
1058 |
|
1058 |
|
1059 |
// If you are getting this error: |
1059 |
// If you are getting this error: |
1060 |
// ---------------------------------------------------------------------------- |
1060 |
// ---------------------------------------------------------------------------- |
1061 |
// "fatal error C1010: unexpected end of file while looking for precompiled |
1061 |
// "fatal error C1010: unexpected end of file while looking for precompiled |
1062 |
// header directive" |
1062 |
// header directive" |
1063 |
//----------------------------------------------------------------------------- |
1063 |
//----------------------------------------------------------------------------- |
1064 |
// Please scroll all the way up and uncomment '#include "stdafx.h"' |
1064 |
// Please scroll all the way up and uncomment '#include "stdafx.h"' |