📄 qsettings_win.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qsettings.h"#include <private/qsettings_p.h>#include "qt_windows.h"#include "qregexp.h"#ifndef QT_NO_SETTINGSstatic bool settingsTryUser = TRUE;static bool settingsTryLocal = TRUE;static QString *settingsBasePath = 0;void Q_EXPORT qt_setSettingsTryUser( bool tryUser ){ settingsTryUser = tryUser;}void Q_EXPORT qt_setSettingsTryLocal( bool tryLocal ){ settingsTryLocal = tryLocal;}void Q_EXPORT qt_setSettingsBasePath( const QString &base ){ if ( settingsBasePath ) { qWarning( "qt_setSettingsBasePath has to be called without any settings object being instantiated!" ); return; } settingsBasePath = new QString( base );}class QSettingsSysPrivate{public: QSettingsSysPrivate( QSettingsPrivate *priv ); ~QSettingsSysPrivate(); HKEY user; HKEY local; QString folder( const QString& ); QString entry( const QString& ); QString validateKey( const QString &key ); bool writeKey( const QString &key, const QByteArray &value, ulong type ); QByteArray readKey( const QString &key, ulong &type ); HKEY readKeyHelper( HKEY root, const QString &folder, const QString &entry, ulong &size ); HKEY openKey( const QString &key, bool write, bool remove = FALSE ); QStringList paths;private: QSettingsPrivate *d; static uint refCount;};uint QSettingsSysPrivate::refCount = 0;QSettingsSysPrivate::QSettingsSysPrivate( QSettingsPrivate *priv ) : d( priv ){ paths.append( "" ); if ( !settingsBasePath ) { settingsBasePath = new QString("Software"); } refCount++; local = 0; user = 0 ; LONG res; if ( settingsTryLocal ) { QT_WA( { res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, NULL, 0, KEY_ALL_ACCESS, &local ); } , { res = RegOpenKeyExA( HKEY_LOCAL_MACHINE, NULL, 0, KEY_ALL_ACCESS, &local ); } ); if ( res != ERROR_SUCCESS ) { QT_WA( { res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ, &local ); } , { res = RegOpenKeyExA( HKEY_LOCAL_MACHINE, NULL, 0, KEY_READ, &local ); } ); if ( res != ERROR_SUCCESS ) { local = NULL; } } } if ( settingsTryUser ) { QT_WA( { res = RegOpenKeyExW( HKEY_CURRENT_USER, NULL, 0, KEY_ALL_ACCESS, &user ); } , { res = RegOpenKeyExA( HKEY_CURRENT_USER, NULL, 0, KEY_ALL_ACCESS, &user ); } ); if ( res != ERROR_SUCCESS ) { QT_WA( { res = RegOpenKeyExW( HKEY_CURRENT_USER, NULL, 0, KEY_READ, &user ); } , { res = RegOpenKeyExA( HKEY_CURRENT_USER, NULL, 0, KEY_READ, &user ); } ); if ( res != ERROR_SUCCESS ) { user = NULL; } } }#if defined(QT_CHECK_STATE) if ( !local && !user ) qSystemWarning( "Error opening registry!", res );#endif}QSettingsSysPrivate::~QSettingsSysPrivate(){ LONG res; if ( local ) { res = RegCloseKey( local );#if defined(QT_CHECK_STATE) if ( res != ERROR_SUCCESS ) qSystemWarning( "Error closing local machine!", res );#endif } if ( user ) { res = RegCloseKey( user );#if defined(QT_CHECK_STATE) if ( res != ERROR_SUCCESS ) qSystemWarning( "Error closing current user!", res );#endif } // Make sure that we only delete the base path if no one else is using it anymore if (refCount > 0) { refCount--; if (refCount == 0) { delete settingsBasePath; settingsBasePath = 0; } }}QString QSettingsSysPrivate::validateKey( const QString &key ){ if ( key.isEmpty() ) return key; QString newKey = key; newKey = newKey.replace( QRegExp( "[/]+" ), "\\" ); if ( newKey[0] != '\\' ) newKey = "\\" + newKey; if ( newKey[(int)newKey.length() - 1] == '\\' ) newKey = newKey.left( newKey.length() - 1 ); return newKey;}QString QSettingsSysPrivate::folder( const QString &key ){ QString k = validateKey( key ); Q_ASSERT(settingsBasePath); return *settingsBasePath + k.left( k.findRev( "\\" ) );}QString QSettingsSysPrivate::entry( const QString &key ){ QString k = validateKey( key ); return k.right( k.length() - k.findRev( "\\" ) - 1 );}HKEY QSettingsSysPrivate::openKey( const QString &key, bool write, bool remove ){ QString f = folder( key ); HKEY handle = 0; LONG res = ERROR_FILE_NOT_FOUND; // if we write and there is a user specific setting, overwrite that if ( (write||remove) && user ) { QT_WA( { if ( remove ) res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_ALL_ACCESS, &handle ); else res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_WRITE, &handle ); } , { if ( remove ) res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_ALL_ACCESS, &handle ); else res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_WRITE, &handle ); } ); } wchar_t empty_t[] = L""; // workaround for Borland if ( res != ERROR_SUCCESS && local && d->globalScope ) { QT_WA( { if ( write && !remove ) res = RegCreateKeyExW( local, (TCHAR*)f.ucs2(), 0, empty_t, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL ); else if ( !write && !remove ) res = RegOpenKeyExW( local, (TCHAR*)f.ucs2(), 0, KEY_READ, &handle ); else res = RegOpenKeyExW( local, (TCHAR*)f.ucs2(), 0, KEY_ALL_ACCESS, &handle ); } , { if ( write && !remove ) res = RegCreateKeyExA( local, f.local8Bit(), 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL ); else if ( !write && !remove ) res = RegOpenKeyExA( local, f.local8Bit(), 0, KEY_READ, &handle ); else res = RegOpenKeyExA( local, f.local8Bit(), 0, KEY_ALL_ACCESS, &handle ); } ); } if ( !handle && user ) { QT_WA( { if ( write && !remove ) res = RegCreateKeyExW( user, (TCHAR*)f.ucs2(), 0, empty_t, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL ); else if ( !write && !remove ) res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_READ, &handle ); else res = RegOpenKeyExW( user, (TCHAR*)f.ucs2(), 0, KEY_ALL_ACCESS, &handle ); } , { if ( write && !remove ) res = RegCreateKeyExA( user, f.local8Bit(), 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &handle, NULL ); else if ( !write && !remove ) res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_READ, &handle ); else res = RegOpenKeyExA( user, f.local8Bit(), 0, KEY_ALL_ACCESS, &handle ); } ); } return handle;}bool QSettingsSysPrivate::writeKey( const QString &key, const QByteArray &value, ulong type ){ QString e; LONG res = ERROR_ACCESS_DENIED; HKEY handle = 0; for ( QStringList::Iterator it = paths.fromLast(); it != paths.end(); --it ) { QString k = *it + "/" + key; e = entry( k ); handle = openKey( k, TRUE ); if ( handle ) break; } if ( !handle ) return FALSE; if (e == "Default" || e == "." ) e = ""; if ( value.size() ) { QT_WA( { res = RegSetValueExW( handle, e.isEmpty() ? 0 : (TCHAR*)e.ucs2(), 0, type, (const uchar*)value.data(), value.size() ); } , { res = RegSetValueExA( handle, e.isEmpty() ? (const char*)0 : (const char*)e.local8Bit(), 0, type, (const uchar*)value.data(), value.size() ); } ); if ( res != ERROR_SUCCESS ) {#if defined(QT_CHECK_STATE) qSystemWarning( "Couldn't write value " + key, res );#endif return FALSE; } } RegCloseKey( handle ); return TRUE;}HKEY QSettingsSysPrivate::readKeyHelper( HKEY root, const QString &folder, const QString &entry, ulong &size ){ HKEY handle; LONG res = ERROR_ACCESS_DENIED; QT_WA( { res = RegOpenKeyExW( root, (TCHAR*)folder.ucs2(), 0, KEY_READ, &handle ); } , { res = RegOpenKeyExA( root, folder.local8Bit(), 0, KEY_READ, &handle ); } ); if ( res == ERROR_SUCCESS ) { QT_WA( { res = RegQueryValueExW( handle, entry.isEmpty() ? 0 : (TCHAR*)entry.ucs2(), NULL, NULL, NULL, &size ); } , { res = RegQueryValueExA( handle, entry.isEmpty() ? (const char*)0 : (const char*)entry.local8Bit(), NULL, NULL, NULL, &size ); } ); } if ( res != ERROR_SUCCESS ) { RegCloseKey( handle ); size = 0; handle = 0; } return handle;}QByteArray QSettingsSysPrivate::readKey( const QString &key, ulong &type ){ HKEY handle = 0; ulong size = 0; QString e; type = REG_NONE; if ( user ) { for ( QStringList::Iterator it = paths.fromLast(); it != paths.end(); --it ) { if ( handle ) { RegCloseKey( handle ); handle = 0; } QString k = *it + "/" + key; QString f = folder( k ); e = entry( k ); if ( e == "Default" || e == "." ) e = ""; handle = readKeyHelper( user, f, e, size ); if ( !handle ) size = 0; else if ( size ) break; } } if ( !size && local ) { for ( QStringList::Iterator it = paths.fromLast(); it != paths.end(); --it ) { if ( handle ) { RegCloseKey( handle ); handle = 0; } QString k = *it + "/" + key; QString f = folder( k ); e = entry( k ); if ( e == "Default" || e == "." ) e = ""; handle = readKeyHelper( local, f, e, size ); if ( !handle ) size = 0; else if ( size ) break; } } if ( !size ) { if ( handle ) RegCloseKey( handle ); return QByteArray(); } uchar* data = new uchar[ size ]; QT_WA( { RegQueryValueExW( handle, e.isEmpty() ? 0 : (TCHAR*)e.ucs2(), NULL, &type, data, &size );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -