1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     XRC resources 
   4 // Author:      Vaclav Slavik 
   7 // Copyright:   (c) 2000 Vaclav Slavik 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  12 #pragma implementation "xmlres.h" 
  15 // For compilers that support precompilation, includes "wx.h". 
  16 #include "wx/wxprec.h" 
  28 #include "wx/dialog.h" 
  31 #include "wx/wfstream.h" 
  32 #include "wx/filesys.h" 
  33 #include "wx/filename.h" 
  36 #include "wx/tokenzr.h" 
  37 #include "wx/fontenum.h" 
  38 #include "wx/module.h" 
  39 #include "wx/bitmap.h" 
  41 #include "wx/fontmap.h" 
  42 #include "wx/artprov.h" 
  43 #include "wx/settings.h" 
  45 #include "wx/xml/xml.h" 
  46 #include "wx/xrc/xmlres.h" 
  48 #include "wx/arrimpl.cpp" 
  49 WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords
); 
  52 wxXmlResource 
*wxXmlResource::ms_instance 
= NULL
; 
  54 /*static*/ wxXmlResource 
*wxXmlResource::Get() 
  57         ms_instance 
= new wxXmlResource
; 
  61 /*static*/ wxXmlResource 
*wxXmlResource::Set(wxXmlResource 
*res
) 
  63     wxXmlResource 
*old 
= ms_instance
; 
  68 wxXmlResource::wxXmlResource(int flags
) 
  74 wxXmlResource::wxXmlResource(const wxString
& filemask
, int flags
) 
  81 wxXmlResource::~wxXmlResource() 
  88 wxString 
wxXmlResource::ConvertFileNameToURL(const wxString
& filename
) 
  90     wxString 
fnd(filename
); 
  92     // NB: as Load() and Unload() accept both filenames and URLs (should 
  93     //     probably be changed to filenames only, but embedded resources 
  94     //     currently rely on its ability to handle URLs - FIXME) we need to 
  95     //     determine whether found name is filename and not URL and this is the 
  96     //     fastest/simplest way to do it 
  97     if (wxFileName::FileExists(fnd
)) 
  99         // Make the name absolute filename, because the app may 
 100         // change working directory later: 
 105             fnd 
= fn
.GetFullPath(); 
 108         fnd 
= wxFileSystem::FileNameToURL(fnd
); 
 118 bool wxXmlResource::IsArchive(const wxString
& filename
) 
 120     const wxString fnd 
= filename
.Lower(); 
 122     return fnd
.Matches(wxT("*.zip")) || fnd
.Matches(wxT("*.xrs")); 
 125 #endif // wxUSE_FILESYSTEM 
 127 bool wxXmlResource::Load(const wxString
& filemask
) 
 130     wxXmlResourceDataRecord 
*drec
; 
 131     bool iswild 
= wxIsWild(filemask
); 
 136 #   define wxXmlFindFirst  fsys.FindFirst(filemask, wxFILE) 
 137 #   define wxXmlFindNext   fsys.FindNext() 
 139 #   define wxXmlFindFirst  wxFindFirstFile(filemask, wxFILE) 
 140 #   define wxXmlFindNext   wxFindNextFile() 
 143         fnd 
= wxXmlFindFirst
; 
 148         fnd 
= ConvertFileNameToURL(fnd
); 
 151         if ( IsArchive(fnd
) ) 
 153             rt 
= rt 
&& Load(fnd 
+ wxT("#zip:*.xrc")); 
 155         else // a single resource URL 
 156 #endif // wxUSE_FILESYSTEM 
 158             drec 
= new wxXmlResourceDataRecord
; 
 168 #   undef wxXmlFindFirst 
 169 #   undef wxXmlFindNext 
 170     return rt 
&& UpdateResources(); 
 173 bool wxXmlResource::Unload(const wxString
& filename
) 
 175     wxASSERT_MSG( !wxIsWild(filename
), 
 176                     _T("wildcards not supported by wxXmlResource::Unload()") ); 
 178     wxString fnd 
= ConvertFileNameToURL(filename
); 
 180     const bool isArchive 
= IsArchive(fnd
); 
 183 #endif // wxUSE_FILESYSTEM 
 185     bool unloaded 
= false; 
 186     const size_t count 
= m_data
.GetCount(); 
 187     for ( size_t i 
= 0; i 
< count
; i
++ ) 
 192             if ( m_data
[i
].File
.StartsWith(fnd
) ) 
 194             // don't break from the loop, we can have other matching files 
 196         else // a single resource URL 
 197 #endif // wxUSE_FILESYSTEM 
 199             if ( m_data
[i
].File 
== fnd 
) 
 204                 // no sense in continuing, there is only one file with this URL 
 214 IMPLEMENT_ABSTRACT_CLASS(wxXmlResourceHandler
, wxObject
) 
 216 void wxXmlResource::AddHandler(wxXmlResourceHandler 
*handler
) 
 218     m_handlers
.Append(handler
); 
 219     handler
->SetParentResource(this); 
 222 void wxXmlResource::InsertHandler(wxXmlResourceHandler 
*handler
) 
 224     m_handlers
.Insert(handler
); 
 225     handler
->SetParentResource(this); 
 230 void wxXmlResource::ClearHandlers() 
 232     WX_CLEAR_LIST(wxList
, m_handlers
); 
 236 wxMenu 
*wxXmlResource::LoadMenu(const wxString
& name
) 
 238     return (wxMenu
*)CreateResFromNode(FindResource(name
, wxT("wxMenu")), NULL
, NULL
); 
 243 wxMenuBar 
*wxXmlResource::LoadMenuBar(wxWindow 
*parent
, const wxString
& name
) 
 245     return (wxMenuBar
*)CreateResFromNode(FindResource(name
, wxT("wxMenuBar")), parent
, NULL
); 
 251 wxToolBar 
*wxXmlResource::LoadToolBar(wxWindow 
*parent
, const wxString
& name
) 
 253     return (wxToolBar
*)CreateResFromNode(FindResource(name
, wxT("wxToolBar")), parent
, NULL
); 
 258 wxDialog 
*wxXmlResource::LoadDialog(wxWindow 
*parent
, const wxString
& name
) 
 260     return (wxDialog
*)CreateResFromNode(FindResource(name
, wxT("wxDialog")), parent
, NULL
); 
 263 bool wxXmlResource::LoadDialog(wxDialog 
*dlg
, wxWindow 
*parent
, const wxString
& name
) 
 265     return CreateResFromNode(FindResource(name
, wxT("wxDialog")), parent
, dlg
) != NULL
; 
 270 wxPanel 
*wxXmlResource::LoadPanel(wxWindow 
*parent
, const wxString
& name
) 
 272     return (wxPanel
*)CreateResFromNode(FindResource(name
, wxT("wxPanel")), parent
, NULL
); 
 275 bool wxXmlResource::LoadPanel(wxPanel 
*panel
, wxWindow 
*parent
, const wxString
& name
) 
 277     return CreateResFromNode(FindResource(name
, wxT("wxPanel")), parent
, panel
) != NULL
; 
 280 wxFrame 
*wxXmlResource::LoadFrame(wxWindow
* parent
, const wxString
& name
) 
 282     return (wxFrame
*)CreateResFromNode(FindResource(name
, wxT("wxFrame")), parent
, NULL
); 
 285 bool wxXmlResource::LoadFrame(wxFrame
* frame
, wxWindow 
*parent
, const wxString
& name
) 
 287     return CreateResFromNode(FindResource(name
, wxT("wxFrame")), parent
, frame
) != NULL
; 
 290 wxBitmap 
wxXmlResource::LoadBitmap(const wxString
& name
) 
 292     wxBitmap 
*bmp 
= (wxBitmap
*)CreateResFromNode( 
 293                                FindResource(name
, wxT("wxBitmap")), NULL
, NULL
); 
 296     if (bmp
) { rt 
= *bmp
; delete bmp
; } 
 300 wxIcon 
wxXmlResource::LoadIcon(const wxString
& name
) 
 302     wxIcon 
*icon 
= (wxIcon
*)CreateResFromNode( 
 303                             FindResource(name
, wxT("wxIcon")), NULL
, NULL
); 
 306     if (icon
) { rt 
= *icon
; delete icon
; } 
 311 wxObject 
*wxXmlResource::LoadObject(wxWindow 
*parent
, const wxString
& name
, const wxString
& classname
) 
 313     return CreateResFromNode(FindResource(name
, classname
), parent
, NULL
); 
 316 bool wxXmlResource::LoadObject(wxObject 
*instance
, wxWindow 
*parent
, const wxString
& name
, const wxString
& classname
) 
 318     return CreateResFromNode(FindResource(name
, classname
), parent
, instance
) != NULL
; 
 322 bool wxXmlResource::AttachUnknownControl(const wxString
& name
, 
 323                                          wxWindow 
*control
, wxWindow 
*parent
) 
 326         parent 
= control
->GetParent(); 
 327     wxWindow 
*container 
= parent
->FindWindow(name 
+ wxT("_container")); 
 330         wxLogError(_("Cannot find container for unknown control '%s'."), name
.c_str()); 
 333     return control
->Reparent(container
); 
 337 static void ProcessPlatformProperty(wxXmlNode 
*node
) 
 342     wxXmlNode 
*c 
= node
->GetChildren(); 
 346         if (!c
->GetPropVal(wxT("platform"), &s
)) 
 350             wxStringTokenizer 
tkn(s
, wxT(" |")); 
 352             while (tkn
.HasMoreTokens()) 
 354                 s 
= tkn
.GetNextToken(); 
 356                 if (s 
== wxT("win")) isok 
= true; 
 358 #if defined(__MAC__) || defined(__APPLE__) 
 359                 if (s 
== wxT("mac")) isok 
= true; 
 360 #elif defined(__UNIX__) 
 361                 if (s 
== wxT("unix")) isok 
= true; 
 364                 if (s 
== wxT("os2")) isok 
= true; 
 374             ProcessPlatformProperty(c
); 
 379             wxXmlNode 
*c2 
= c
->GetNext(); 
 380             node
->RemoveChild(c
); 
 389 bool wxXmlResource::UpdateResources() 
 393 #   if wxUSE_FILESYSTEM 
 394     wxFSFile 
*file 
= NULL
; 
 399     wxString 
encoding(wxT("UTF-8")); 
 400 #if !wxUSE_UNICODE && wxUSE_INTL 
 401     if ( (GetFlags() & wxXRC_USE_LOCALE
) == 0 ) 
 403         // In case we are not using wxLocale to translate strings, convert the 
 404         // strings GUI's charset. This must not be done when wxXRC_USE_LOCALE 
 405         // is on, because it could break wxGetTranslation lookup. 
 406         encoding 
= wxLocale::GetSystemEncodingName(); 
 410     for (size_t i 
= 0; i 
< m_data
.GetCount(); i
++) 
 412         modif 
= (m_data
[i
].Doc 
== NULL
); 
 414         if (!modif 
&& !(m_flags 
& wxXRC_NO_RELOADING
)) 
 416 #           if wxUSE_FILESYSTEM 
 417             file 
= fsys
.OpenFile(m_data
[i
].File
); 
 418             modif 
= file 
&& file
->GetModificationTime() > m_data
[i
].Time
; 
 421                 wxLogError(_("Cannot open file '%s'."), m_data
[i
].File
.c_str()); 
 427             modif 
= wxDateTime(wxFileModificationTime(m_data
[i
].File
)) > m_data
[i
].Time
; 
 433             wxLogTrace(_T("xrc"), 
 434                        _T("opening file '%s'"), m_data
[i
].File
.c_str()); 
 436             wxInputStream 
*stream 
= NULL
; 
 438 #           if wxUSE_FILESYSTEM 
 439             file 
= fsys
.OpenFile(m_data
[i
].File
); 
 441                 stream 
= file
->GetStream(); 
 443             stream 
= new wxFileInputStream(m_data
[i
].File
); 
 448                 delete m_data
[i
].Doc
; 
 449                 m_data
[i
].Doc 
= new wxXmlDocument
; 
 451             if (!stream 
|| !m_data
[i
].Doc
->Load(*stream
, encoding
)) 
 453                 wxLogError(_("Cannot load resources from file '%s'."), 
 454                            m_data
[i
].File
.c_str()); 
 455                 wxDELETE(m_data
[i
].Doc
); 
 458             else if (m_data
[i
].Doc
->GetRoot()->GetName() != wxT("resource")) 
 460                 wxLogError(_("Invalid XRC resource '%s': doesn't have root node 'resource'."), m_data
[i
].File
.c_str()); 
 461                 wxDELETE(m_data
[i
].Doc
); 
 468                 wxString verstr 
= m_data
[i
].Doc
->GetRoot()->GetPropVal( 
 469                                       wxT("version"), wxT("0.0.0.0")); 
 470                 if (wxSscanf(verstr
.c_str(), wxT("%i.%i.%i.%i"), 
 471                     &v1
, &v2
, &v3
, &v4
) == 4) 
 472                     version 
= v1
*256*256*256+v2
*256*256+v3
*256+v4
; 
 477                 if (m_version 
!= version
) 
 479                     wxLogError(_("Resource files must have same version number!")); 
 483                 ProcessPlatformProperty(m_data
[i
].Doc
->GetRoot()); 
 485                 m_data
[i
].Time 
= file
->GetModificationTime(); 
 487                 m_data
[i
].Time 
= wxDateTime(wxFileModificationTime(m_data
[i
].File
)); 
 491 #           if wxUSE_FILESYSTEM 
 504 wxXmlNode 
*wxXmlResource::DoFindResource(wxXmlNode 
*parent
, 
 505                                          const wxString
& name
, 
 506                                          const wxString
& classname
, 
 512     // first search for match at the top-level nodes (as this is 
 513     // where the resource is most commonly looked for): 
 514     for (node 
= parent
->GetChildren(); node
; node 
= node
->GetNext()) 
 516         if ( node
->GetType() == wxXML_ELEMENT_NODE 
&& 
 517                  (node
->GetName() == wxT("object") || 
 518                   node
->GetName() == wxT("object_ref")) && 
 519              node
->GetPropVal(wxT("name"), &dummy
) && dummy 
== name 
) 
 521             wxString 
cls(node
->GetPropVal(wxT("class"), wxEmptyString
)); 
 522             if (!classname 
|| cls 
== classname
) 
 524             // object_ref may not have 'class' property: 
 525             if (cls
.empty() && node
->GetName() == wxT("object_ref")) 
 527                 wxString refName 
= node
->GetPropVal(wxT("ref"), wxEmptyString
); 
 530                 wxXmlNode
* refNode 
= FindResource(refName
, wxEmptyString
, true); 
 532                     refNode
->GetPropVal(wxT("class"), wxEmptyString
) == classname
) 
 541         for (node 
= parent
->GetChildren(); node
; node 
= node
->GetNext()) 
 543             if ( node
->GetType() == wxXML_ELEMENT_NODE 
&& 
 544                  (node
->GetName() == wxT("object") || 
 545                   node
->GetName() == wxT("object_ref")) ) 
 547                 wxXmlNode
* found 
= DoFindResource(node
, name
, classname
, true); 
 556 wxXmlNode 
*wxXmlResource::FindResource(const wxString
& name
, 
 557                                        const wxString
& classname
, 
 560     UpdateResources(); //ensure everything is up-to-date 
 563     for (size_t f 
= 0; f 
< m_data
.GetCount(); f
++) 
 565         if ( m_data
[f
].Doc 
== NULL 
|| m_data
[f
].Doc
->GetRoot() == NULL 
) 
 568         wxXmlNode
* found 
= DoFindResource(m_data
[f
].Doc
->GetRoot(), 
 569                                           name
, classname
, recursive
); 
 573             m_curFileSystem
.ChangePathTo(m_data
[f
].File
); 
 579     wxLogError(_("XRC resource '%s' (class '%s') not found!"), 
 580                name
.c_str(), classname
.c_str()); 
 584 static void MergeNodes(wxXmlNode
& dest
, wxXmlNode
& with
) 
 587     for (wxXmlProperty 
*prop 
= with
.GetProperties(); prop
; prop 
= prop
->GetNext()) 
 589         wxXmlProperty 
*dprop
; 
 590         for (dprop 
= dest
.GetProperties(); dprop
; dprop 
= dprop
->GetNext()) 
 593             if ( dprop
->GetName() == prop
->GetName() ) 
 595                 dprop
->SetValue(prop
->GetValue()); 
 601             dest
.AddProperty(prop
->GetName(), prop
->GetValue()); 
 604     // Merge child nodes: 
 605     for (wxXmlNode
* node 
= with
.GetChildren(); node
; node 
= node
->GetNext()) 
 607         wxString name 
= node
->GetPropVal(wxT("name"), wxEmptyString
); 
 610         for (dnode 
= dest
.GetChildren(); dnode
; dnode 
= dnode
->GetNext() ) 
 612             if ( dnode
->GetName() == node
->GetName() && 
 613                  dnode
->GetPropVal(wxT("name"), wxEmptyString
) == name 
&& 
 614                  dnode
->GetType() == node
->GetType() ) 
 616                 MergeNodes(*dnode
, *node
); 
 622             dest
.AddChild(new wxXmlNode(*node
)); 
 625     if ( dest
.GetType() == wxXML_TEXT_NODE 
&& with
.GetContent().Length() ) 
 626          dest
.SetContent(with
.GetContent()); 
 629 wxObject 
*wxXmlResource::CreateResFromNode(wxXmlNode 
*node
, wxObject 
*parent
, 
 631                                            wxXmlResourceHandler 
*handlerToUse
) 
 633     if (node 
== NULL
) return NULL
; 
 635     // handling of referenced resource 
 636     if ( node
->GetName() == wxT("object_ref") ) 
 638         wxString refName 
= node
->GetPropVal(wxT("ref"), wxEmptyString
); 
 639         wxXmlNode
* refNode 
= FindResource(refName
, wxEmptyString
, true); 
 643             wxLogError(_("Referenced object node with ref=\"%s\" not found!"), 
 648         wxXmlNode 
copy(*refNode
); 
 649         MergeNodes(copy
, *node
); 
 651         return CreateResFromNode(©
, parent
, instance
); 
 654     wxXmlResourceHandler 
*handler
; 
 658         if (handlerToUse
->CanHandle(node
)) 
 660             return handlerToUse
->CreateResource(node
, parent
, instance
); 
 663     else if (node
->GetName() == wxT("object")) 
 665         wxList::compatibility_iterator ND 
= m_handlers
.GetFirst(); 
 668             handler 
= (wxXmlResourceHandler
*)ND
->GetData(); 
 669             if (handler
->CanHandle(node
)) 
 671                 return handler
->CreateResource(node
, parent
, instance
); 
 677     wxLogError(_("No handler found for XML node '%s', class '%s'!"), 
 678                node
->GetName().c_str(), 
 679                node
->GetPropVal(wxT("class"), wxEmptyString
).c_str()); 
 684 #include "wx/listimpl.cpp" 
 685 WX_DECLARE_LIST(wxXmlSubclassFactory
, wxXmlSubclassFactoriesList
); 
 686 WX_DEFINE_LIST(wxXmlSubclassFactoriesList
); 
 688 wxXmlSubclassFactoriesList 
*wxXmlResource::ms_subclassFactories 
= NULL
; 
 690 /*static*/ void wxXmlResource::AddSubclassFactory(wxXmlSubclassFactory 
*factory
) 
 692     if (!ms_subclassFactories
) 
 694         ms_subclassFactories 
= new wxXmlSubclassFactoriesList
; 
 696     ms_subclassFactories
->Append(factory
); 
 699 class wxXmlSubclassFactoryCXX 
: public wxXmlSubclassFactory
 
 702     ~wxXmlSubclassFactoryCXX() {} 
 704     wxObject 
*Create(const wxString
& className
) 
 706         wxClassInfo
* classInfo 
= wxClassInfo::FindClass(className
); 
 709             return classInfo
->CreateObject(); 
 718 wxXmlResourceHandler::wxXmlResourceHandler() 
 719         : m_node(NULL
), m_parent(NULL
), m_instance(NULL
), 
 720           m_parentAsWindow(NULL
) 
 725 wxObject 
*wxXmlResourceHandler::CreateResource(wxXmlNode 
*node
, wxObject 
*parent
, wxObject 
*instance
) 
 727     wxXmlNode 
*myNode 
= m_node
; 
 728     wxString myClass 
= m_class
; 
 729     wxObject 
*myParent 
= m_parent
, *myInstance 
= m_instance
; 
 730     wxWindow 
*myParentAW 
= m_parentAsWindow
; 
 732     m_instance 
= instance
; 
 733     if (!m_instance 
&& node
->HasProp(wxT("subclass")) && 
 734         !(m_resource
->GetFlags() & wxXRC_NO_SUBCLASSING
)) 
 736         wxString subclass 
= node
->GetPropVal(wxT("subclass"), wxEmptyString
); 
 737         if (!subclass
.empty()) 
 739             for (wxXmlSubclassFactoriesList::compatibility_iterator i 
= wxXmlResource::ms_subclassFactories
->GetFirst(); 
 742                 m_instance 
= i
->GetData()->Create(subclass
); 
 749                 wxString name 
= node
->GetPropVal(wxT("name"), wxEmptyString
); 
 750                 wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"), 
 751                            subclass
.c_str(), name
.c_str()); 
 757     m_class 
= node
->GetPropVal(wxT("class"), wxEmptyString
); 
 759     m_parentAsWindow 
= wxDynamicCast(m_parent
, wxWindow
); 
 761     wxObject 
*returned 
= DoCreateResource(); 
 765     m_parent 
= myParent
; m_parentAsWindow 
= myParentAW
; 
 766     m_instance 
= myInstance
; 
 772 void wxXmlResourceHandler::AddStyle(const wxString
& name
, int value
) 
 774     m_styleNames
.Add(name
); 
 775     m_styleValues
.Add(value
); 
 780 void wxXmlResourceHandler::AddWindowStyles() 
 782     XRC_ADD_STYLE(wxCLIP_CHILDREN
); 
 783     XRC_ADD_STYLE(wxSIMPLE_BORDER
); 
 784     XRC_ADD_STYLE(wxSUNKEN_BORDER
); 
 785     XRC_ADD_STYLE(wxDOUBLE_BORDER
); 
 786     XRC_ADD_STYLE(wxRAISED_BORDER
); 
 787     XRC_ADD_STYLE(wxSTATIC_BORDER
); 
 788     XRC_ADD_STYLE(wxNO_BORDER
); 
 789     XRC_ADD_STYLE(wxTRANSPARENT_WINDOW
); 
 790     XRC_ADD_STYLE(wxWANTS_CHARS
); 
 791     XRC_ADD_STYLE(wxTAB_TRAVERSAL
); 
 792     XRC_ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE
); 
 793     XRC_ADD_STYLE(wxFULL_REPAINT_ON_RESIZE
); 
 794     XRC_ADD_STYLE(wxWS_EX_BLOCK_EVENTS
); 
 795     XRC_ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY
); 
 800 bool wxXmlResourceHandler::HasParam(const wxString
& param
) 
 802     return (GetParamNode(param
) != NULL
); 
 806 int wxXmlResourceHandler::GetStyle(const wxString
& param
, int defaults
) 
 808     wxString s 
= GetParamValue(param
); 
 810     if (!s
) return defaults
; 
 812     wxStringTokenizer 
tkn(s
, wxT("| \t\n"), wxTOKEN_STRTOK
); 
 816     while (tkn
.HasMoreTokens()) 
 818         fl 
= tkn
.GetNextToken(); 
 819         index 
= m_styleNames
.Index(fl
); 
 820         if (index 
!= wxNOT_FOUND
) 
 821             style 
|= m_styleValues
[index
]; 
 823             wxLogError(_("Unknown style flag ") + fl
); 
 830 wxString 
wxXmlResourceHandler::GetText(const wxString
& param
, bool translate
) 
 832     wxXmlNode 
*parNode 
= GetParamNode(param
); 
 833     wxString 
str1(GetNodeContent(parNode
)); 
 838     // VS: First version of XRC resources used $ instead of & (which is 
 839     //     illegal in XML), but later I realized that '_' fits this purpose 
 840     //     much better (because &File means "File with F underlined"). 
 841     if (m_resource
->CompareVersion(2,3,0,1) < 0) 
 846     for (dt 
= str1
.c_str(); *dt
; dt
++) 
 848         // Remap amp_char to &, map double amp_char to amp_char (for things 
 849         // like "&File..." -- this is illegal in XML, so we use "_File..."): 
 852             if ( *(++dt
) == amp_char 
) 
 855                 str2 
<< wxT('&') << *dt
; 
 857         // Remap \n to CR, \r to LF, \t to TAB, \\ to \: 
 858         else if (*dt 
== wxT('\\')) 
 874                     // "\\" wasn't translated to "\" prior to 2.5.3.0: 
 875                     if (m_resource
->CompareVersion(2,5,3,0) >= 0) 
 880                     // else fall-through to default: branch below 
 883                     str2 
<< wxT('\\') << *dt
; 
 889     if (m_resource
->GetFlags() & wxXRC_USE_LOCALE
) 
 891         if (translate 
&& parNode 
&& 
 892             parNode
->GetPropVal(wxT("translate"), wxEmptyString
) != wxT("0")) 
 894             return wxGetTranslation(str2
); 
 901             // The string is internally stored as UTF-8, we have to convert 
 902             // it into system's default encoding so that it can be displayed: 
 903             return wxString(str2
.mb_str(wxConvUTF8
), wxConvLocal
); 
 908     // If wxXRC_USE_LOCALE is not set, then the string is already in 
 909     // system's default encoding in ANSI build, so we don't have to 
 910     // do anything special here. 
 916 long wxXmlResourceHandler::GetLong(const wxString
& param
, long defaultv
) 
 919     wxString str1 
= GetParamValue(param
); 
 921     if (!str1
.ToLong(&value
)) 
 927 float wxXmlResourceHandler::GetFloat(const wxString
& param
, float defaultv
) 
 930     wxString str1 
= GetParamValue(param
); 
 933     const char *prevlocale 
= setlocale(LC_NUMERIC
, "C"); 
 936     if (!str1
.ToDouble(&value
)) 
 940     setlocale(LC_NUMERIC
, prevlocale
); 
 947 int wxXmlResourceHandler::GetID() 
 949     return wxXmlResource::GetXRCID(GetName()); 
 954 wxString 
wxXmlResourceHandler::GetName() 
 956     return m_node
->GetPropVal(wxT("name"), wxT("-1")); 
 961 bool wxXmlResourceHandler::GetBool(const wxString
& param
, bool defaultv
) 
 963     wxString v 
= GetParamValue(param
); 
 965     if (!v
) return defaultv
; 
 967     return (v 
== wxT("1")); 
 971 static wxColour 
GetSystemColour(const wxString
& name
) 
 975         #define SYSCLR(clr) \ 
 976             if (name == _T(#clr)) return wxSystemSettings::GetColour(clr); 
 977         SYSCLR(wxSYS_COLOUR_SCROLLBAR
) 
 978         SYSCLR(wxSYS_COLOUR_BACKGROUND
) 
 979         SYSCLR(wxSYS_COLOUR_DESKTOP
) 
 980         SYSCLR(wxSYS_COLOUR_ACTIVECAPTION
) 
 981         SYSCLR(wxSYS_COLOUR_INACTIVECAPTION
) 
 982         SYSCLR(wxSYS_COLOUR_MENU
) 
 983         SYSCLR(wxSYS_COLOUR_WINDOW
) 
 984         SYSCLR(wxSYS_COLOUR_WINDOWFRAME
) 
 985         SYSCLR(wxSYS_COLOUR_MENUTEXT
) 
 986         SYSCLR(wxSYS_COLOUR_WINDOWTEXT
) 
 987         SYSCLR(wxSYS_COLOUR_CAPTIONTEXT
) 
 988         SYSCLR(wxSYS_COLOUR_ACTIVEBORDER
) 
 989         SYSCLR(wxSYS_COLOUR_INACTIVEBORDER
) 
 990         SYSCLR(wxSYS_COLOUR_APPWORKSPACE
) 
 991         SYSCLR(wxSYS_COLOUR_HIGHLIGHT
) 
 992         SYSCLR(wxSYS_COLOUR_HIGHLIGHTTEXT
) 
 993         SYSCLR(wxSYS_COLOUR_BTNFACE
) 
 994         SYSCLR(wxSYS_COLOUR_3DFACE
) 
 995         SYSCLR(wxSYS_COLOUR_BTNSHADOW
) 
 996         SYSCLR(wxSYS_COLOUR_3DSHADOW
) 
 997         SYSCLR(wxSYS_COLOUR_GRAYTEXT
) 
 998         SYSCLR(wxSYS_COLOUR_BTNTEXT
) 
 999         SYSCLR(wxSYS_COLOUR_INACTIVECAPTIONTEXT
) 
1000         SYSCLR(wxSYS_COLOUR_BTNHIGHLIGHT
) 
1001         SYSCLR(wxSYS_COLOUR_BTNHILIGHT
) 
1002         SYSCLR(wxSYS_COLOUR_3DHIGHLIGHT
) 
1003         SYSCLR(wxSYS_COLOUR_3DHILIGHT
) 
1004         SYSCLR(wxSYS_COLOUR_3DDKSHADOW
) 
1005         SYSCLR(wxSYS_COLOUR_3DLIGHT
) 
1006         SYSCLR(wxSYS_COLOUR_INFOTEXT
) 
1007         SYSCLR(wxSYS_COLOUR_INFOBK
) 
1008         SYSCLR(wxSYS_COLOUR_LISTBOX
) 
1009         SYSCLR(wxSYS_COLOUR_HOTLIGHT
) 
1010         SYSCLR(wxSYS_COLOUR_GRADIENTACTIVECAPTION
) 
1011         SYSCLR(wxSYS_COLOUR_GRADIENTINACTIVECAPTION
) 
1012         SYSCLR(wxSYS_COLOUR_MENUHILIGHT
) 
1013         SYSCLR(wxSYS_COLOUR_MENUBAR
) 
1017     return wxNullColour
; 
1020 wxColour 
wxXmlResourceHandler::GetColour(const wxString
& param
) 
1022     wxString v 
= GetParamValue(param
); 
1024     // find colour using HTML syntax (#RRGGBB) 
1025     unsigned long tmp 
= 0; 
1027     if (v
.Length() != 7 || v
[0u] != wxT('#') || 
1028         wxSscanf(v
.c_str(), wxT("#%lX"), &tmp
) != 1) 
1030         // the colour doesn't use #RRGGBB format, check if it is symbolic 
1032         wxColour clr 
= GetSystemColour(v
); 
1036         wxLogError(_("XRC resource: Incorrect colour specification '%s' for property '%s'."), 
1037                    v
.c_str(), param
.c_str()); 
1038         return wxNullColour
; 
1041     return wxColour((unsigned char) ((tmp 
& 0xFF0000) >> 16) , 
1042                     (unsigned char) ((tmp 
& 0x00FF00) >> 8), 
1043                     (unsigned char) ((tmp 
& 0x0000FF))); 
1048 wxBitmap 
wxXmlResourceHandler::GetBitmap(const wxString
& param
, 
1049                                          const wxArtClient
& defaultArtClient
, 
1052     /* If the bitmap is specified as stock item, query wxArtProvider for it: */ 
1053     wxXmlNode 
*bmpNode 
= GetParamNode(param
); 
1056         wxString sid 
= bmpNode
->GetPropVal(wxT("stock_id"), wxEmptyString
); 
1059             wxString scl 
= bmpNode
->GetPropVal(wxT("stock_client"), wxEmptyString
); 
1061                 scl 
= defaultArtClient
; 
1063                 scl 
= wxART_MAKE_CLIENT_ID_FROM_STR(scl
); 
1066                 wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(sid
), 
1068             if ( stockArt
.Ok() ) 
1073     /* ...or load the bitmap from file: */ 
1074     wxString name 
= GetParamValue(param
); 
1075     if (name
.empty()) return wxNullBitmap
; 
1076 #if wxUSE_FILESYSTEM 
1077     wxFSFile 
*fsfile 
= GetCurFileSystem().OpenFile(name
); 
1080         wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), 
1082         return wxNullBitmap
; 
1084     wxImage 
img(*(fsfile
->GetStream())); 
1087     wxImage 
img(GetParamValue(wxT("bitmap"))); 
1092         wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), 
1094         return wxNullBitmap
; 
1096     if (!(size 
== wxDefaultSize
)) img
.Rescale(size
.x
, size
.y
); 
1097     return wxBitmap(img
); 
1103 wxIcon 
wxXmlResourceHandler::GetIcon(const wxString
& param
, 
1104                                      const wxArtClient
& defaultArtClient
, 
1108     icon
.CopyFromBitmap(GetBitmap(param
, defaultArtClient
, size
)); 
1114 wxXmlNode 
*wxXmlResourceHandler::GetParamNode(const wxString
& param
) 
1116     wxCHECK_MSG(m_node
, NULL
, wxT("You can't access handler data before it was initialized!")); 
1118     wxXmlNode 
*n 
= m_node
->GetChildren(); 
1122         if (n
->GetType() == wxXML_ELEMENT_NODE 
&& n
->GetName() == param
) 
1130 wxString 
wxXmlResourceHandler::GetNodeContent(wxXmlNode 
*node
) 
1132     wxXmlNode 
*n 
= node
; 
1133     if (n 
== NULL
) return wxEmptyString
; 
1134     n 
= n
->GetChildren(); 
1138         if (n
->GetType() == wxXML_TEXT_NODE 
|| 
1139             n
->GetType() == wxXML_CDATA_SECTION_NODE
) 
1140             return n
->GetContent(); 
1143     return wxEmptyString
; 
1148 wxString 
wxXmlResourceHandler::GetParamValue(const wxString
& param
) 
1151         return GetNodeContent(m_node
); 
1153         return GetNodeContent(GetParamNode(param
)); 
1158 wxSize 
wxXmlResourceHandler::GetSize(const wxString
& param
, 
1159                                      wxWindow 
*windowToUse
) 
1161     wxString s 
= GetParamValue(param
); 
1162     if (s
.empty()) s 
= wxT("-1,-1"); 
1166     is_dlg 
= s
[s
.Length()-1] == wxT('d'); 
1167     if (is_dlg
) s
.RemoveLast(); 
1169     if (!s
.BeforeFirst(wxT(',')).ToLong(&sx
) || 
1170         !s
.AfterLast(wxT(',')).ToLong(&sy
)) 
1172         wxLogError(_("Cannot parse coordinates from '%s'."), s
.c_str()); 
1173         return wxDefaultSize
; 
1180             return wxDLG_UNIT(windowToUse
, wxSize(sx
, sy
)); 
1182         else if (m_parentAsWindow
) 
1184             return wxDLG_UNIT(m_parentAsWindow
, wxSize(sx
, sy
)); 
1188             wxLogError(_("Cannot convert dialog units: dialog unknown.")); 
1189             return wxDefaultSize
; 
1193     return wxSize(sx
, sy
); 
1198 wxPoint 
wxXmlResourceHandler::GetPosition(const wxString
& param
) 
1200     wxSize sz 
= GetSize(param
); 
1201     return wxPoint(sz
.x
, sz
.y
); 
1206 wxCoord 
wxXmlResourceHandler::GetDimension(const wxString
& param
, 
1208                                            wxWindow 
*windowToUse
) 
1210     wxString s 
= GetParamValue(param
); 
1211     if (s
.empty()) return defaultv
; 
1215     is_dlg 
= s
[s
.Length()-1] == wxT('d'); 
1216     if (is_dlg
) s
.RemoveLast(); 
1220         wxLogError(_("Cannot parse dimension from '%s'."), s
.c_str()); 
1228             return wxDLG_UNIT(windowToUse
, wxSize(sx
, 0)).x
; 
1230         else if (m_parentAsWindow
) 
1232             return wxDLG_UNIT(m_parentAsWindow
, wxSize(sx
, 0)).x
; 
1236             wxLogError(_("Cannot convert dialog units: dialog unknown.")); 
1245 // Get system font index using indexname 
1246 static wxFont 
GetSystemFont(const wxString
& name
) 
1250         #define SYSFNT(fnt) \ 
1251             if (name == _T(#fnt)) return wxSystemSettings::GetFont(fnt); 
1252         SYSFNT(wxSYS_OEM_FIXED_FONT
) 
1253         SYSFNT(wxSYS_ANSI_FIXED_FONT
) 
1254         SYSFNT(wxSYS_ANSI_VAR_FONT
) 
1255         SYSFNT(wxSYS_SYSTEM_FONT
) 
1256         SYSFNT(wxSYS_DEVICE_DEFAULT_FONT
) 
1257         SYSFNT(wxSYS_DEFAULT_PALETTE
) 
1258         SYSFNT(wxSYS_SYSTEM_FIXED_FONT
) 
1259         SYSFNT(wxSYS_DEFAULT_GUI_FONT
) 
1266 wxFont 
wxXmlResourceHandler::GetFont(const wxString
& param
) 
1268     wxXmlNode 
*font_node 
= GetParamNode(param
); 
1269     if (font_node 
== NULL
) 
1271         wxLogError(_("Cannot find font node '%s'."), param
.c_str()); 
1275     wxXmlNode 
*oldnode 
= m_node
; 
1281     int isize 
= wxDEFAULT
; 
1282     bool hasSize 
= HasParam(wxT("size")); 
1284         isize 
= GetLong(wxT("size"), wxDEFAULT
); 
1287     int istyle 
= wxNORMAL
; 
1288     bool hasStyle 
= HasParam(wxT("style")); 
1291         wxString style 
= GetParamValue(wxT("style")); 
1292         if (style 
== wxT("italic")) 
1294         else if (style 
== wxT("slant")) 
1299     int iweight 
= wxNORMAL
; 
1300     bool hasWeight 
= HasParam(wxT("weight")); 
1303         wxString weight 
= GetParamValue(wxT("weight")); 
1304         if (weight 
== wxT("bold")) 
1306         else if (weight 
== wxT("light")) 
1311     bool hasUnderlined 
= HasParam(wxT("underlined")); 
1312     bool underlined 
= hasUnderlined 
? GetBool(wxT("underlined"), false) : false; 
1314     // family and facename 
1315     int ifamily 
= wxDEFAULT
; 
1316     bool hasFamily 
= HasParam(wxT("family")); 
1319         wxString family 
= GetParamValue(wxT("family")); 
1320              if (family 
== wxT("decorative")) ifamily 
= wxDECORATIVE
; 
1321         else if (family 
== wxT("roman")) ifamily 
= wxROMAN
; 
1322         else if (family 
== wxT("script")) ifamily 
= wxSCRIPT
; 
1323         else if (family 
== wxT("swiss")) ifamily 
= wxSWISS
; 
1324         else if (family 
== wxT("modern")) ifamily 
= wxMODERN
; 
1325         else if (family 
== wxT("teletype")) ifamily 
= wxTELETYPE
; 
1330     bool hasFacename 
= HasParam(wxT("face")); 
1333         wxString faces 
= GetParamValue(wxT("face")); 
1334         wxFontEnumerator enu
; 
1335         enu
.EnumerateFacenames(); 
1336         wxStringTokenizer 
tk(faces
, wxT(",")); 
1337         while (tk
.HasMoreTokens()) 
1339             int index 
= enu
.GetFacenames()->Index(tk
.GetNextToken(), false); 
1340             if (index 
!= wxNOT_FOUND
) 
1342                 facename 
= (*enu
.GetFacenames())[index
]; 
1349     wxFontEncoding enc 
= wxFONTENCODING_DEFAULT
; 
1350     bool hasEncoding 
= HasParam(wxT("encoding")); 
1353         wxString encoding 
= GetParamValue(wxT("encoding")); 
1354         wxFontMapper mapper
; 
1355         if (!encoding
.empty()) 
1356             enc 
= mapper
.CharsetToEncoding(encoding
); 
1357         if (enc 
== wxFONTENCODING_SYSTEM
) 
1358             enc 
= wxFONTENCODING_DEFAULT
; 
1361     // is this font based on a system font? 
1362     wxFont sysfont 
= GetSystemFont(GetParamValue(wxT("sysfont"))); 
1367             sysfont
.SetPointSize(isize
); 
1368         else if (HasParam(wxT("relativesize"))) 
1369             sysfont
.SetPointSize(int(sysfont
.GetPointSize() * 
1370                                      GetFloat(wxT("relativesize")))); 
1373             sysfont
.SetStyle(istyle
); 
1375             sysfont
.SetWeight(iweight
); 
1377             sysfont
.SetUnderlined(underlined
); 
1379             sysfont
.SetFamily(ifamily
); 
1381             sysfont
.SetFaceName(facename
); 
1383             sysfont
.SetDefaultEncoding(enc
); 
1390     return wxFont(isize
, ifamily
, istyle
, iweight
, 
1391                   underlined
, facename
, enc
); 
1395 void wxXmlResourceHandler::SetupWindow(wxWindow 
*wnd
) 
1397     //FIXME : add cursor 
1399     if (HasParam(wxT("exstyle"))) 
1400         // Have to OR it with existing style, since 
1401         // some implementations (e.g. wxGTK) use the extra style 
1403         wnd
->SetExtraStyle(wnd
->GetExtraStyle() | GetStyle(wxT("exstyle"))); 
1404     if (HasParam(wxT("bg"))) 
1405         wnd
->SetBackgroundColour(GetColour(wxT("bg"))); 
1406     if (HasParam(wxT("fg"))) 
1407         wnd
->SetForegroundColour(GetColour(wxT("fg"))); 
1408     if (GetBool(wxT("enabled"), 1) == 0) 
1410     if (GetBool(wxT("focused"), 0) == 1) 
1412     if (GetBool(wxT("hidden"), 0) == 1) 
1415     if (HasParam(wxT("tooltip"))) 
1416         wnd
->SetToolTip(GetText(wxT("tooltip"))); 
1418     if (HasParam(wxT("font"))) 
1419         wnd
->SetFont(GetFont()); 
1423 void wxXmlResourceHandler::CreateChildren(wxObject 
*parent
, bool this_hnd_only
) 
1425     wxXmlNode 
*n 
= m_node
->GetChildren(); 
1429         if (n
->GetType() == wxXML_ELEMENT_NODE 
&& 
1430            (n
->GetName() == wxT("object") || n
->GetName() == wxT("object_ref"))) 
1432             m_resource
->CreateResFromNode(n
, parent
, NULL
, 
1433                                           this_hnd_only 
? this : NULL
); 
1440 void wxXmlResourceHandler::CreateChildrenPrivately(wxObject 
*parent
, wxXmlNode 
*rootnode
) 
1443     if (rootnode 
== NULL
) root 
= m_node
; else root 
= rootnode
; 
1444     wxXmlNode 
*n 
= root
->GetChildren(); 
1448         if (n
->GetType() == wxXML_ELEMENT_NODE 
&& CanHandle(n
)) 
1450             CreateResource(n
, parent
, NULL
); 
1462 // --------------- XRCID implementation ----------------------------- 
1464 #define XRCID_TABLE_SIZE     1024 
1474 static XRCID_record 
*XRCID_Records
[XRCID_TABLE_SIZE
] = {NULL
}; 
1476 static int XRCID_Lookup(const wxChar 
*str_id
, int value_if_not_found 
= -2) 
1480     for (const wxChar 
*c 
= str_id
; *c 
!= wxT('\0'); c
++) index 
+= (int)*c
; 
1481     index 
%= XRCID_TABLE_SIZE
; 
1483     XRCID_record 
*oldrec 
= NULL
; 
1484     for (XRCID_record 
*rec 
= XRCID_Records
[index
]; rec
; rec 
= rec
->next
) 
1486         if (wxStrcmp(rec
->key
, str_id
) == 0) 
1493     XRCID_record 
**rec_var 
= (oldrec 
== NULL
) ? 
1494                               &XRCID_Records
[index
] : &oldrec
->next
; 
1495     *rec_var 
= new XRCID_record
; 
1496     (*rec_var
)->key 
= wxStrdup(str_id
); 
1497     (*rec_var
)->next 
= NULL
; 
1500     if (value_if_not_found 
!= -2) 
1501         (*rec_var
)->id 
= value_if_not_found
; 
1504         int asint 
= wxStrtol(str_id
, &end
, 10); 
1505         if (*str_id 
&& *end 
== 0) 
1507             // if str_id was integer, keep it verbosely: 
1508             (*rec_var
)->id 
= asint
; 
1512             (*rec_var
)->id 
= wxNewId(); 
1516     return (*rec_var
)->id
; 
1519 static void AddStdXRCID_Records(); 
1521 /*static*/ int wxXmlResource::GetXRCID(const wxChar 
*str_id
) 
1523     static bool s_stdIDsAdded 
= false; 
1525     if ( !s_stdIDsAdded 
) 
1527         s_stdIDsAdded 
= true; 
1528         AddStdXRCID_Records(); 
1531     return XRCID_Lookup(str_id
); 
1535 static void CleanXRCID_Record(XRCID_record 
*rec
) 
1539         CleanXRCID_Record(rec
->next
); 
1545 static void CleanXRCID_Records() 
1547     for (int i 
= 0; i 
< XRCID_TABLE_SIZE
; i
++) 
1549         CleanXRCID_Record(XRCID_Records
[i
]); 
1550         XRCID_Records
[i
] = NULL
; 
1554 static void AddStdXRCID_Records() 
1556 #define stdID(id) XRCID_Lookup(wxT(#id), id) 
1560     stdID(wxID_SEPARATOR
); 
1573     stdID(wxID_PRINT_SETUP
); 
1574     stdID(wxID_PREVIEW
); 
1576     stdID(wxID_HELP_CONTENTS
); 
1577     stdID(wxID_HELP_COMMANDS
); 
1578     stdID(wxID_HELP_PROCEDURES
); 
1579     stdID(wxID_HELP_CONTEXT
); 
1580     stdID(wxID_CLOSE_ALL
); 
1581     stdID(wxID_PREFERENCES
); 
1587     stdID(wxID_DUPLICATE
); 
1588     stdID(wxID_SELECTALL
); 
1590     stdID(wxID_REPLACE
); 
1591     stdID(wxID_REPLACE_ALL
); 
1592     stdID(wxID_PROPERTIES
); 
1593     stdID(wxID_VIEW_DETAILS
); 
1594     stdID(wxID_VIEW_LARGEICONS
); 
1595     stdID(wxID_VIEW_SMALLICONS
); 
1596     stdID(wxID_VIEW_LIST
); 
1597     stdID(wxID_VIEW_SORTDATE
); 
1598     stdID(wxID_VIEW_SORTNAME
); 
1599     stdID(wxID_VIEW_SORTSIZE
); 
1600     stdID(wxID_VIEW_SORTTYPE
); 
1616     stdID(wxID_FORWARD
); 
1617     stdID(wxID_BACKWARD
); 
1618     stdID(wxID_DEFAULT
); 
1622     stdID(wxID_CONTEXT_HELP
); 
1623     stdID(wxID_YESTOALL
); 
1624     stdID(wxID_NOTOALL
); 
1633     stdID(wxID_REFRESH
); 
1638     stdID(wxID_JUSTIFY_CENTER
); 
1639     stdID(wxID_JUSTIFY_FILL
); 
1640     stdID(wxID_JUSTIFY_RIGHT
); 
1641     stdID(wxID_JUSTIFY_LEFT
); 
1642     stdID(wxID_UNDERLINE
); 
1644     stdID(wxID_UNINDENT
); 
1645     stdID(wxID_ZOOM_100
); 
1646     stdID(wxID_ZOOM_FIT
); 
1647     stdID(wxID_ZOOM_IN
); 
1648     stdID(wxID_ZOOM_OUT
); 
1649     stdID(wxID_UNDELETE
); 
1650     stdID(wxID_REVERT_TO_SAVED
); 
1651     stdID(wxID_SYSTEM_MENU
); 
1652     stdID(wxID_CLOSE_FRAME
); 
1653     stdID(wxID_MOVE_FRAME
); 
1654     stdID(wxID_RESIZE_FRAME
); 
1655     stdID(wxID_MAXIMIZE_FRAME
); 
1656     stdID(wxID_ICONIZE_FRAME
); 
1657     stdID(wxID_RESTORE_FRAME
); 
1666 // --------------- module and globals ----------------------------- 
1668 class wxXmlResourceModule
: public wxModule
 
1670 DECLARE_DYNAMIC_CLASS(wxXmlResourceModule
) 
1672     wxXmlResourceModule() {} 
1675         wxXmlResource::AddSubclassFactory(new wxXmlSubclassFactoryCXX
); 
1680         delete wxXmlResource::Set(NULL
); 
1681         if(wxXmlResource::ms_subclassFactories
) 
1682             WX_CLEAR_LIST(wxXmlSubclassFactoriesList
, *wxXmlResource::ms_subclassFactories
); 
1683         wxDELETE(wxXmlResource::ms_subclassFactories
); 
1684         CleanXRCID_Records(); 
1688 IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule
, wxModule
) 
1691 // When wxXml is loaded dynamically after the application is already running 
1692 // then the built-in module system won't pick this one up.  Add it manually. 
1693 void wxXmlInitResourceModule() 
1695     wxModule
* module = new wxXmlResourceModule
; 
1697     wxModule::RegisterModule(module);