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