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:
Włodzimierz Skiba 2004-12-22 07:35:19 +00:00
parent 82ef81ed9c
commit b6ae016a1f
5 changed files with 0 additions and 3438 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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