]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/iniconf.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/iniconf.cpp
3 // Purpose: implementation of wxIniConfig class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
26 #include <wx/string.h>
30 #include <wx/dynarray.h>
32 #include <wx/config.h>
34 #include <wx/msw/iniconf.h>
36 // _WINDOWS_ is defined when windows.h is included,
37 // __WXMSW__ is defined for MS Windows compilation
38 #if defined(__WXMSW__) && !defined(_WINDOWS_)
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 // we replace all path separators with this character
47 #define PATH_SEP_REPLACE '_'
49 // ============================================================================
51 // ============================================================================
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 wxIniConfig::wxIniConfig(const wxString
& strAppName
, const wxString
& strVendor
)
58 : m_strAppName(strAppName
), m_strVendor(strVendor
)
60 if ( strVendor
.IsEmpty() )
61 m_strVendor
= strAppName
;
63 // append the extension if none given and it's not an absolute file name
64 // (otherwise we assume that they know what they're doing)
65 if ( !wxIsPathSeparator(m_strAppName
[0u]) &&
66 m_strAppName
.Find('.') == NOT_FOUND
) {
67 m_strAppName
<< ".ini";
74 wxIniConfig::~wxIniConfig()
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 void wxIniConfig::SetPath(const wxString
& strPath
)
86 if ( strPath
.IsEmpty() ) {
89 else if ( strPath
[0u] == wxCONFIG_PATH_SEPARATOR
) {
91 wxSplitPath(aParts
, strPath
);
94 // relative path, combine with current one
95 wxString strFullPath
= GetPath();
96 strFullPath
<< wxCONFIG_PATH_SEPARATOR
<< strPath
;
97 wxSplitPath(aParts
, strFullPath
);
100 uint nPartsCount
= aParts
.Count();
102 if ( nPartsCount
== 0 ) {
104 m_strGroup
= PATH_SEP_REPLACE
;
108 m_strGroup
= aParts
[0u];
109 for ( uint nPart
= 1; nPart
< nPartsCount
; nPart
++ ) {
111 m_strPath
<< PATH_SEP_REPLACE
;
112 m_strPath
<< aParts
[nPart
];
116 // other functions assume that all this is true, i.e. there are no trailing
117 // underscores at the end except if the group is the root one
118 wxASSERT( (m_strPath
.IsEmpty() || m_strPath
.Last() != PATH_SEP_REPLACE
) &&
119 (m_strGroup
== PATH_SEP_REPLACE
||
120 m_strGroup
.Last() != PATH_SEP_REPLACE
) );
123 const wxString
& wxIniConfig::GetPath() const
125 static wxString s_str
;
127 // always return abs path
128 s_str
= wxCONFIG_PATH_SEPARATOR
;
130 if ( m_strGroup
== PATH_SEP_REPLACE
) {
131 // we're at the root level, nothing to do
135 if ( !m_strPath
.IsEmpty() )
136 s_str
<< wxCONFIG_PATH_SEPARATOR
;
137 for ( const char *p
= m_strPath
; *p
!= '\0'; p
++ ) {
138 s_str
<< (*p
== PATH_SEP_REPLACE
? wxCONFIG_PATH_SEPARATOR
: *p
);
145 wxString
wxIniConfig::GetPrivateKeyName(const char *szKey
) const
149 if ( !m_strPath
.IsEmpty() )
150 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
157 wxString
wxIniConfig::GetKeyName(const char *szKey
) const
161 if ( m_strGroup
!= PATH_SEP_REPLACE
)
162 strKey
<< m_strGroup
<< PATH_SEP_REPLACE
;
163 if ( !m_strPath
.IsEmpty() )
164 strKey
<< m_strPath
<< PATH_SEP_REPLACE
;
171 // ----------------------------------------------------------------------------
173 // ----------------------------------------------------------------------------
176 bool wxIniConfig::GetFirstGroup(wxString
& str
, long& lIndex
) const
178 wxFAIL_MSG("not implemented");
183 bool wxIniConfig::GetNextGroup (wxString
& str
, long& lIndex
) const
185 wxFAIL_MSG("not implemented");
190 bool wxIniConfig::GetFirstEntry(wxString
& str
, long& lIndex
) const
192 wxFAIL_MSG("not implemented");
197 bool wxIniConfig::GetNextEntry (wxString
& str
, long& lIndex
) const
199 wxFAIL_MSG("not implemented");
204 // ----------------------------------------------------------------------------
206 // ----------------------------------------------------------------------------
209 uint
wxIniConfig::GetNumberOfEntries(bool bRecursive
) const
211 wxFAIL_MSG("not implemented");
216 uint
wxIniConfig::GetNumberOfGroups(bool bRecursive
) const
218 wxFAIL_MSG("not implemented");
223 bool wxIniConfig::HasGroup(const wxString
& strName
) const
225 wxFAIL_MSG("not implemented");
230 bool wxIniConfig::HasEntry(const wxString
& strName
) const
232 wxFAIL_MSG("not implemented");
237 // is current group empty?
238 bool wxIniConfig::IsEmpty() const
242 GetPrivateProfileString(m_strGroup
, NULL
, "",
243 szBuf
, WXSIZEOF(szBuf
), m_strAppName
);
244 if ( !::IsEmpty(szBuf
) )
247 GetProfileString(m_strGroup
, NULL
, "", szBuf
, WXSIZEOF(szBuf
));
248 if ( !::IsEmpty(szBuf
) )
254 // ----------------------------------------------------------------------------
256 // ----------------------------------------------------------------------------
258 bool wxIniConfig::Read(wxString
*pstr
,
260 const char *szDefault
) const
262 PathChanger
path(this, szKey
);
263 wxString strKey
= GetPrivateKeyName(path
.Name());
265 char szBuf
[1024]; // @@ should dynamically allocate memory...
267 // first look in the private INI file
269 // NB: the lpDefault param to GetPrivateProfileString can't be NULL
270 GetPrivateProfileString(m_strGroup
, strKey
, "",
271 szBuf
, WXSIZEOF(szBuf
), m_strAppName
);
272 if ( ::IsEmpty(szBuf
) ) {
273 // now look in win.ini
274 wxString strKey
= GetKeyName(path
.Name());
275 GetProfileString(m_strGroup
, strKey
, "", szBuf
, WXSIZEOF(szBuf
));
278 if ( ::IsEmpty(szBuf
) ) {
287 const char *wxIniConfig::Read(const char *szKey
,
288 const char *szDefault
) const
290 static wxString s_str
;
291 Read(&s_str
, szKey
, szDefault
);
293 return s_str
.c_str();
296 bool wxIniConfig::Read(long *pl
, const char *szKey
, long lDefault
) const
298 PathChanger
path(this, szKey
);
299 wxString strKey
= GetPrivateKeyName(path
.Name());
301 // hack: we have no mean to know if it really found the default value or
302 // didn't find anything, so we call it twice
304 static const int nMagic
= 17; // 17 is some "rare" number
305 static const int nMagic2
= 28; // arbitrary number != nMagic
306 long lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic
, m_strAppName
);
307 if ( lVal
!= nMagic
) {
308 // the value was read from the file
313 // is it really nMagic?
314 lVal
= GetPrivateProfileInt(m_strGroup
, strKey
, nMagic2
, m_strAppName
);
315 if ( lVal
== nMagic
) {
316 // the nMagic it returned was indeed read from the file
321 // no, it was just returning the default value, so now look in win.ini
322 *pl
= GetProfileInt(m_strVendor
, GetKeyName(szKey
), lDefault
);
324 // we're not going to check here whether it read the default or not: it's
325 // not that important
329 long wxIniConfig::Read(const char *szKey
, long lDefault
) const
332 Read(&lVal
, szKey
, lDefault
);
337 bool wxIniConfig::Write(const char *szKey
, const char *szValue
)
339 PathChanger
path(this, szKey
);
340 wxString strKey
= GetPrivateKeyName(path
.Name());
342 bool bOk
= WritePrivateProfileString(m_strGroup
, strKey
,
343 szValue
, m_strAppName
) != 0;
346 wxLogLastError("WritePrivateProfileString");
351 bool wxIniConfig::Write(const char *szKey
, long lValue
)
353 // ltoa() is not ANSI :-(
354 char szBuf
[40]; // should be good for sizeof(long) <= 16 (128 bits)
355 sprintf(szBuf
, "%ld", lValue
);
357 return Write(szKey
, szBuf
);
360 bool wxIniConfig::Flush(bool /* bCurrentOnly */)
362 // this is just the way it works
363 return WritePrivateProfileString(NULL
, NULL
, NULL
, m_strAppName
) != 0;
366 // ----------------------------------------------------------------------------
368 // ----------------------------------------------------------------------------
370 bool wxIniConfig::DeleteEntry(const char *szKey
, bool bGroupIfEmptyAlso
)
372 // passing NULL as value to WritePrivateProfileString deletes the key
373 if ( !Write(szKey
, (const char *)NULL
) )
376 if ( !bGroupIfEmptyAlso
|| !IsEmpty() )
379 // delete the current group too
380 bool bOk
= WritePrivateProfileString(m_strGroup
, NULL
,
381 NULL
, m_strAppName
) != 0;
384 wxLogLastError("WritePrivateProfileString");
389 bool wxIniConfig::DeleteGroup(const char *szKey
)
391 PathChanger
path(this, szKey
);
393 // passing NULL as section name to WritePrivateProfileString deletes the
394 // whole section according to the docs
395 bool bOk
= WritePrivateProfileString(path
.Name(), NULL
,
396 NULL
, m_strAppName
) != 0;
399 wxLogLastError("WritePrivateProfileString");
404 bool wxIniConfig::DeleteAll()
406 // first delete our group in win.ini
407 WriteProfileString(m_strVendor
, NULL
, NULL
);
409 // then delete our own ini file
410 char szBuf
[MAX_PATH
];
411 uint nRc
= GetWindowsDirectory(szBuf
, WXSIZEOF(szBuf
));
413 wxLogLastError("GetWindowsDirectory");
414 else if ( nRc
> WXSIZEOF(szBuf
) )
415 wxFAIL_MSG("buffer is too small for Windows directory.");
417 wxString strFile
= szBuf
;
418 strFile
<< '\\' << m_strAppName
;
420 if ( !DeleteFile(strFile
) ) {
421 wxLogSysError(_("Can't delete the INI file '%s'"), strFile
.c_str());