Final MSW/PalmOS split. Remove dump copies of MSW specific code.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31115 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
82ef81ed9c
commit
b6ae016a1f
File diff suppressed because it is too large
Load Diff
@ -1,822 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: palmos/mimetype.cpp
|
||||
// Purpose: classes and functions to manage MIME types
|
||||
// Author: Vadim Zeitlin
|
||||
// Modified by:
|
||||
// Created: 23.09.98
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// Licence: wxWindows licence (part of wxExtra library)
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "mimetype.h"
|
||||
#endif
|
||||
|
||||
// for compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// This really doesn't apply to Palm OS
|
||||
#ifdef __WXPALMOS__
|
||||
|
||||
#if wxUSE_MIMETYPE
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/string.h"
|
||||
#if wxUSE_GUI
|
||||
#include "wx/icon.h"
|
||||
#include "wx/msgdlg.h"
|
||||
#endif
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
#include "wx/log.h"
|
||||
#include "wx/file.h"
|
||||
#include "wx/iconloc.h"
|
||||
#include "wx/intl.h"
|
||||
#include "wx/dynarray.h"
|
||||
#include "wx/confbase.h"
|
||||
|
||||
#include "wx/palmos/mimetype.h"
|
||||
|
||||
// other standard headers
|
||||
#include <ctype.h>
|
||||
|
||||
// in case we're compiling in non-GUI mode
|
||||
class WXDLLEXPORT wxIcon;
|
||||
|
||||
// These classes use Windows registry to retrieve the required information.
|
||||
//
|
||||
// Keys used (not all of them are documented, so it might actually stop working
|
||||
// in future versions of Windows...):
|
||||
// 1. "HKCR\MIME\Database\Content Type" contains subkeys for all known MIME
|
||||
// types, each key has a string value "Extension" which gives (dot preceded)
|
||||
// extension for the files of this MIME type.
|
||||
//
|
||||
// 2. "HKCR\.ext" contains
|
||||
// a) unnamed value containing the "filetype"
|
||||
// b) value "Content Type" containing the MIME type
|
||||
//
|
||||
// 3. "HKCR\filetype" contains
|
||||
// a) unnamed value containing the description
|
||||
// b) subkey "DefaultIcon" with single unnamed value giving the icon index in
|
||||
// an icon file
|
||||
// c) shell\open\command and shell\open\print subkeys containing the commands
|
||||
// to open/print the file (the positional parameters are introduced by %1,
|
||||
// %2, ... in these strings, we change them to %s ourselves)
|
||||
|
||||
// although I don't know of any official documentation which mentions this
|
||||
// location, uses it, so it isn't likely to change
|
||||
static const wxChar *MIME_DATABASE_KEY = wxT("MIME\\Database\\Content Type\\");
|
||||
|
||||
// this function replaces Microsoft %1 with Unix-like %s
|
||||
static bool CanonicalizeParams(wxString& command)
|
||||
{
|
||||
// transform it from '%1' to '%s' style format string (now also test for %L
|
||||
// as apparently MS started using it as well for the same purpose)
|
||||
|
||||
// NB: we don't make any attempt to verify that the string is valid, i.e.
|
||||
// doesn't contain %2, or second %1 or .... But we do make sure that we
|
||||
// return a string with _exactly_ one '%s'!
|
||||
bool foundFilename = false;
|
||||
size_t len = command.length();
|
||||
for ( size_t n = 0; (n < len) && !foundFilename; n++ )
|
||||
{
|
||||
if ( command[n] == wxT('%') &&
|
||||
(n + 1 < len) &&
|
||||
(command[n + 1] == wxT('1') || command[n + 1] == wxT('L')) )
|
||||
{
|
||||
// replace it with '%s'
|
||||
command[n + 1] = wxT('s');
|
||||
|
||||
foundFilename = true;
|
||||
}
|
||||
}
|
||||
|
||||
return foundFilename;
|
||||
}
|
||||
|
||||
void wxFileTypeImpl::Init(const wxString& strFileType, const wxString& ext)
|
||||
{
|
||||
// VZ: does it? (FIXME)
|
||||
wxCHECK_RET( !ext.empty(), _T("needs an extension") );
|
||||
|
||||
if ( ext[0u] != wxT('.') ) {
|
||||
m_ext = wxT('.');
|
||||
}
|
||||
m_ext << ext;
|
||||
|
||||
m_strFileType = strFileType;
|
||||
if ( !strFileType ) {
|
||||
m_strFileType = m_ext.AfterFirst('.') + _T("_auto_file");
|
||||
}
|
||||
}
|
||||
|
||||
wxString wxFileTypeImpl::GetVerbPath(const wxString& verb) const
|
||||
{
|
||||
wxString path;
|
||||
path << m_strFileType << _T("\\shell\\") << verb << _T("\\command");
|
||||
return path;
|
||||
}
|
||||
|
||||
size_t wxFileTypeImpl::GetAllCommands(wxArrayString *verbs,
|
||||
wxArrayString *commands,
|
||||
const wxFileType::MessageParameters& params) const
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty(), 0, _T("GetAllCommands() needs an extension") );
|
||||
|
||||
if ( m_strFileType.empty() )
|
||||
{
|
||||
// get it from the registry
|
||||
wxFileTypeImpl *self = wxConstCast(this, wxFileTypeImpl);
|
||||
wxRegKey rkey(wxRegKey::HKCR, m_ext);
|
||||
if ( !rkey.Exists() || !rkey.QueryValue(wxEmptyString, self->m_strFileType) )
|
||||
{
|
||||
wxLogDebug(_T("Can't get the filetype for extension '%s'."),
|
||||
m_ext.c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// enum all subkeys of HKCR\filetype\shell
|
||||
size_t count = 0;
|
||||
wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\shell"));
|
||||
long dummy;
|
||||
wxString verb;
|
||||
bool ok = rkey.GetFirstKey(verb, dummy);
|
||||
while ( ok )
|
||||
{
|
||||
wxString command = wxFileType::ExpandCommand(GetCommand(verb), params);
|
||||
|
||||
// we want the open bverb to eb always the first
|
||||
|
||||
if ( verb.CmpNoCase(_T("open")) == 0 )
|
||||
{
|
||||
if ( verbs )
|
||||
verbs->Insert(verb, 0);
|
||||
if ( commands )
|
||||
commands->Insert(command, 0);
|
||||
}
|
||||
else // anything else than "open"
|
||||
{
|
||||
if ( verbs )
|
||||
verbs->Add(verb);
|
||||
if ( commands )
|
||||
commands->Add(command);
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
ok = rkey.GetNextKey(verb, dummy);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// modify the registry database
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxFileTypeImpl::EnsureExtKeyExists()
|
||||
{
|
||||
wxRegKey rkey(wxRegKey::HKCR, m_ext);
|
||||
if ( !rkey.Exists() )
|
||||
{
|
||||
if ( !rkey.Create() || !rkey.SetValue(wxEmptyString, m_strFileType) )
|
||||
{
|
||||
wxLogError(_("Failed to create registry entry for '%s' files."),
|
||||
m_ext.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// get the command to use
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
|
||||
{
|
||||
// suppress possible error messages
|
||||
wxLogNull nolog;
|
||||
wxString strKey;
|
||||
|
||||
if ( wxRegKey(wxRegKey::HKCR, m_ext + _T("\\shell")).Exists() )
|
||||
strKey = m_ext;
|
||||
if ( wxRegKey(wxRegKey::HKCR, m_strFileType + _T("\\shell")).Exists() )
|
||||
strKey = m_strFileType;
|
||||
|
||||
if ( !strKey )
|
||||
{
|
||||
// no info
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
strKey << wxT("\\shell\\") << verb;
|
||||
wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command"));
|
||||
wxString command;
|
||||
if ( key.Open(wxRegKey::Read) ) {
|
||||
// it's the default value of the key
|
||||
if ( key.QueryValue(wxEmptyString, command) ) {
|
||||
bool foundFilename = CanonicalizeParams(command);
|
||||
|
||||
#if wxUSE_IPC
|
||||
// look whether we must issue some DDE requests to the application
|
||||
// (and not just launch it)
|
||||
strKey += _T("\\DDEExec");
|
||||
wxRegKey keyDDE(wxRegKey::HKCR, strKey);
|
||||
if ( keyDDE.Open(wxRegKey::Read) ) {
|
||||
wxString ddeCommand, ddeServer, ddeTopic;
|
||||
keyDDE.QueryValue(wxEmptyString, ddeCommand);
|
||||
ddeCommand.Replace(_T("%1"), _T("%s"));
|
||||
|
||||
wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")).
|
||||
QueryValue(wxEmptyString, ddeServer);
|
||||
wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")).
|
||||
QueryValue(wxEmptyString, ddeTopic);
|
||||
|
||||
if (ddeTopic.IsEmpty())
|
||||
ddeTopic = wxT("System");
|
||||
|
||||
// HACK: we use a special feature of wxExecute which exists
|
||||
// just because we need it here: it will establish DDE
|
||||
// conversation with the program it just launched
|
||||
command.Prepend(_T("WX_DDE#"));
|
||||
command << _T('#') << ddeServer
|
||||
<< _T('#') << ddeTopic
|
||||
<< _T('#') << ddeCommand;
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_IPC
|
||||
if ( !foundFilename )
|
||||
{
|
||||
// we didn't find any '%1' - the application doesn't know which
|
||||
// file to open (note that we only do it if there is no DDEExec
|
||||
// subkey)
|
||||
//
|
||||
// HACK: append the filename at the end, hope that it will do
|
||||
command << wxT(" %s");
|
||||
}
|
||||
}
|
||||
}
|
||||
//else: no such file type or no value, will return empty string
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
bool
|
||||
wxFileTypeImpl::GetOpenCommand(wxString *openCmd,
|
||||
const wxFileType::MessageParameters& params)
|
||||
const
|
||||
{
|
||||
wxString cmd = GetCommand(wxT("open"));
|
||||
|
||||
*openCmd = wxFileType::ExpandCommand(cmd, params);
|
||||
|
||||
return !openCmd->empty();
|
||||
}
|
||||
|
||||
bool
|
||||
wxFileTypeImpl::GetPrintCommand(wxString *printCmd,
|
||||
const wxFileType::MessageParameters& params)
|
||||
const
|
||||
{
|
||||
wxString cmd = GetCommand(wxT("print"));
|
||||
|
||||
*printCmd = wxFileType::ExpandCommand(cmd, params);
|
||||
|
||||
return !printCmd->empty();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// getting other stuff
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// TODO this function is half implemented
|
||||
bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
|
||||
{
|
||||
if ( m_ext.empty() ) {
|
||||
// the only way to get the list of extensions from the file type is to
|
||||
// scan through all extensions in the registry - too slow...
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
extensions.Empty();
|
||||
extensions.Add(m_ext);
|
||||
|
||||
// it's a lie too, we don't return _all_ extensions...
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
|
||||
{
|
||||
// suppress possible error messages
|
||||
wxLogNull nolog;
|
||||
wxRegKey key(wxRegKey::HKCR, m_ext);
|
||||
|
||||
return key.Open(wxRegKey::Read) &&
|
||||
key.QueryValue(wxT("Content Type"), *mimeType);
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
|
||||
{
|
||||
wxString s;
|
||||
|
||||
if ( !GetMimeType(&s) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mimeTypes.Clear();
|
||||
mimeTypes.Add(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool wxFileTypeImpl::GetIcon(wxIconLocation *iconLoc) const
|
||||
{
|
||||
wxString strIconKey;
|
||||
strIconKey << m_strFileType << wxT("\\DefaultIcon");
|
||||
|
||||
// suppress possible error messages
|
||||
wxLogNull nolog;
|
||||
wxRegKey key(wxRegKey::HKCR, strIconKey);
|
||||
|
||||
if ( key.Open(wxRegKey::Read) ) {
|
||||
wxString strIcon;
|
||||
// it's the default value of the key
|
||||
if ( key.QueryValue(wxEmptyString, strIcon) ) {
|
||||
// the format is the following: <full path to file>, <icon index>
|
||||
// NB: icon index may be negative as well as positive and the full
|
||||
// path may contain the environment variables inside '%'
|
||||
wxString strFullPath = strIcon.BeforeLast(wxT(',')),
|
||||
strIndex = strIcon.AfterLast(wxT(','));
|
||||
|
||||
// index may be omitted, in which case BeforeLast(',') is empty and
|
||||
// AfterLast(',') is the whole string
|
||||
if ( strFullPath.empty() ) {
|
||||
strFullPath = strIndex;
|
||||
strIndex = wxT("0");
|
||||
}
|
||||
|
||||
if ( iconLoc )
|
||||
{
|
||||
iconLoc->SetFileName(wxExpandEnvVars(strFullPath));
|
||||
|
||||
iconLoc->SetIndex(wxAtoi(strIndex));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// no such file type or no value or incorrect icon entry
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::GetDescription(wxString *desc) const
|
||||
{
|
||||
// suppress possible error messages
|
||||
wxLogNull nolog;
|
||||
wxRegKey key(wxRegKey::HKCR, m_strFileType);
|
||||
|
||||
if ( key.Open(wxRegKey::Read) ) {
|
||||
// it's the default value of the key
|
||||
if ( key.QueryValue(wxEmptyString, *desc) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// helper function
|
||||
wxFileType *
|
||||
wxMimeTypesManagerImpl::CreateFileType(const wxString& filetype, const wxString& ext)
|
||||
{
|
||||
wxFileType *fileType = new wxFileType;
|
||||
fileType->m_impl->Init(filetype, ext);
|
||||
return fileType;
|
||||
}
|
||||
|
||||
// extension -> file type
|
||||
wxFileType *
|
||||
wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
|
||||
{
|
||||
// add the leading point if necessary
|
||||
wxString str;
|
||||
if ( ext[0u] != wxT('.') ) {
|
||||
str = wxT('.');
|
||||
}
|
||||
str << ext;
|
||||
|
||||
// suppress possible error messages
|
||||
wxLogNull nolog;
|
||||
|
||||
bool knownExtension = false;
|
||||
|
||||
wxString strFileType;
|
||||
wxRegKey key(wxRegKey::HKCR, str);
|
||||
if ( key.Open(wxRegKey::Read) ) {
|
||||
// it's the default value of the key
|
||||
if ( key.QueryValue(wxEmptyString, strFileType) ) {
|
||||
// create the new wxFileType object
|
||||
return CreateFileType(strFileType, ext);
|
||||
}
|
||||
else {
|
||||
// this extension doesn't have a filetype, but it's known to the
|
||||
// system and may be has some other useful keys (open command or
|
||||
// content-type), so still return a file type object for it
|
||||
knownExtension = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !knownExtension )
|
||||
{
|
||||
// unknown extension
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return CreateFileType(wxEmptyString, ext);
|
||||
}
|
||||
|
||||
/*
|
||||
wxFileType *
|
||||
wxMimeTypesManagerImpl::GetOrAllocateFileTypeFromExtension(const wxString& ext)
|
||||
{
|
||||
wxFileType *fileType = GetFileTypeFromExtension(ext);
|
||||
if ( !fileType )
|
||||
{
|
||||
fileType = CreateFileType(wxEmptyString, ext);
|
||||
}
|
||||
|
||||
return fileType;
|
||||
}
|
||||
*/
|
||||
|
||||
// MIME type -> extension -> file type
|
||||
wxFileType *
|
||||
wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
|
||||
{
|
||||
wxString strKey = MIME_DATABASE_KEY;
|
||||
strKey << mimeType;
|
||||
|
||||
// suppress possible error messages
|
||||
wxLogNull nolog;
|
||||
|
||||
wxString ext;
|
||||
wxRegKey key(wxRegKey::HKCR, strKey);
|
||||
if ( key.Open(wxRegKey::Read) ) {
|
||||
if ( key.QueryValue(wxT("Extension"), ext) ) {
|
||||
return GetFileTypeFromExtension(ext);
|
||||
}
|
||||
}
|
||||
|
||||
// unknown MIME type
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
|
||||
{
|
||||
// enumerate all keys under MIME_DATABASE_KEY
|
||||
wxRegKey key(wxRegKey::HKCR, MIME_DATABASE_KEY);
|
||||
|
||||
wxString type;
|
||||
long cookie;
|
||||
bool cont = key.GetFirstKey(type, cookie);
|
||||
while ( cont )
|
||||
{
|
||||
mimetypes.Add(type);
|
||||
|
||||
cont = key.GetNextKey(type, cookie);
|
||||
}
|
||||
|
||||
return mimetypes.GetCount();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// create a new association
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxFileType *wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo)
|
||||
{
|
||||
wxCHECK_MSG( !ftInfo.GetExtensions().IsEmpty(), NULL,
|
||||
_T("Associate() needs extension") );
|
||||
|
||||
bool ok;
|
||||
int iExtCount = 0 ;
|
||||
wxString filetype;
|
||||
wxString extWithDot;
|
||||
|
||||
wxString ext = ftInfo.GetExtensions()[iExtCount];
|
||||
|
||||
wxCHECK_MSG( !ext.empty(), NULL,
|
||||
_T("Associate() needs non empty extension") );
|
||||
|
||||
if ( ext[0u] != _T('.') )
|
||||
extWithDot = _T('.');
|
||||
extWithDot += ext;
|
||||
|
||||
// start by setting the HKCR\\.ext entries
|
||||
// default is filetype; content type is mimetype
|
||||
const wxString& filetypeOrig = ftInfo.GetShortDesc();
|
||||
|
||||
wxRegKey key(wxRegKey::HKCR, extWithDot);
|
||||
if ( !key.Exists() )
|
||||
{
|
||||
// create the mapping from the extension to the filetype
|
||||
ok = key.Create();
|
||||
if ( ok )
|
||||
{
|
||||
|
||||
if ( filetypeOrig.empty() )
|
||||
{
|
||||
// make it up from the extension
|
||||
filetype << extWithDot.c_str() + 1 << _T("_file");
|
||||
}
|
||||
else
|
||||
{
|
||||
// just use the provided one
|
||||
filetype = filetypeOrig;
|
||||
}
|
||||
|
||||
key.SetValue(wxEmptyString, filetype);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// key already exists, maybe we want to change it ??
|
||||
if (!filetypeOrig.empty())
|
||||
{
|
||||
filetype = filetypeOrig;
|
||||
key.SetValue(wxEmptyString, filetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
key.QueryValue(wxEmptyString, filetype);
|
||||
}
|
||||
}
|
||||
// now set a mimetypeif we have it, but ignore it if none
|
||||
const wxString& mimetype = ftInfo.GetMimeType();
|
||||
if ( !mimetype.empty() )
|
||||
{
|
||||
// set the MIME type
|
||||
ok = key.SetValue(_T("Content Type"), mimetype);
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
// create the MIME key
|
||||
wxString strKey = MIME_DATABASE_KEY;
|
||||
strKey << mimetype;
|
||||
wxRegKey keyMIME(wxRegKey::HKCR, strKey);
|
||||
ok = keyMIME.Create();
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
// and provide a back link to the extension
|
||||
keyMIME.SetValue(_T("Extension"), extWithDot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now make other extensions have the same filetype
|
||||
|
||||
for (iExtCount=1; iExtCount < ftInfo.GetExtensionsCount(); iExtCount++ )
|
||||
{
|
||||
ext = ftInfo.GetExtensions()[iExtCount];
|
||||
if ( ext[0u] != _T('.') )
|
||||
extWithDot = _T('.');
|
||||
extWithDot += ext;
|
||||
|
||||
wxRegKey key(wxRegKey::HKCR, extWithDot);
|
||||
if ( !key.Exists() ) key.Create();
|
||||
key.SetValue(wxEmptyString, filetype);
|
||||
|
||||
// now set any mimetypes we may have, but ignore it if none
|
||||
const wxString& mimetype = ftInfo.GetMimeType();
|
||||
if ( !mimetype.empty() )
|
||||
{
|
||||
// set the MIME type
|
||||
ok = key.SetValue(_T("Content Type"), mimetype);
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
// create the MIME key
|
||||
wxString strKey = MIME_DATABASE_KEY;
|
||||
strKey << mimetype;
|
||||
wxRegKey keyMIME(wxRegKey::HKCR, strKey);
|
||||
ok = keyMIME.Create();
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
// and provide a back link to the extension
|
||||
keyMIME.SetValue(_T("Extension"), extWithDot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end of for loop; all extensions now point to HKCR\.ext\Default
|
||||
|
||||
// create the filetype key itself (it will be empty for now, but
|
||||
// SetCommand(), SetDefaultIcon() &c will use it later)
|
||||
wxRegKey keyFT(wxRegKey::HKCR, filetype);
|
||||
keyFT.Create();
|
||||
|
||||
wxFileType *ft = CreateFileType(filetype, extWithDot);
|
||||
|
||||
if (ft)
|
||||
{
|
||||
if (! ftInfo.GetOpenCommand ().IsEmpty() ) ft->SetCommand (ftInfo.GetOpenCommand (), wxT("open" ) );
|
||||
if (! ftInfo.GetPrintCommand().IsEmpty() ) ft->SetCommand (ftInfo.GetPrintCommand(), wxT("print" ) );
|
||||
// chris: I don't like the ->m_impl-> here FIX this ??
|
||||
if (! ftInfo.GetDescription ().IsEmpty() ) ft->m_impl->SetDescription (ftInfo.GetDescription ()) ;
|
||||
if (! ftInfo.GetIconFile().IsEmpty() ) ft->SetDefaultIcon (ftInfo.GetIconFile(), ftInfo.GetIconIndex() );
|
||||
|
||||
}
|
||||
return ft;
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::SetCommand(const wxString& cmd,
|
||||
const wxString& verb,
|
||||
bool WXUNUSED(overwriteprompt))
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty() && !verb.empty(), false,
|
||||
_T("SetCommand() needs an extension and a verb") );
|
||||
|
||||
if ( !EnsureExtKeyExists() )
|
||||
return false;
|
||||
|
||||
wxRegKey rkey(wxRegKey::HKCR, GetVerbPath(verb));
|
||||
#if 0
|
||||
if ( rkey.Exists() && overwriteprompt )
|
||||
{
|
||||
#if wxUSE_GUI
|
||||
wxString old;
|
||||
rkey.QueryValue(wxEmptyString, old);
|
||||
if ( wxMessageBox
|
||||
(
|
||||
wxString::Format(
|
||||
_("Do you want to overwrite the command used to %s "
|
||||
"files with extension \"%s\" ?\nCurrent value is \n%s, "
|
||||
"\nNew value is \n%s %1"), // bug here FIX need %1 ??
|
||||
verb.c_str(),
|
||||
m_ext.c_str(),
|
||||
old.c_str(),
|
||||
cmd.c_str()),
|
||||
_("Confirm registry update"),
|
||||
wxYES_NO | wxICON_QUESTION
|
||||
) != wxYES )
|
||||
#endif // wxUSE_GUI
|
||||
{
|
||||
// cancelled by user
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// TODO:
|
||||
// 1. translate '%s' to '%1' instead of always adding it
|
||||
// 2. create DDEExec value if needed (undo GetCommand)
|
||||
return rkey.Create() && rkey.SetValue(wxEmptyString, cmd + _T(" \"%1\"") );
|
||||
}
|
||||
|
||||
/* // no longer used
|
||||
bool wxFileTypeImpl::SetMimeType(const wxString& mimeTypeOrig)
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty(), false, _T("SetMimeType() needs extension") );
|
||||
|
||||
if ( !EnsureExtKeyExists() )
|
||||
return false;
|
||||
|
||||
// VZ: is this really useful? (FIXME)
|
||||
wxString mimeType;
|
||||
if ( !mimeTypeOrig )
|
||||
{
|
||||
// make up a default value for it
|
||||
wxString cmd;
|
||||
wxSplitPath(GetCommand(_T("open")), NULL, &cmd, NULL);
|
||||
mimeType << _T("application/x-") << cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
mimeType = mimeTypeOrig;
|
||||
}
|
||||
|
||||
wxRegKey rkey(wxRegKey::HKCR, m_ext);
|
||||
return rkey.Create() && rkey.SetValue(_T("Content Type"), mimeType);
|
||||
}
|
||||
*/
|
||||
|
||||
bool wxFileTypeImpl::SetDefaultIcon(const wxString& cmd, int index)
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty(), false, _T("SetDefaultIcon() needs extension") );
|
||||
wxCHECK_MSG( !m_strFileType.empty(), false, _T("File key not found") );
|
||||
// the next line fails on a SMBshare, I think because it is case mangled
|
||||
// wxCHECK_MSG( !wxFileExists(cmd), false, _T("Icon file not found.") );
|
||||
|
||||
if ( !EnsureExtKeyExists() )
|
||||
return false;
|
||||
|
||||
wxRegKey rkey(wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon"));
|
||||
|
||||
return rkey.Create() &&
|
||||
rkey.SetValue(wxEmptyString,
|
||||
wxString::Format(_T("%s,%d"), cmd.c_str(), index));
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::SetDescription (const wxString& desc)
|
||||
{
|
||||
wxCHECK_MSG( !m_strFileType.empty(), false, _T("File key not found") );
|
||||
wxCHECK_MSG( !desc.empty(), false, _T("No file description supplied") );
|
||||
|
||||
if ( !EnsureExtKeyExists() )
|
||||
return false;
|
||||
|
||||
wxRegKey rkey(wxRegKey::HKCR, m_strFileType );
|
||||
|
||||
return rkey.Create() &&
|
||||
rkey.SetValue(wxEmptyString, desc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// remove file association
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxFileTypeImpl::Unassociate()
|
||||
{
|
||||
bool result = true;
|
||||
if ( !RemoveOpenCommand() )
|
||||
result = false;
|
||||
if ( !RemoveDefaultIcon() )
|
||||
result = false;
|
||||
if ( !RemoveMimeType() )
|
||||
result = false;
|
||||
if ( !RemoveDescription() )
|
||||
result = false;
|
||||
|
||||
/*
|
||||
//this might hold other keys, eg some have CSLID keys
|
||||
if ( result )
|
||||
{
|
||||
// delete the root key
|
||||
wxRegKey key(wxRegKey::HKCR, m_ext);
|
||||
if ( key.Exists() )
|
||||
result = key.DeleteSelf();
|
||||
}
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::RemoveOpenCommand()
|
||||
{
|
||||
return RemoveCommand(_T("open"));
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::RemoveCommand(const wxString& verb)
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty() && !verb.empty(), false,
|
||||
_T("RemoveCommand() needs an extension and a verb") );
|
||||
|
||||
wxString sKey = m_strFileType;
|
||||
wxRegKey rkey(wxRegKey::HKCR, GetVerbPath(verb));
|
||||
|
||||
// if the key already doesn't exist, it's a success
|
||||
return !rkey.Exists() || rkey.DeleteSelf();
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::RemoveMimeType()
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty(), false, _T("RemoveMimeType() needs extension") );
|
||||
|
||||
wxRegKey rkey(wxRegKey::HKCR, m_ext);
|
||||
return !rkey.Exists() || rkey.DeleteSelf();
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::RemoveDefaultIcon()
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty(), false,
|
||||
_T("RemoveDefaultIcon() needs extension") );
|
||||
|
||||
wxRegKey rkey (wxRegKey::HKCR, m_strFileType + _T("\\DefaultIcon"));
|
||||
return !rkey.Exists() || rkey.DeleteSelf();
|
||||
}
|
||||
|
||||
bool wxFileTypeImpl::RemoveDescription()
|
||||
{
|
||||
wxCHECK_MSG( !m_ext.empty(), false,
|
||||
_T("RemoveDescription() needs extension") );
|
||||
|
||||
wxRegKey rkey (wxRegKey::HKCR, m_strFileType );
|
||||
return !rkey.Exists() || rkey.DeleteSelf();
|
||||
}
|
||||
|
||||
#endif // wxUSE_MIMETYPE
|
||||
#endif // __WXPALMOS__
|
@ -1,160 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: msw/mslu.cpp
|
||||
// Purpose: Fixes for bugs in MSLU
|
||||
// Author: Vaclav Slavik
|
||||
// Modified by:
|
||||
// Created: 2002/02/17
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2002 Vaclav Slavik
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
// This may or may not apply to Palm OS in the future, but for right now Unicode
|
||||
// is not supported.
|
||||
#ifndef __WXPALMOS__
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#include <dir.h>
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/defs.h"
|
||||
#endif
|
||||
|
||||
#if wxUSE_UNICODE_MSLU
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// NB: MSLU only covers Win32 API, it doesn't provide Unicode implementation of
|
||||
// libc functions. Unfortunately, some of MSVCRT wchar_t functions
|
||||
// (e.g. _wopen) don't work on Windows 9x, so we have to workaround it
|
||||
// by calling the char version. We still want to use wchar_t version on
|
||||
// NT/2000/XP, though, because they allow for Unicode file names.
|
||||
//
|
||||
// Moreover, there are bugs in unicows.dll, of course. We have to
|
||||
// workaround them, too.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/mslu.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef __VISUALC__
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
// Undef redirection macros defined in wx/msw/mslu.h:
|
||||
#undef DrawStateW
|
||||
#undef GetOpenFileNameW
|
||||
#undef GetSaveFileNameW
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Wrongly implemented functions from unicows.dll
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_GUI
|
||||
|
||||
WXDLLEXPORT int wxMSLU_DrawStateW(WXHDC dc, WXHBRUSH br, WXFARPROC outputFunc,
|
||||
WXLPARAM lData, WXWPARAM wData,
|
||||
int x, int y, int cx, int cy,
|
||||
unsigned int flags)
|
||||
{
|
||||
// VS: There's yet another bug in MSLU: DrawStateW behaves like if it was
|
||||
// expecting char*, not wchar_t* input. We have to use DrawStateA
|
||||
// explicitly.
|
||||
|
||||
if ( wxUsingUnicowsDll() )
|
||||
{
|
||||
return DrawStateA((HDC)dc, (HBRUSH)br, (DRAWSTATEPROC)outputFunc,
|
||||
(LPARAM)(const char*)
|
||||
wxConvLocal.cWX2MB((const wxChar*)lData),
|
||||
wData, x, y, cx, cy, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
return DrawStateW((HDC)dc, (HBRUSH)br, (DRAWSTATEPROC)outputFunc,
|
||||
lData, wData, x, y, cx, cy, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void wxFixOPENFILENAME(LPOPENFILENAME ofn)
|
||||
{
|
||||
#ifdef OFN_EXPLORER
|
||||
// VS: there's a bug in unicows.dll - when multiple files are selected,
|
||||
// of.nFileOffset doesn't point to the first filename but rather to
|
||||
// the last component of directory name. This bug is known to MSLU
|
||||
// developers, but they are not going to fix it: "this is a true
|
||||
// limitation, that we have decided to live with" and "working
|
||||
// harder on this case just did not seem worth the effort"...
|
||||
//
|
||||
// Our only option is to try to fix it ourselves:
|
||||
|
||||
if ( (ofn->Flags & OFN_ALLOWMULTISELECT) &&
|
||||
ofn->lpstrFile[ofn->nFileOffset-1] != wxT('\0') )
|
||||
{
|
||||
if ( wxDirExists(ofn->lpstrFile) )
|
||||
{
|
||||
// 1st component is dir => multiple files selected
|
||||
ofn->nFileOffset = wxStrlen(ofn->lpstrFile)+1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
WXDLLEXPORT int wxMSLU_GetOpenFileNameW(void *ofn)
|
||||
{
|
||||
int ret = GetOpenFileName((LPOPENFILENAME)ofn);
|
||||
if ( wxUsingUnicowsDll() && ret != 0 )
|
||||
wxFixOPENFILENAME((LPOPENFILENAME)ofn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
WXDLLEXPORT int wxMSLU_GetSaveFileNameW(void *ofn)
|
||||
{
|
||||
int ret = GetSaveFileName((LPOPENFILENAME)ofn);
|
||||
if ( wxUsingUnicowsDll() && ret != 0 )
|
||||
wxFixOPENFILENAME((LPOPENFILENAME)ofn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Missing libc file manipulation functions in Win9x
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_BASE
|
||||
|
||||
WXDLLEXPORT int wxMSLU__trename(const wxChar *oldname, const wxChar *newname)
|
||||
{
|
||||
if ( wxUsingUnicowsDll() )
|
||||
return rename(wxConvFile.cWX2MB(oldname), wxConvFile.cWX2MB(newname));
|
||||
else
|
||||
return _trename(oldname, newname);
|
||||
}
|
||||
|
||||
WXDLLEXPORT int wxMSLU__tremove(const wxChar *name)
|
||||
{
|
||||
if ( wxUsingUnicowsDll() )
|
||||
return remove(wxConvFile.cWX2MB(name));
|
||||
else
|
||||
return _tremove(name);
|
||||
}
|
||||
|
||||
#endif // wxUSE_BASE
|
||||
|
||||
#endif // wxUSE_UNICODE_MSLU
|
||||
|
||||
#endif // __WXPALMOS__
|
@ -1,975 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: palmos/registry.cpp
|
||||
// Purpose: implementation of registry classes and functions
|
||||
// Author: Vadim Zeitlin
|
||||
// Modified by:
|
||||
// Created: 03.04.98
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// Licence: wxWindows licence
|
||||
// TODO: - parsing of registry key names
|
||||
// - support of other (than REG_SZ/REG_DWORD) registry types
|
||||
// - add high level functions (RegisterOleServer, ...)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma implementation "registry.h"
|
||||
#endif
|
||||
|
||||
// for compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// This really doesn't apply to the Palm OS platform. It would be better to
|
||||
// support the Palm OS preference database instead.
|
||||
#ifndef __WXPALMOS__
|
||||
|
||||
// other wxWidgets headers
|
||||
#include "wx/string.h"
|
||||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
|
||||
#include "wx/palmos/wrapwin.h"
|
||||
|
||||
// other std headers
|
||||
#include <stdlib.h> // for _MAX_PATH
|
||||
|
||||
#ifndef _MAX_PATH
|
||||
#define _MAX_PATH 512
|
||||
#endif
|
||||
|
||||
// our header
|
||||
#define HKEY_DEFINED // already defined in windows.h
|
||||
#include "wx/palmos/registry.h"
|
||||
|
||||
// some registry functions don't like signed chars
|
||||
typedef unsigned char *RegString;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// the registry name separator (perhaps one day MS will change it to '/' ;-)
|
||||
#define REG_SEPARATOR wxT('\\')
|
||||
|
||||
// useful for Windows programmers: makes somewhat more clear all these zeroes
|
||||
// being passed to Windows APIs
|
||||
#define RESERVED (0)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// macros
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// const_cast<> is not yet supported by all compilers
|
||||
#define CONST_CAST ((wxRegKey *)this)->
|
||||
|
||||
// and neither is mutable which m_dwLastError should be
|
||||
#define m_dwLastError CONST_CAST m_dwLastError
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// non member functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// ============================================================================
|
||||
// implementation of wxRegKey class
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// static functions and variables
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const size_t wxRegKey::nStdKeys = WXSIZEOF(aStdKeys);
|
||||
|
||||
// @@ should take a `StdKey key', but as it's often going to be used in loops
|
||||
// it would require casts in user code.
|
||||
const wxChar *wxRegKey::GetStdKeyName(size_t key)
|
||||
{
|
||||
// return empty string if key is invalid
|
||||
wxCHECK_MSG( key < nStdKeys, wxEmptyString, wxT("invalid key in wxRegKey::GetStdKeyName") );
|
||||
|
||||
return aStdKeys[key].szName;
|
||||
}
|
||||
|
||||
const wxChar *wxRegKey::GetStdKeyShortName(size_t key)
|
||||
{
|
||||
// return empty string if key is invalid
|
||||
wxCHECK( key < nStdKeys, wxEmptyString );
|
||||
|
||||
return aStdKeys[key].szShortName;
|
||||
}
|
||||
|
||||
wxRegKey::StdKey wxRegKey::ExtractKeyName(wxString& strKey)
|
||||
{
|
||||
wxString strRoot = strKey.BeforeFirst(REG_SEPARATOR);
|
||||
|
||||
HKEY hRootKey = 0;
|
||||
size_t ui;
|
||||
for ( ui = 0; ui < nStdKeys; ui++ ) {
|
||||
if ( strRoot.CmpNoCase(aStdKeys[ui].szName) == 0 ||
|
||||
strRoot.CmpNoCase(aStdKeys[ui].szShortName) == 0 ) {
|
||||
hRootKey = aStdKeys[ui].hkey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ui == nStdKeys ) {
|
||||
wxFAIL_MSG(wxT("invalid key prefix in wxRegKey::ExtractKeyName."));
|
||||
|
||||
hRootKey = HKEY_CLASSES_ROOT;
|
||||
}
|
||||
else {
|
||||
strKey = strKey.After(REG_SEPARATOR);
|
||||
if ( !strKey.empty() && strKey.Last() == REG_SEPARATOR )
|
||||
strKey.Truncate(strKey.Len() - 1);
|
||||
}
|
||||
|
||||
return (wxRegKey::StdKey)(int)hRootKey;
|
||||
}
|
||||
|
||||
wxRegKey::StdKey wxRegKey::GetStdKeyFromHkey(WXHKEY hkey)
|
||||
{
|
||||
for ( size_t ui = 0; ui < nStdKeys; ui++ ) {
|
||||
if ( (int) aStdKeys[ui].hkey == (int) hkey )
|
||||
return (StdKey)ui;
|
||||
}
|
||||
|
||||
wxFAIL_MSG(wxT("non root hkey passed to wxRegKey::GetStdKeyFromHkey."));
|
||||
|
||||
return HKCR;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ctors and dtor
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxRegKey::wxRegKey()
|
||||
{
|
||||
m_hRootKey = (WXHKEY) aStdKeys[HKCR].hkey;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
wxRegKey::wxRegKey(const wxString& strKey) : m_strKey(strKey)
|
||||
{
|
||||
m_hRootKey = (WXHKEY) aStdKeys[ExtractKeyName(m_strKey)].hkey;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
// parent is a predefined (and preopened) key
|
||||
wxRegKey::wxRegKey(StdKey keyParent, const wxString& strKey) : m_strKey(strKey)
|
||||
{
|
||||
RemoveTrailingSeparator(m_strKey);
|
||||
m_hRootKey = (WXHKEY) aStdKeys[keyParent].hkey;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
// parent is a normal regkey
|
||||
wxRegKey::wxRegKey(const wxRegKey& keyParent, const wxString& strKey)
|
||||
: m_strKey(keyParent.m_strKey)
|
||||
{
|
||||
// combine our name with parent's to get the full name
|
||||
if ( !m_strKey.empty() &&
|
||||
(strKey.empty() || strKey[0] != REG_SEPARATOR) ) {
|
||||
m_strKey += REG_SEPARATOR;
|
||||
}
|
||||
|
||||
m_strKey += strKey;
|
||||
RemoveTrailingSeparator(m_strKey);
|
||||
|
||||
m_hRootKey = keyParent.m_hRootKey;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
// dtor closes the key releasing system resource
|
||||
wxRegKey::~wxRegKey()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// change the key name/hkey
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// set the full key name
|
||||
void wxRegKey::SetName(const wxString& strKey)
|
||||
{
|
||||
Close();
|
||||
|
||||
m_strKey = strKey;
|
||||
m_hRootKey = (WXHKEY) aStdKeys[ExtractKeyName(m_strKey)].hkey;
|
||||
}
|
||||
|
||||
// the name is relative to the parent key
|
||||
void wxRegKey::SetName(StdKey keyParent, const wxString& strKey)
|
||||
{
|
||||
Close();
|
||||
|
||||
m_strKey = strKey;
|
||||
RemoveTrailingSeparator(m_strKey);
|
||||
m_hRootKey = (WXHKEY) aStdKeys[keyParent].hkey;
|
||||
}
|
||||
|
||||
// the name is relative to the parent key
|
||||
void wxRegKey::SetName(const wxRegKey& keyParent, const wxString& strKey)
|
||||
{
|
||||
Close();
|
||||
|
||||
// combine our name with parent's to get the full name
|
||||
|
||||
// NB: this method is called by wxRegConfig::SetPath() which is a performance
|
||||
// critical function and so it preallocates space for our m_strKey to
|
||||
// gain some speed - this is why we only use += here and not = which
|
||||
// would just free the prealloc'd buffer and would have to realloc it the
|
||||
// next line!
|
||||
m_strKey.clear();
|
||||
m_strKey += keyParent.m_strKey;
|
||||
if ( !strKey.empty() && strKey[0] != REG_SEPARATOR )
|
||||
m_strKey += REG_SEPARATOR;
|
||||
m_strKey += strKey;
|
||||
|
||||
RemoveTrailingSeparator(m_strKey);
|
||||
|
||||
m_hRootKey = keyParent.m_hRootKey;
|
||||
}
|
||||
|
||||
// hKey should be opened and will be closed in wxRegKey dtor
|
||||
void wxRegKey::SetHkey(WXHKEY hKey)
|
||||
{
|
||||
Close();
|
||||
|
||||
m_hKey = hKey;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// info about the key
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// returns true if the key exists
|
||||
bool wxRegKey::Exists() const
|
||||
{
|
||||
// opened key has to exist, try to open it if not done yet
|
||||
return IsOpened() ? true : KeyExists(m_hRootKey, m_strKey);
|
||||
}
|
||||
|
||||
// returns the full name of the key (prefix is abbreviated if bShortPrefix)
|
||||
wxString wxRegKey::GetName(bool bShortPrefix) const
|
||||
{
|
||||
StdKey key = GetStdKeyFromHkey((WXHKEY) m_hRootKey);
|
||||
wxString str = bShortPrefix ? aStdKeys[key].szShortName
|
||||
: aStdKeys[key].szName;
|
||||
if ( !m_strKey.empty() )
|
||||
str << _T("\\") << m_strKey;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool wxRegKey::GetKeyInfo(size_t *pnSubKeys,
|
||||
size_t *pnMaxKeyLen,
|
||||
size_t *pnValues,
|
||||
size_t *pnMaxValueLen) const
|
||||
{
|
||||
// old gcc headers incorrectly prototype RegQueryInfoKey()
|
||||
#if defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__)
|
||||
#define REG_PARAM (size_t *)
|
||||
#else
|
||||
#define REG_PARAM (LPDWORD)
|
||||
#endif
|
||||
|
||||
// it might be unexpected to some that this function doesn't open the key
|
||||
wxASSERT_MSG( IsOpened(), _T("key should be opened in GetKeyInfo") );
|
||||
|
||||
m_dwLastError = ::RegQueryInfoKey
|
||||
(
|
||||
(HKEY) m_hKey,
|
||||
NULL, // class name
|
||||
NULL, // (ptr to) size of class name buffer
|
||||
RESERVED,
|
||||
REG_PARAM
|
||||
pnSubKeys, // [out] number of subkeys
|
||||
REG_PARAM
|
||||
pnMaxKeyLen, // [out] max length of a subkey name
|
||||
NULL, // longest subkey class name
|
||||
REG_PARAM
|
||||
pnValues, // [out] number of values
|
||||
REG_PARAM
|
||||
pnMaxValueLen, // [out] max length of a value name
|
||||
NULL, // longest value data
|
||||
NULL, // security descriptor
|
||||
NULL // time of last modification
|
||||
);
|
||||
|
||||
#undef REG_PARAM
|
||||
|
||||
if ( m_dwLastError != ERROR_SUCCESS ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't get info about registry key '%s'"),
|
||||
GetName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// operations
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// opens key (it's not an error to call Open() on an already opened key)
|
||||
bool wxRegKey::Open(AccessMode mode)
|
||||
{
|
||||
if ( IsOpened() )
|
||||
return true;
|
||||
|
||||
HKEY tmpKey;
|
||||
m_dwLastError = ::RegOpenKeyEx
|
||||
(
|
||||
(HKEY) m_hRootKey,
|
||||
m_strKey,
|
||||
RESERVED,
|
||||
mode == Read ? KEY_READ : KEY_ALL_ACCESS,
|
||||
&tmpKey
|
||||
);
|
||||
|
||||
if ( m_dwLastError != ERROR_SUCCESS )
|
||||
{
|
||||
wxLogSysError(m_dwLastError, _("Can't open registry key '%s'"),
|
||||
GetName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hKey = (WXHKEY) tmpKey;
|
||||
return true;
|
||||
}
|
||||
|
||||
// creates key, failing if it exists and !bOkIfExists
|
||||
bool wxRegKey::Create(bool bOkIfExists)
|
||||
{
|
||||
// check for existence only if asked (i.e. order is important!)
|
||||
if ( !bOkIfExists && Exists() )
|
||||
return false;
|
||||
|
||||
if ( IsOpened() )
|
||||
return true;
|
||||
|
||||
HKEY tmpKey;
|
||||
#ifdef __WXWINCE__
|
||||
DWORD disposition;
|
||||
m_dwLastError = RegCreateKeyEx((HKEY) m_hRootKey, m_strKey,
|
||||
NULL, // reserved
|
||||
NULL, // class string
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&tmpKey,
|
||||
&disposition);
|
||||
#else
|
||||
m_dwLastError = RegCreateKey((HKEY) m_hRootKey, m_strKey, &tmpKey);
|
||||
#endif
|
||||
if ( m_dwLastError != ERROR_SUCCESS ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't create registry key '%s'"),
|
||||
GetName().c_str());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hKey = (WXHKEY) tmpKey;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// close the key, it's not an error to call it when not opened
|
||||
bool wxRegKey::Close()
|
||||
{
|
||||
if ( IsOpened() ) {
|
||||
m_dwLastError = RegCloseKey((HKEY) m_hKey);
|
||||
m_hKey = 0;
|
||||
|
||||
if ( m_dwLastError != ERROR_SUCCESS ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't close registry key '%s'"),
|
||||
GetName().c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxRegKey::RenameValue(const wxChar *szValueOld, const wxChar *szValueNew)
|
||||
{
|
||||
bool ok = true;
|
||||
if ( HasValue(szValueNew) ) {
|
||||
wxLogError(_("Registry value '%s' already exists."), szValueNew);
|
||||
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if ( !ok ||
|
||||
!CopyValue(szValueOld, *this, szValueNew) ||
|
||||
!DeleteValue(szValueOld) ) {
|
||||
wxLogError(_("Failed to rename registry value '%s' to '%s'."),
|
||||
szValueOld, szValueNew);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxRegKey::CopyValue(const wxChar *szValue,
|
||||
wxRegKey& keyDst,
|
||||
const wxChar *szValueNew)
|
||||
{
|
||||
if ( !szValueNew ) {
|
||||
// by default, use the same name
|
||||
szValueNew = szValue;
|
||||
}
|
||||
|
||||
switch ( GetValueType(szValue) ) {
|
||||
case Type_String:
|
||||
{
|
||||
wxString strVal;
|
||||
return QueryValue(szValue, strVal) &&
|
||||
keyDst.SetValue(szValueNew, strVal);
|
||||
}
|
||||
|
||||
case Type_Dword:
|
||||
/* case Type_Dword_little_endian: == Type_Dword */
|
||||
{
|
||||
long dwVal;
|
||||
return QueryValue(szValue, &dwVal) &&
|
||||
keyDst.SetValue(szValueNew, dwVal);
|
||||
}
|
||||
|
||||
// these types are unsupported because I am not sure about how
|
||||
// exactly they should be copied and because they shouldn't
|
||||
// occur among the application keys (supposedly created with
|
||||
// this class)
|
||||
default:
|
||||
wxLogError(_("Can't copy values of unsupported type %d."),
|
||||
GetValueType(szValue));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool wxRegKey::Rename(const wxChar *szNewName)
|
||||
{
|
||||
wxCHECK_MSG( !!m_strKey, false, _T("registry hives can't be renamed") );
|
||||
|
||||
if ( !Exists() ) {
|
||||
wxLogError(_("Registry key '%s' does not exist, cannot rename it."),
|
||||
GetFullName(this));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// do we stay in the same hive?
|
||||
bool inSameHive = !wxStrchr(szNewName, REG_SEPARATOR);
|
||||
|
||||
// construct the full new name of the key
|
||||
wxRegKey keyDst;
|
||||
|
||||
if ( inSameHive ) {
|
||||
// rename the key to the new name under the same parent
|
||||
wxString strKey = m_strKey.BeforeLast(REG_SEPARATOR);
|
||||
if ( !!strKey ) {
|
||||
// don't add '\\' in the start if strFullNewName is empty
|
||||
strKey += REG_SEPARATOR;
|
||||
}
|
||||
|
||||
strKey += szNewName;
|
||||
|
||||
keyDst.SetName(GetStdKeyFromHkey(m_hRootKey), strKey);
|
||||
}
|
||||
else {
|
||||
// this is the full name already
|
||||
keyDst.SetName(szNewName);
|
||||
}
|
||||
|
||||
bool ok = keyDst.Create(false /* fail if alredy exists */);
|
||||
if ( !ok ) {
|
||||
wxLogError(_("Registry key '%s' already exists."),
|
||||
GetFullName(&keyDst));
|
||||
}
|
||||
else {
|
||||
ok = Copy(keyDst) && DeleteSelf();
|
||||
}
|
||||
|
||||
if ( !ok ) {
|
||||
wxLogError(_("Failed to rename the registry key '%s' to '%s'."),
|
||||
GetFullName(this), GetFullName(&keyDst));
|
||||
}
|
||||
else {
|
||||
m_hRootKey = keyDst.m_hRootKey;
|
||||
m_strKey = keyDst.m_strKey;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool wxRegKey::Copy(const wxChar *szNewName)
|
||||
{
|
||||
// create the new key first
|
||||
wxRegKey keyDst(szNewName);
|
||||
bool ok = keyDst.Create(false /* fail if alredy exists */);
|
||||
if ( ok ) {
|
||||
ok = Copy(keyDst);
|
||||
|
||||
// we created the dest key but copying to it failed - delete it
|
||||
if ( !ok ) {
|
||||
(void)keyDst.DeleteSelf();
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool wxRegKey::Copy(wxRegKey& keyDst)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
// copy all sub keys to the new location
|
||||
wxString strKey;
|
||||
long lIndex;
|
||||
bool bCont = GetFirstKey(strKey, lIndex);
|
||||
while ( ok && bCont ) {
|
||||
wxRegKey key(*this, strKey);
|
||||
wxString keyName;
|
||||
keyName << GetFullName(&keyDst) << REG_SEPARATOR << strKey;
|
||||
ok = key.Copy((const wxChar*) keyName);
|
||||
|
||||
if ( ok )
|
||||
bCont = GetNextKey(strKey, lIndex);
|
||||
}
|
||||
|
||||
// copy all values
|
||||
wxString strVal;
|
||||
bCont = GetFirstValue(strVal, lIndex);
|
||||
while ( ok && bCont ) {
|
||||
ok = CopyValue(strVal, keyDst);
|
||||
|
||||
if ( !ok ) {
|
||||
wxLogSysError(m_dwLastError,
|
||||
_("Failed to copy registry value '%s'"),
|
||||
strVal.c_str());
|
||||
}
|
||||
else {
|
||||
bCont = GetNextValue(strVal, lIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !ok ) {
|
||||
wxLogError(_("Failed to copy the contents of registry key '%s' to '%s'."), GetFullName(this), GetFullName(&keyDst));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// delete keys/values
|
||||
// ----------------------------------------------------------------------------
|
||||
bool wxRegKey::DeleteSelf()
|
||||
{
|
||||
{
|
||||
wxLogNull nolog;
|
||||
if ( !Open() ) {
|
||||
// it already doesn't exist - ok!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// prevent a buggy program from erasing one of the root registry keys or an
|
||||
// immediate subkey (i.e. one which doesn't have '\\' inside) of any other
|
||||
// key except HKCR (HKCR has some "deleteable" subkeys)
|
||||
if ( m_strKey.empty() ||
|
||||
((m_hRootKey != (WXHKEY) aStdKeys[HKCR].hkey) &&
|
||||
(m_strKey.Find(REG_SEPARATOR) == wxNOT_FOUND)) ) {
|
||||
wxLogError(_("Registry key '%s' is needed for normal system operation,\ndeleting it will leave your system in unusable state:\noperation aborted."), GetFullName(this));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// we can't delete keys while enumerating because it confuses GetNextKey, so
|
||||
// we first save the key names and then delete them all
|
||||
wxArrayString astrSubkeys;
|
||||
|
||||
wxString strKey;
|
||||
long lIndex;
|
||||
bool bCont = GetFirstKey(strKey, lIndex);
|
||||
while ( bCont ) {
|
||||
astrSubkeys.Add(strKey);
|
||||
|
||||
bCont = GetNextKey(strKey, lIndex);
|
||||
}
|
||||
|
||||
size_t nKeyCount = astrSubkeys.Count();
|
||||
for ( size_t nKey = 0; nKey < nKeyCount; nKey++ ) {
|
||||
wxRegKey key(*this, astrSubkeys[nKey]);
|
||||
if ( !key.DeleteSelf() )
|
||||
return false;
|
||||
}
|
||||
|
||||
// now delete this key itself
|
||||
Close();
|
||||
|
||||
m_dwLastError = RegDeleteKey((HKEY) m_hRootKey, m_strKey);
|
||||
// deleting a key which doesn't exist is not considered an error
|
||||
if ( m_dwLastError != ERROR_SUCCESS &&
|
||||
m_dwLastError != ERROR_FILE_NOT_FOUND ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't delete key '%s'"),
|
||||
GetName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxRegKey::DeleteKey(const wxChar *szKey)
|
||||
{
|
||||
if ( !Open() )
|
||||
return false;
|
||||
|
||||
wxRegKey key(*this, szKey);
|
||||
return key.DeleteSelf();
|
||||
}
|
||||
|
||||
bool wxRegKey::DeleteValue(const wxChar *szValue)
|
||||
{
|
||||
if ( !Open() )
|
||||
return false;
|
||||
|
||||
m_dwLastError = RegDeleteValue((HKEY) m_hKey, WXSTRINGCAST szValue);
|
||||
|
||||
// deleting a value which doesn't exist is not considered an error
|
||||
if ( (m_dwLastError != ERROR_SUCCESS) &&
|
||||
(m_dwLastError != ERROR_FILE_NOT_FOUND) ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't delete value '%s' from key '%s'"),
|
||||
szValue, GetName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// access to values and subkeys
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// return true if value exists
|
||||
bool wxRegKey::HasValue(const wxChar *szValue) const
|
||||
{
|
||||
// this function should be silent, so suppress possible messages from Open()
|
||||
wxLogNull nolog;
|
||||
|
||||
if ( !CONST_CAST Open() )
|
||||
return false;
|
||||
|
||||
LONG dwRet = ::RegQueryValueEx((HKEY) m_hKey,
|
||||
WXSTRINGCAST szValue,
|
||||
RESERVED,
|
||||
NULL, NULL, NULL);
|
||||
return dwRet == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// returns true if this key has any values
|
||||
bool wxRegKey::HasValues() const
|
||||
{
|
||||
// suppress possible messages from GetFirstValue()
|
||||
wxLogNull nolog;
|
||||
|
||||
// just call GetFirstValue with dummy parameters
|
||||
wxString str;
|
||||
long l;
|
||||
return CONST_CAST GetFirstValue(str, l);
|
||||
}
|
||||
|
||||
// returns true if this key has any subkeys
|
||||
bool wxRegKey::HasSubkeys() const
|
||||
{
|
||||
// suppress possible messages from GetFirstKey()
|
||||
wxLogNull nolog;
|
||||
|
||||
// just call GetFirstKey with dummy parameters
|
||||
wxString str;
|
||||
long l;
|
||||
return CONST_CAST GetFirstKey(str, l);
|
||||
}
|
||||
|
||||
// returns true if given subkey exists
|
||||
bool wxRegKey::HasSubKey(const wxChar *szKey) const
|
||||
{
|
||||
// this function should be silent, so suppress possible messages from Open()
|
||||
wxLogNull nolog;
|
||||
|
||||
if ( !CONST_CAST Open() )
|
||||
return false;
|
||||
|
||||
return KeyExists(m_hKey, szKey);
|
||||
}
|
||||
|
||||
wxRegKey::ValueType wxRegKey::GetValueType(const wxChar *szValue) const
|
||||
{
|
||||
if ( ! CONST_CAST Open() )
|
||||
return Type_None;
|
||||
|
||||
DWORD dwType;
|
||||
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
|
||||
&dwType, NULL, NULL);
|
||||
if ( m_dwLastError != ERROR_SUCCESS ) {
|
||||
wxLogSysError(m_dwLastError, _("Can't read value of key '%s'"),
|
||||
GetName().c_str());
|
||||
return Type_None;
|
||||
}
|
||||
|
||||
return (ValueType)dwType;
|
||||
}
|
||||
|
||||
bool wxRegKey::QueryValue(const wxChar *szValue,
|
||||
wxString& strValue,
|
||||
bool raw) const
|
||||
{
|
||||
if ( CONST_CAST Open() ) {
|
||||
|
||||
// first get the type and size of the data
|
||||
DWORD dwType, dwSize;
|
||||
m_dwLastError = RegQueryValueEx((HKEY) m_hKey, WXSTRINGCAST szValue, RESERVED,
|
||||
&dwType, NULL, &dwSize);
|
||||
if ( m_dwLastError == ERROR_SUCCESS ) {
|
||||
if ( !dwSize ) {
|
||||
// must treat this case specially as GetWriteBuf() doesn't like
|
||||
// being called with 0 size
|
||||
strValue.Empty();
|
||||
}
|
||||
else {
|
||||
m_dwLastError = RegQueryValueEx((HKEY) m_hKey,
|
||||
WXSTRINGCAST szValue,
|
||||
RESERVED,
|
||||
&dwType,
|
||||
(RegString)(wxChar*)wxStringBuffer(strValue, dwSize),
|
||||
&dwSize);
|
||||
|
||||
// expand the var expansions in the string unless disabled
|
||||
#ifndef __WXWINCE__
|
||||
if ( (dwType == REG_EXPAND_SZ) && !raw )
|
||||
{
|
||||
DWORD dwExpSize = ::ExpandEnvironmentStrings(strValue, NULL, 0);
|
||||
bool ok = dwExpSize != 0;
|
||||
if ( ok )
|
||||
{
|
||||
wxString strExpValue;
|
||||
ok = ::ExpandEnvironmentStrings
|
||||
(
|
||||
strValue,
|
||||
wxStringBuffer(strExpValue, dwExpSize),
|
||||
dwExpSize
|
||||
) != 0;
|
||||
strValue = strExpValue;
|
||||
}
|
||||
|
||||
if ( !ok )
|
||||
{
|
||||
wxLogLastError(_T("ExpandEnvironmentStrings"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// __WXWINCE__
|
||||
}
|
||||
|
||||
if ( m_dwLastError == ERROR_SUCCESS ) {
|
||||
// check that it was the right type
|
||||
wxASSERT_MSG( !IsNumericValue(szValue),
|
||||
wxT("Type mismatch in wxRegKey::QueryValue().") );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxLogSysError(m_dwLastError, _("Can't read value of '%s'"),
|
||||
GetFullName(this, szValue));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxRegKey::SetValue(const wxChar *szValue, const wxString& strValue)
|
||||
{
|
||||
if ( CONST_CAST Open() ) {
|
||||
m_dwLastError = RegSetValueEx((HKEY) m_hKey, szValue, (DWORD) RESERVED, REG_SZ,
|
||||
(RegString)strValue.c_str(),
|
||||
(strValue.Len() + 1)*sizeof(wxChar));
|
||||
if ( m_dwLastError == ERROR_SUCCESS )
|
||||
return true;
|
||||
}
|
||||
|
||||
wxLogSysError(m_dwLastError, _("Can't set value of '%s'"),
|
||||
GetFullName(this, szValue));
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString wxRegKey::QueryDefaultValue() const
|
||||
{
|
||||
wxString str;
|
||||
QueryValue(NULL, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// enumeration
|
||||
// NB: all these functions require an index variable which allows to have
|
||||
// several concurrently running indexations on the same key
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxRegKey::GetFirstValue(wxString& strValueName, long& lIndex)
|
||||
{
|
||||
if ( !Open() )
|
||||
return false;
|
||||
|
||||
lIndex = 0;
|
||||
return GetNextValue(strValueName, lIndex);
|
||||
}
|
||||
|
||||
bool wxRegKey::GetNextValue(wxString& strValueName, long& lIndex) const
|
||||
{
|
||||
wxASSERT( IsOpened() );
|
||||
|
||||
// are we already at the end of enumeration?
|
||||
if ( lIndex == -1 )
|
||||
return false;
|
||||
|
||||
wxChar szValueName[1024]; // @@ use RegQueryInfoKey...
|
||||
DWORD dwValueLen = WXSIZEOF(szValueName);
|
||||
|
||||
m_dwLastError = RegEnumValue((HKEY) m_hKey, lIndex++,
|
||||
szValueName, &dwValueLen,
|
||||
RESERVED,
|
||||
NULL, // [out] type
|
||||
NULL, // [out] buffer for value
|
||||
NULL); // [i/o] it's length
|
||||
|
||||
if ( m_dwLastError != ERROR_SUCCESS ) {
|
||||
if ( m_dwLastError == ERROR_NO_MORE_ITEMS ) {
|
||||
m_dwLastError = ERROR_SUCCESS;
|
||||
lIndex = -1;
|
||||
}
|
||||
else {
|
||||
wxLogSysError(m_dwLastError, _("Can't enumerate values of key '%s'"),
|
||||
GetName().c_str());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
strValueName = szValueName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxRegKey::GetFirstKey(wxString& strKeyName, long& lIndex)
|
||||
{
|
||||
if ( !Open() )
|
||||
return false;
|
||||
|
||||
lIndex = 0;
|
||||
return GetNextKey(strKeyName, lIndex);
|
||||
}
|
||||
|
||||
bool wxRegKey::GetNextKey(wxString& strKeyName, long& lIndex) const
|
||||
{
|
||||
wxASSERT( IsOpened() );
|
||||
|
||||
// are we already at the end of enumeration?
|
||||
if ( lIndex == -1 )
|
||||
return false;
|
||||
|
||||
wxChar szKeyName[_MAX_PATH + 1];
|
||||
|
||||
#ifdef __WXWINCE__
|
||||
DWORD sizeName = WXSIZEOF(szKeyName);
|
||||
m_dwLastError = RegEnumKeyEx((HKEY) m_hKey, lIndex++, szKeyName, & sizeName,
|
||||
0, NULL, NULL, NULL);
|
||||
#else
|
||||
m_dwLastError = RegEnumKey((HKEY) m_hKey, lIndex++, szKeyName, WXSIZEOF(szKeyName));
|
||||
#endif
|
||||
|
||||
if ( m_dwLastError != ERROR_SUCCESS ) {
|
||||
if ( m_dwLastError == ERROR_NO_MORE_ITEMS ) {
|
||||
m_dwLastError = ERROR_SUCCESS;
|
||||
lIndex = -1;
|
||||
}
|
||||
else {
|
||||
wxLogSysError(m_dwLastError, _("Can't enumerate subkeys of key '%s'"),
|
||||
GetName().c_str());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
strKeyName = szKeyName;
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true if the value contains a number (else it's some string)
|
||||
bool wxRegKey::IsNumericValue(const wxChar *szValue) const
|
||||
{
|
||||
ValueType type = GetValueType(szValue);
|
||||
switch ( type ) {
|
||||
case Type_Dword:
|
||||
/* case Type_Dword_little_endian: == Type_Dword */
|
||||
case Type_Dword_big_endian:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// implementation of global private functions
|
||||
// ============================================================================
|
||||
|
||||
bool KeyExists(WXHKEY hRootKey, const wxChar *szKey)
|
||||
{
|
||||
// don't close this key itself for the case of empty szKey!
|
||||
if ( wxIsEmpty(szKey) )
|
||||
return true;
|
||||
|
||||
HKEY hkeyDummy;
|
||||
if ( ::RegOpenKeyEx
|
||||
(
|
||||
(HKEY)hRootKey,
|
||||
szKey,
|
||||
RESERVED,
|
||||
KEY_READ, // we might not have enough rights for rw access
|
||||
&hkeyDummy
|
||||
) == ERROR_SUCCESS )
|
||||
{
|
||||
::RegCloseKey(hkeyDummy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const wxChar *GetFullName(const wxRegKey *pKey, const wxChar *szValue)
|
||||
{
|
||||
static wxString s_str;
|
||||
s_str = pKey->GetName();
|
||||
if ( !wxIsEmpty(szValue) )
|
||||
s_str << wxT("\\") << szValue;
|
||||
|
||||
return s_str.c_str();
|
||||
}
|
||||
|
||||
void RemoveTrailingSeparator(wxString& str)
|
||||
{
|
||||
if ( !str.empty() && str.Last() == REG_SEPARATOR )
|
||||
str.Truncate(str.Len() - 1);
|
||||
}
|
||||
|
||||
#endif //Palm OS
|
||||
|
@ -1,191 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: palmos/renderer.cpp
|
||||
// Purpose: implementation of wxRendererNative for Palm OS
|
||||
// Author: Vadim Zeitlin
|
||||
// Modified by:
|
||||
// Created: 20.07.2003
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
|
||||
// License: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// for compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// Palm OS doesn't really have a theme engine, so this is not needed.
|
||||
#ifndef __WXPALMOS__
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/string.h"
|
||||
#include "wx/window.h"
|
||||
#include "wx/dc.h"
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
#include "wx/splitter.h"
|
||||
#include "wx/renderer.h"
|
||||
|
||||
#include "wx/palmos/uxtheme.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxRendererMSW : public wxDelegateRendererNative
|
||||
{
|
||||
public:
|
||||
wxRendererMSW() { }
|
||||
|
||||
static wxRendererNative& Get();
|
||||
|
||||
private:
|
||||
DECLARE_NO_COPY_CLASS(wxRendererMSW)
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxRendererXP: wxRendererNative implementation for Windows XP and later
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxRendererXP : public wxDelegateRendererNative
|
||||
{
|
||||
public:
|
||||
wxRendererXP() : wxDelegateRendererNative(wxRendererMSW::Get()) { }
|
||||
|
||||
static wxRendererNative& Get();
|
||||
|
||||
virtual void DrawSplitterBorder(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int flags = 0);
|
||||
virtual void DrawSplitterSash(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxSize& size,
|
||||
wxCoord position,
|
||||
wxOrientation orient,
|
||||
int flags = 0);
|
||||
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
|
||||
|
||||
private:
|
||||
DECLARE_NO_COPY_CLASS(wxRendererXP)
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// wxRendererNative and wxRendererMSW implementation
|
||||
// ============================================================================
|
||||
|
||||
/* static */
|
||||
wxRendererNative& wxRendererNative::GetDefault()
|
||||
{
|
||||
wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
|
||||
return themeEngine && themeEngine->IsAppThemed() ? wxRendererXP::Get()
|
||||
: wxRendererMSW::Get();
|
||||
}
|
||||
|
||||
/* static */
|
||||
wxRendererNative& wxRendererMSW::Get()
|
||||
{
|
||||
static wxRendererMSW s_rendererMSW;
|
||||
|
||||
return s_rendererMSW;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxRendererXP implementation
|
||||
// ============================================================================
|
||||
|
||||
/* static */
|
||||
wxRendererNative& wxRendererXP::Get()
|
||||
{
|
||||
static wxRendererXP s_rendererXP;
|
||||
|
||||
return s_rendererXP;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// splitter drawing
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// the width of the sash: this is the same as used by Explorer...
|
||||
static const wxCoord SASH_WIDTH = 4;
|
||||
|
||||
wxSplitterRenderParams
|
||||
wxRendererXP::GetSplitterParams(const wxWindow * win)
|
||||
{
|
||||
if (win->GetWindowStyle() & wxSP_NO_XP_THEME)
|
||||
return m_rendererNative.GetSplitterParams(win);
|
||||
else
|
||||
return wxSplitterRenderParams(SASH_WIDTH, 0, false);
|
||||
}
|
||||
|
||||
void
|
||||
wxRendererXP::DrawSplitterBorder(wxWindow * win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int flags)
|
||||
{
|
||||
if (win->GetWindowStyle() & wxSP_NO_XP_THEME)
|
||||
{
|
||||
m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wxRendererXP::DrawSplitterSash(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxSize& size,
|
||||
wxCoord position,
|
||||
wxOrientation orient,
|
||||
int flags)
|
||||
{
|
||||
if (win->GetWindowStyle() & wxSP_NO_XP_THEME)
|
||||
{
|
||||
m_rendererNative.DrawSplitterSash(
|
||||
win, dc, size, position, orient, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
// I don't know if it is correct to use the rebar background for the
|
||||
// splitter but it least this works ok in the default theme
|
||||
wxUxThemeHandle hTheme(win, L"REBAR");
|
||||
if ( hTheme )
|
||||
{
|
||||
RECT rect;
|
||||
if ( orient == wxVERTICAL )
|
||||
{
|
||||
rect.left = position;
|
||||
rect.right = position + SASH_WIDTH;
|
||||
rect.top = 0;
|
||||
rect.bottom = size.y;
|
||||
}
|
||||
else // wxHORIZONTAL
|
||||
{
|
||||
rect.left = 0;
|
||||
rect.right = size.x;
|
||||
rect.top = position;
|
||||
rect.bottom = position + SASH_WIDTH;
|
||||
}
|
||||
|
||||
wxUxThemeEngine::Get()->DrawThemeBackground
|
||||
(
|
||||
(WXHTHEME)hTheme,
|
||||
dc.GetHDC(),
|
||||
3 /* RP_BAND */,
|
||||
0 /* no state */ ,
|
||||
&rect,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user