]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/xml/xmlres.cpp
fixed creation of toolbars under MSW
[wxWidgets.git] / contrib / src / xml / xmlres.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: xmlres.cpp
3 // Purpose: XML resources
4 // Author: Vaclav Slavik
5 // Created: 2000/03/05
6 // RCS-ID: $Id$
7 // Copyright: (c) 2000 Vaclav Slavik
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "xmlres.h"
13 #endif
14
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
17
18 #ifdef __BORLANDC__
19 #pragma hdrstop
20 #endif
21
22 #include "wx/dialog.h"
23 #include "wx/panel.h"
24 #include "wx/wfstream.h"
25 #include "wx/filesys.h"
26 #include "wx/log.h"
27 #include "wx/intl.h"
28 #include "wx/tokenzr.h"
29 #include "wx/module.h"
30 #include "wx/bitmap.h"
31 #include "wx/image.h"
32
33 #include "wx/xml/xml.h"
34 #include "wx/xml/xmlres.h"
35
36 #include "wx/arrimpl.cpp"
37 WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords);
38
39
40 wxXmlResource::wxXmlResource()
41 {
42 m_Handlers.DeleteContents(TRUE);
43 }
44
45 wxXmlResource::wxXmlResource(const wxString& filemask)
46 {
47 m_Handlers.DeleteContents(TRUE);
48 Load(filemask);
49 }
50
51 wxXmlResource::~wxXmlResource()
52 {
53 ClearHandlers();
54 }
55
56
57 bool wxXmlResource::Load(const wxString& filemask)
58 {
59 wxString fnd;
60 wxXmlResourceDataRecord *drec;
61 bool iswild = wxIsWild(filemask);
62
63 #if wxUSE_FILESYSTEM
64 wxFileSystem fsys;
65 # define wxXmlFindFirst fsys.FindFirst(filemask, wxFILE)
66 # define wxXmlFindNext fsys.FindNext()
67 #else
68 # define wxXmlFindFirst wxFindFirstFile(filemask, wxFILE)
69 # define wxXmlFindNext wxFindNextFile()
70 #endif
71 if (iswild)
72 fnd = wxXmlFindFirst;
73 else
74 fnd = filemask;
75 while (!!fnd)
76 {
77 #if wxUSE_FILESYSTEM
78 if (filemask.Lower().Matches("*.zip") ||
79 filemask.Lower().Matches("*.rsc"))
80 {
81 wxFileSystem fs2;
82 wxString fnd2;
83
84 fnd2 = fs2.FindFirst(fnd + wxT("#zip:*.xmb"), wxFILE);
85 while (!!fnd2)
86 {
87 drec = new wxXmlResourceDataRecord;
88 drec->File = fnd2;
89 m_Data.Add(drec);
90 fnd2 = fs2.FindNext();
91 }
92 }
93 else
94 #endif
95 {
96 drec = new wxXmlResourceDataRecord;
97 drec->File = fnd;
98 m_Data.Add(drec);
99 }
100
101 if (iswild)
102 fnd = wxXmlFindNext;
103 else
104 fnd = wxEmptyString;
105 }
106 # undef wxXmlFindFirst
107 # undef wxXmlFindNext
108 return TRUE;
109 }
110
111
112
113 void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
114 {
115 m_Handlers.Append(handler);
116 handler->SetParentResource(this);
117 }
118
119
120
121 void wxXmlResource::ClearHandlers()
122 {
123 m_Handlers.Clear();
124 }
125
126
127
128 wxMenu *wxXmlResource::LoadMenu(const wxString& name)
129 {
130 return (wxMenu*)CreateResFromNode(FindResource(name, wxT("menu")), NULL, NULL);
131 }
132
133
134
135 wxMenuBar *wxXmlResource::LoadMenuBar(const wxString& name)
136 {
137 return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("menubar")), NULL, NULL);
138 }
139
140
141
142 wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name)
143 {
144 return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("toolbar")), parent, NULL);
145 }
146
147
148
149 wxDialog *wxXmlResource::LoadDialog(wxWindow *parent, const wxString& name)
150 {
151 wxDialog *dialog = new wxDialog;
152 if (!LoadDialog(dialog, parent, name))
153 { delete dialog; return NULL; }
154 else return dialog;
155 }
156
157 bool wxXmlResource::LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name)
158 {
159 return CreateResFromNode(FindResource(name, wxT("dialog")), parent, dlg) != NULL;
160 }
161
162
163
164 wxPanel *wxXmlResource::LoadPanel(wxWindow *parent, const wxString& name)
165 {
166 wxPanel *panel = new wxPanel;
167 if (!LoadPanel(panel, parent, name))
168 { delete panel; return NULL; }
169 else return panel;
170 }
171
172 bool wxXmlResource::LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name)
173 {
174 return CreateResFromNode(FindResource(name, wxT("panel")), parent, panel) != NULL;
175 }
176
177
178
179 void wxXmlResource::ProcessPlatformProperty(wxXmlNode *node)
180 {
181 wxString s;
182 bool isok;
183
184 wxXmlNode *c = node->GetChildren();
185 while (c)
186 {
187 isok = FALSE;
188 if (!c->GetPropVal(_T("platform"), &s))
189 isok = TRUE;
190 else
191 {
192 wxStringTokenizer tkn(s, " |");
193
194 while (tkn.HasMoreTokens())
195 {
196 s = tkn.GetNextToken();
197 if (
198 #ifdef __WXMSW__
199 s == wxString(_T("win"))
200 #elif defined(__UNIX__)
201 s == wxString(_T("unix"))
202 #elif defined(__MAC__)
203 s == wxString(_T("mac"))
204 #elif defined(__OS2__)
205 s == wxString(_T("os2"))
206 #else
207 FALSE
208 #endif
209 ) isok = TRUE;
210 }
211 }
212
213 if (isok)
214 ProcessPlatformProperty(c);
215 else
216 {
217 node->RemoveChild(c);
218 delete c;
219 }
220
221 c = c->GetNext();
222 }
223 }
224
225
226
227 void wxXmlResource::UpdateResources()
228 {
229 bool modif;
230 # if wxUSE_FILESYSTEM
231 wxFSFile *file;
232 wxFileSystem fsys;
233 # endif
234
235 for (size_t i = 0; i < m_Data.GetCount(); i++)
236 {
237 modif = (m_Data[i].Doc == NULL);
238
239 if (!modif)
240 {
241 # if wxUSE_FILESYSTEM
242 file = fsys.OpenFile(m_Data[i].File);
243 modif = file && file->GetModificationTime() > m_Data[i].Time;
244 if (!file)
245 wxLogError(_("Cannot open file '%s'."), m_Data[i].File.c_str());
246 delete file;
247 # else
248 modif = wxDateTime(wxFileModificationTime(m_Data[i].File)) > m_Data[i].Time;
249 # endif
250 }
251
252 if (modif)
253 {
254 wxInputStream *stream;
255
256 # if wxUSE_FILESYSTEM
257 file = fsys.OpenFile(m_Data[i].File);
258 stream = file->GetStream();
259 # else
260 stream = new wxFileInputStream(m_Data[i].File);
261 # endif
262
263 if (stream)
264 {
265 delete m_Data[i].Doc;
266 m_Data[i].Doc = new wxXmlDocument;
267 }
268 if (!stream || !m_Data[i].Doc->Load(*stream))
269 {
270 wxLogError(_("Cannot load resources from file '%s'."), m_Data[i].File.c_str());
271 delete m_Data[i].Doc;
272 m_Data[i].Doc = NULL;
273 }
274 else if (m_Data[i].Doc->GetRoot()->GetName() != _T("resource"))
275 {
276 wxLogError(_("Invalid XML resource '%s': doesn't have root node 'resource'."), m_Data[i].File.c_str());
277 delete m_Data[i].Doc;
278 m_Data[i].Doc = NULL;
279 }
280 else
281 ProcessPlatformProperty(m_Data[i].Doc->GetRoot());
282
283 # if wxUSE_FILESYSTEM
284 delete file;
285 # else
286 delete stream;
287 # endif
288 }
289 }
290 }
291
292
293
294 wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& type)
295 {
296 UpdateResources(); //ensure everything is up-to-date
297
298 wxString dummy;
299 for (size_t f = 0; f < m_Data.GetCount(); f++)
300 {
301 if (m_Data[f].Doc == NULL || m_Data[f].Doc->GetRoot() == NULL) continue;
302 for (wxXmlNode *node = m_Data[f].Doc->GetRoot()->GetChildren();
303 node; node = node->GetNext())
304 if ( node->GetType() == wxXML_ELEMENT_NODE &&
305 (!type || node->GetName() == type) &&
306 node->GetPropVal(wxT("name"), &dummy) &&
307 dummy == name)
308 {
309 #if wxUSE_FILESYSTEM
310 m_CurFileSystem.ChangePathTo(m_Data[f].File);
311 #endif
312 return node;
313 }
314 }
315
316 wxLogError(_("XML resource '%s' (type '%s') not found!"),
317 name.c_str(), type.c_str());
318 return NULL;
319 }
320
321
322
323 wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance)
324 {
325 if (node == NULL) return NULL;
326
327 wxXmlResourceHandler *handler;
328 wxObject *ret;
329 wxNode * ND = m_Handlers.GetFirst();
330 while (ND)
331 {
332 handler = (wxXmlResourceHandler*)ND->GetData();
333 if (handler->CanHandle(node))
334 {
335 ret = handler->CreateResource(node, parent, instance);
336 if (ret) return ret;
337 }
338 ND = ND->GetNext();
339 }
340
341 wxLogError(_("No handler found for XML node '%s'!"), node->GetName().c_str());
342 return NULL;
343 }
344
345
346
347
348
349
350
351
352
353 wxXmlResourceHandler::wxXmlResourceHandler()
354 : m_Node(NULL), m_Parent(NULL), m_Instance(NULL),
355 m_ParentAsWindow(NULL), m_InstanceAsWindow(NULL)
356 {}
357
358
359
360 wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
361 {
362 wxXmlNode *myNode = m_Node;
363 wxObject *myParent = m_Parent, *myInstance = m_Instance;
364 wxWindow *myParentAW = m_ParentAsWindow, *myInstanceAW = m_InstanceAsWindow;
365
366 m_Node = node;
367 m_Parent = parent;
368 m_Instance = instance;
369 m_ParentAsWindow = wxDynamicCast(m_Parent, wxWindow);
370 m_InstanceAsWindow = wxDynamicCast(m_Instance, wxWindow);
371
372 wxObject *returned = DoCreateResource();
373
374 m_Node = myNode;
375 m_Parent = myParent; m_ParentAsWindow = myParentAW;
376 m_Instance = myInstance; m_InstanceAsWindow = myInstanceAW;
377
378 return returned;
379 }
380
381
382 void wxXmlResourceHandler::AddStyle(const wxString& name, int value)
383 {
384 m_StyleNames.Add(name);
385 m_StyleValues.Add(value);
386 }
387
388
389 bool wxXmlResourceHandler::HasParam(const wxString& param)
390 {
391 return (GetParamNode(param) != NULL);
392 }
393
394
395 int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
396 {
397 wxString s = GetParamValue(param);
398
399 if (!s) return defaults;
400
401 wxStringTokenizer tkn(s, _T("| "), wxTOKEN_STRTOK);
402 int style = 0;
403 int index;
404 wxString fl;
405 while (tkn.HasMoreTokens())
406 {
407 fl = tkn.GetNextToken();
408 index = m_StyleNames.Index(fl);
409 if (index != wxNOT_FOUND)
410 style |= m_StyleValues[index];
411 else
412 wxLogError(_("Unknown style flag ") + fl);
413 }
414 return style;
415 }
416
417
418
419 wxString wxXmlResourceHandler::GetText(const wxString& param)
420 {
421 wxString str1 = GetParamValue(param);
422 wxString str2;
423 const wxChar *dt;
424
425 for (dt = str1.c_str(); *dt; dt++)
426 {
427 // Remap $ to &, map $$ to $ (for things like "&File..." --
428 // this is illegal in XML, so we use "$File..."):
429 if (*dt == '$')
430 switch (*(++dt))
431 {
432 case '$' : str2 << '$'; break;
433 default : str2 << '&' << *dt; break;
434 }
435 // Remap \n to CR, \r LF, \t to TAB:
436 else if (*dt == '\\')
437 switch (*(++dt))
438 {
439 case 'n' : str2 << '\n'; break;
440 case 't' : str2 << '\t'; break;
441 case 'r' : str2 << '\r'; break;
442 default : str2 << '\\' << *dt; break;
443 }
444 else str2 << *dt;
445 }
446 return str2;
447 }
448
449
450
451 long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv)
452 {
453 long value;
454 wxString str1 = GetParamValue(param);
455
456 if (!str1.ToLong(&value))
457 value = defaultv;
458
459 return value;
460 }
461
462
463 int wxXmlResourceHandler::GetID()
464 {
465 wxString sid = GetName();
466 long num;
467
468 if (sid == _T("-1")) return -1;
469 else if (sid.IsNumber() && sid.ToLong(&num)) return num;
470 #define stdID(id) else if (sid == _T(#id)) return id
471 stdID(wxID_OPEN); stdID(wxID_CLOSE); stdID(wxID_NEW);
472 stdID(wxID_SAVE); stdID(wxID_SAVEAS); stdID(wxID_REVERT);
473 stdID(wxID_EXIT); stdID(wxID_UNDO); stdID(wxID_REDO);
474 stdID(wxID_HELP); stdID(wxID_PRINT); stdID(wxID_PRINT_SETUP);
475 stdID(wxID_PREVIEW); stdID(wxID_ABOUT); stdID(wxID_HELP_CONTENTS);
476 stdID(wxID_HELP_COMMANDS); stdID(wxID_HELP_PROCEDURES);
477 stdID(wxID_CUT); stdID(wxID_COPY); stdID(wxID_PASTE);
478 stdID(wxID_CLEAR); stdID(wxID_FIND); stdID(wxID_DUPLICATE);
479 stdID(wxID_SELECTALL); stdID(wxID_OK); stdID(wxID_CANCEL);
480 stdID(wxID_APPLY); stdID(wxID_YES); stdID(wxID_NO);
481 stdID(wxID_STATIC); stdID(wxID_FORWARD); stdID(wxID_BACKWARD);
482 stdID(wxID_DEFAULT); stdID(wxID_MORE); stdID(wxID_SETUP);
483 stdID(wxID_RESET); stdID(wxID_HELP_CONTEXT);
484 #undef stdID
485 else return XMLID(sid.c_str());
486 }
487
488
489 wxString wxXmlResourceHandler::GetName()
490 {
491 return m_Node->GetPropVal(_T("name"), _T("-1"));
492 }
493
494
495
496 bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv)
497 {
498 wxString v = GetParamValue(param);
499 v.MakeLower();
500 if (!v) return defaultv;
501 else return (v == _T("1"));
502 }
503
504
505
506 wxColour wxXmlResourceHandler::GetColour(const wxString& param)
507 {
508 wxString v = GetParamValue(param);
509 unsigned long tmp = 0;
510
511 if (v.Length() != 7 || v[0] != _T('#') ||
512 wxSscanf(v.c_str(), _T("#%lX"), &tmp) != 1)
513 {
514 wxLogError(_("XML resource: Incorrect colour specification '%s' for property '%s'."),
515 v.c_str(), param.c_str());
516 return wxNullColour;
517 }
518
519 return wxColour((tmp & 0xFF0000) >> 16 ,
520 (tmp & 0x00FF00) >> 8,
521 (tmp & 0x0000FF));
522 }
523
524
525
526 wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxSize size)
527 {
528 wxString name = GetParamValue(param);
529 if (name.IsEmpty()) return wxNullBitmap;
530 #if wxUSE_FILESYSTEM
531 wxFSFile *fsfile = GetCurFileSystem().OpenFile(name);
532 if (fsfile == NULL)
533 {
534 wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
535 return wxNullBitmap;
536 }
537 wxImage img(*(fsfile->GetStream()));
538 delete fsfile;
539 #else
540 wxImage img(GetParamValue(_T("bitmap")));
541 #endif
542 if (!img.Ok())
543 {
544 wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
545 return wxNullBitmap;
546 }
547 if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y);
548 return img.ConvertToBitmap();
549 }
550
551
552
553 wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, wxSize size)
554 {
555 #ifdef __WXMSW__
556 wxIcon icon;
557 icon.CopyFromBitmap(GetBitmap(param, size));
558 #else
559 wxIcon *iconpt;
560 wxBitmap bmppt = GetBitmap(param, size);
561 iconpt = (wxIcon*)(&bmppt);
562 wxIcon icon(*iconpt);
563 #endif
564 return icon;
565 }
566
567
568
569 wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param)
570 {
571 wxXmlNode *n = m_Node->GetChildren();
572
573 while (n)
574 {
575 if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == param)
576 return n;
577 n = n->GetNext();
578 }
579 return NULL;
580 }
581
582
583 wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node)
584 {
585 wxXmlNode *n = node;
586 if (n == NULL) return wxEmptyString;
587 n = n->GetChildren();
588
589 while (n)
590 {
591 if (n->GetType() == wxXML_TEXT_NODE ||
592 n->GetType() == wxXML_CDATA_SECTION_NODE)
593 return n->GetContent();
594 n = n->GetNext();
595 }
596 return wxEmptyString;
597 }
598
599
600
601 wxString wxXmlResourceHandler::GetParamValue(const wxString& param)
602 {
603 return GetNodeContent(GetParamNode(param));
604 }
605
606
607
608 wxSize wxXmlResourceHandler::GetSize(const wxString& param)
609 {
610 wxString s = GetParamValue(param);
611 if (s.IsEmpty()) s = _T("-1,-1");
612 bool is_dlg;
613 long sx, sy;
614
615 is_dlg = s[s.Length()-1] == _T('d');
616 if (is_dlg) s.RemoveLast();
617
618 if (!s.BeforeFirst(_T(',')).ToLong(&sx) ||
619 !s.AfterLast(_T(',')).ToLong(&sy))
620 {
621 wxLogError(_("Cannot parse coordinates from '%s'."), s.mb_str());
622 return wxDefaultSize;
623 }
624
625 if (is_dlg)
626 {
627 if (m_InstanceAsWindow)
628 return wxDLG_UNIT(m_InstanceAsWindow, wxSize(sx, sy));
629 else if (m_ParentAsWindow)
630 return wxDLG_UNIT(m_ParentAsWindow, wxSize(sx, sy));
631 else
632 {
633 wxLogError(_("Cannot convert dialog units: dialog unknown."));
634 return wxDefaultSize;
635 }
636 }
637 else return wxSize(sx, sy);
638 }
639
640
641
642 wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
643 {
644 wxSize sz = GetSize(param);
645 return wxPoint(sz.x, sz.y);
646 }
647
648
649
650 void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
651 {
652 //FIXME : add font, cursor
653
654 if (HasParam(_T("exstyle")))
655 wnd->SetExtraStyle(GetStyle(_T("exstyle")));
656 if (HasParam(_T("bg")))
657 wnd->SetBackgroundColour(GetColour(_T("bg")));
658 if (HasParam(_T("fg")))
659 wnd->SetForegroundColour(GetColour(_T("fg")));
660 if (GetBool(_T("enabled"), 1) == 0)
661 wnd->Enable(FALSE);
662 if (GetBool(_T("focused"), 0) == 1)
663 wnd->SetFocus();
664 if (GetBool(_T("hidden"), 0) == 1)
665 wnd->Show(FALSE);
666 #if wxUSE_TOOLTIPS
667 if (HasParam(_T("tooltip")))
668 wnd->SetToolTip(GetText(_T("tooltip")));
669 #endif
670 }
671
672
673 void wxXmlResourceHandler::CreateChildren(wxObject *parent,
674 bool only_this_handler, wxXmlNode *children_node)
675 {
676 if (children_node == NULL) children_node = GetParamNode(_T("children"));
677 if (children_node == NULL) return;
678
679 wxXmlNode *n = children_node->GetChildren();
680
681 while (n)
682 {
683 if (n->GetType() == wxXML_ELEMENT_NODE)
684 {
685 if (only_this_handler)
686 {
687 if (CanHandle(n))
688 CreateResource(n, parent, NULL);
689 }
690 else
691 m_Resource->CreateResFromNode(n, parent, NULL);
692 }
693 n = n->GetNext();
694 }
695 }
696
697
698
699
700
701
702
703
704
705 // --------------- XMLID implementation -----------------------------
706
707 #define XMLID_TABLE_SIZE 1024
708
709
710 struct XMLID_record
711 {
712 int id;
713 char *key;
714 XMLID_record *next;
715 };
716
717 static XMLID_record *XMLID_Records[XMLID_TABLE_SIZE] = {NULL};
718 static int XMLID_LastID = wxID_HIGHEST;
719
720 /*static*/ int wxXmlResource::GetXMLID(const char *str_id)
721 {
722 int index = 0;
723
724 for (const char *c = str_id; *c != '\0'; c++) index += (int)*c;
725 index %= XMLID_TABLE_SIZE;
726
727 XMLID_record *oldrec = NULL;
728 int matchcnt = 0;
729 for (XMLID_record *rec = XMLID_Records[index]; rec; rec = rec->next)
730 {
731 if (strcmp(rec->key, str_id) == 0)
732 {
733 #ifdef DEBUG_XMLID_HASH
734 printf("XMLID: matched '%s' (%ith item)\n", rec->key, matchcnt);
735 #endif
736 return rec->id;
737 }
738 matchcnt++;
739 oldrec = rec;
740 }
741
742 XMLID_record **rec_var = (oldrec == NULL) ?
743 &XMLID_Records[index] : &oldrec->next;
744 *rec_var = new XMLID_record;
745 (*rec_var)->id = ++XMLID_LastID;
746 (*rec_var)->key = strdup(str_id);
747 (*rec_var)->next = NULL;
748 #ifdef DEBUG_XMLID_HASH
749 printf("XMLID: new key for '%s': %i at %i (%ith item)\n",
750 (*rec_var)->key, (*rec_var)->id, index, matchcnt);
751 #endif
752
753 return (*rec_var)->id;
754 }
755
756
757 static void CleanXMLID_Record(XMLID_record *rec)
758 {
759 if (rec)
760 {
761 #ifdef DEBUG_XMLID_HASH
762 printf("XMLID: clearing '%s'\n", rec->key);
763 #endif
764 CleanXMLID_Record(rec->next);
765 free (rec->key);
766 delete rec;
767 }
768 }
769
770 static void CleanXMLID_Records()
771 {
772 for (int i = 0; i < XMLID_TABLE_SIZE; i++)
773 CleanXMLID_Record(XMLID_Records[i]);
774 }
775
776
777
778
779
780
781
782
783 // --------------- module and globals -----------------------------
784
785
786 static wxXmlResource gs_XmlResource;
787
788 wxXmlResource *wxTheXmlResource = &gs_XmlResource;
789
790
791 class wxXmlResourceModule: public wxModule
792 {
793 DECLARE_DYNAMIC_CLASS(wxXmlResourceModule)
794 public:
795 wxXmlResourceModule() {}
796 bool OnInit() {return TRUE;}
797 void OnExit()
798 {
799 wxTheXmlResource->ClearHandlers();
800 CleanXMLID_Records();
801 }
802 };
803
804 IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule, wxModule)