]>
git.saurik.com Git - wxWidgets.git/blob - contrib/utils/convertrc/rc2xml.cpp
1 // rc2xml.cpp: implementation of the rc2xml class.
2 //Author: Brian Gavin 9/24/00
3 //License: wxWindows License
9 trans->Convert("Myfile.rc","Myfile.xml");
12 1. Figure how to fix memory leaks in all wxLists in this class
13 2. Find a way to rename MS Windows fonts so that they work
14 cross platform (wxGTK,etc)
15 3. Be able to abort incorrectly formated files without crashing
19 #pragma implementation "rc2xml.h"
22 // For compilers that support precompilation, includes "wx/wx.h".
23 #include "wx/wxprec.h"
29 // for all others, include the necessary headers (this file is usually all you
30 // need because it includes almost all "standard" wxWidgets headers
38 #include "wx/deprecated/setup.h"
39 #include "wx/deprecated/resource.h"
40 #include <wx/textfile.h>
41 #include <wx/tokenzr.h>
45 //////////////////////////////////////////////////////////////////////
46 // Construction/Destruction
47 //////////////////////////////////////////////////////////////////////
52 m_bitmaplist
=new wxList(wxKEY_STRING
);
53 m_stringtable
=new wxList(wxKEY_STRING
);
54 m_iconlist
= new wxList(wxKEY_STRING
);
55 m_resourcelist
=new wxList(wxKEY_INTEGER
);
63 delete m_resourcelist
;
66 bool rc2xml::Convert(wxString rcfile
, wxString xmlfile
)
68 m_rc
.Open(rcfile
.c_str());
69 m_filesize
=m_rc
.Length();
72 m_workingpath
=wxPathOnly(rcfile
);
74 m_targetpath
=wxPathOnly(xmlfile
) + _T("\\");
78 wxSetWorkingDirectory(m_workingpath
);
82 result
=m_xmlfile
.Open(xmlfile
.c_str(),_T("w+t"));
83 wxASSERT_MSG(result
,_T("Couldn't create XML file"));
88 /* Write Basic header for XML file */
89 m_xmlfile
.Write(_T("<?xml version=\"1.0\" ?>\n"));
90 m_xmlfile
.Write(_T("<resource>\n"));
93 ParseResourceHeader();
94 //Gather all the resource we need for toolbars,menus, and etc
98 //Read in dialogs, toolbars,menus
101 m_xmlfile
.Write(_T("</resource>\n"));
104 wxMessageBox(_("Conversion complete."), _("Done"),
105 wxOK
| wxICON_INFORMATION
);
111 void rc2xml::ParseDialog(wxString dlgname
)
114 static int dlgid
=999;
116 /* Make sure that this really is a dialog
117 microsoft reuses the keyword DIALOG for other things
120 //Microsoft notation?
121 while ((token
==_T("DISCARDABLE"))
122 ||(token
==_T("LOADONCALL"))||(token
==_T("MOVEABLE")))
127 //Error isn't a Dialog resource eject eject
128 if (!token
.IsNumber())
131 //Record x,y,width,height
132 int x
,y
,width
,height
;
133 ReadRect(x
,y
,width
,height
);
137 wxString ptsize
,face
;
139 m_xmlfile
.Write(_T("\t<object class=\"wxDialog\""));
140 //Avoid duplicate names this way
141 dlgname
.Replace(_T("IDD_"),_T("DLG_"));
142 WriteBasicInfo(x
,y
,width
,height
,dlgname
);
146 while ((token
!=_T("BEGIN"))&(token
!=_T("{")))
148 if (token
==_T("CAPTION"))
150 title
=GetQuoteField();
153 //TODO fix face name so that it is cross platform name
154 // FONT 8, "MS Sans Serif"
155 if (token
==_T("FONT"))
158 face
=GetQuoteField();
159 m_xmlfile
.Write(_T("\t\t<font>\n"));
160 m_xmlfile
.Write(_T("\t\t\t<size>")+ptsize
+_T("</size>\n"));
161 m_xmlfile
.Write(_T("\t\t\t<face>")+face
+_T("</face>\n"));
162 m_xmlfile
.Write(_T("\t\t</font>\n"));
169 m_xmlfile
.Write(_T("\t</object>\n"));
174 EDITTEXT IDC_BANDS,36,83,22,14,ES_AUTOHSCROLL | ES_NUMBER | NOT
176 LTEXT "Bands",IDC_STATIC,11,86,21,8
177 EDITTEXT IDC_NAME,10,3,75,14,ES_AUTOHSCROLL
180 void rc2xml::ParseControls()
183 wxString label
,varname
;
186 while ((token
!=_T("END"))&(token
!=_T("}")))
188 if (token
==_T("AUTOCHECKBOX"))
190 label
=GetQuoteField();
192 ParseCheckBox(label
,varname
);
195 if (token
==_T("AUTORADIOBUTTON"))
197 label
=GetQuoteField();
199 ParseRadioButton(label
,varname
);
202 if (token
==_T("LTEXT"))
204 label
=GetQuoteField();
206 ParseStaticText(label
,varname
);
208 else if (token
==_T("EDITTEXT"))
211 ParseTextCtrl(varname
);
213 else if ((token
==_T("PUSHBUTTON"))||(token
==_T("DEFPUSHBUTTON")))
215 label
=GetQuoteField();
217 ParsePushButton(label
,varname
);
219 else if (token
==_T("GROUPBOX"))
221 label
=GetQuoteField();
223 ParseGroupBox(label
,varname
);
225 else if (token
==_T("COMBOBOX"))
228 ParseComboBox(varname
);
230 else if (token
==_T("CONTROL"))
232 else if (token
==_T("LISTBOX"))
235 ParseListBox(varname
);
237 else if (token
==_T("ICON"))
239 else if (token
==_T("SCROLLBAR"))
245 //LTEXT "Radius",IDC_STATIC,9,67,23,8
246 void rc2xml::ParseStaticText(wxString phrase
, wxString varname
)
250 while (!token
.IsNumber())
255 int x
,y
,width
,height
;
256 ReadRect(x
,y
,width
,height
);
258 m_xmlfile
.Write(_T("\t\t<object class=\"wxStaticText\""));
259 WriteBasicInfo(x
,y
,width
,height
,varname
);WriteLabel(phrase
);
260 m_xmlfile
.Write(_T("\t\t</object>\n"));
263 //EDITTEXT IDC_RADIUS,36,65,40,14,ES_AUTOHSCROLL
264 void rc2xml::ParseTextCtrl(wxString varname
)
269 while (!token
.IsNumber())
274 int x
,y
,width
,height
;
275 ReadRect(x
,y
,width
,height
);
278 m_xmlfile
.Write(_T("\t\t<object class=\"wxTextCtrl\""));
279 WriteBasicInfo(x
,y
,width
,height
,varname
);
280 m_xmlfile
.Write(_T("\t\t</object>\n"));
283 //AUTOCHECKBOX "&log.", ID_XLOG, 25, 24, 21, 12
284 void rc2xml::ParseCheckBox(wxString phrase
, wxString varname
)
288 while (!token
.IsNumber())
293 int x
,y
,width
,height
;
294 ReadRect(x
,y
,width
,height
);
296 m_xmlfile
.Write(_T("\t\t<object class=\"wxCheckBox\""));
297 WriteBasicInfo(x
,y
,width
,height
,varname
);
299 m_xmlfile
.Write(_T("\t\t</object>\n"));
302 //AUTORADIOBUTTON "&text", ID_SW10, 13, 12, 68, 10, BS_AUTORADIOBUTTON | WS_GROUP
303 void rc2xml::ParseRadioButton(wxString phrase
, wxString varname
)
305 wxString token
,style
;
306 int x
,y
,width
,height
;
308 GotOrs
= ReadOrs(token
);
309 if (ReadRect(x
,y
,width
,height
))
312 if (token
.Find(_T("WS_GROUP")) != wxNOT_FOUND
)
313 style
+= _T("wxRB_GROUP");
315 m_xmlfile
.Write(_T("\t\t<object class=\"wxRadioButton\""));
316 WriteBasicInfo(x
,y
,width
,height
,varname
);
319 m_xmlfile
.Write(_T("\t\t</object>\n"));
323 //PUSHBUTTON "Create/Update",IDC_CREATE,15,25,53,13,NOT WS_TABSTOP
324 void rc2xml::ParsePushButton(wxString phrase
, wxString varname
)
329 while (!token
.IsNumber())
334 int x
,y
,width
,height
;
335 ReadRect(x
,y
,width
,height
);
337 m_xmlfile
.Write(_T("\t\t<object class=\"wxButton\""));
338 WriteBasicInfo(x
,y
,width
,height
,varname
);
340 m_xmlfile
.Write(_T("\t\t</object>\n"));
345 bool rc2xml::Separator(int ch
)
347 //if ((ch==' ')|(ch==',')|(ch==13)|(ch==10)|(ch=='|')|(ch=='\t'))
348 if ((ch
==' ')|(ch
==',')|(ch
==13)|(ch
==10)|(ch
=='\t'))
360 void rc2xml::ParseGroupBox(wxString phrase
, wxString varname
)
362 // GROUPBOX "Rotate",IDC_STATIC,1,1,71,79
365 while (!token
.IsNumber())
370 int x
,y
,width
,height
;
371 ReadRect(x
,y
,width
,height
);
373 m_xmlfile
.Write(_T("\t\t<object class=\"wxStaticBox\""));
374 WriteBasicInfo(x
,y
,width
,height
,varname
);
376 m_xmlfile
.Write(_T("\t\t</object>\n"));
379 bool rc2xml::ReadRect(int & x
, int & y
, int & width
, int & height
)
381 x
=wxAtoi(GetToken());
382 y
=wxAtoi(GetToken());
383 width
=wxAtoi(GetToken());
385 wxString tmp
= GetToken(&ret
);
387 return ret
; // check for more parameters
390 wxString
rc2xml::GetToken(bool *listseparator
)
392 wxString token
=wxEmptyString
;
408 while (Separator(ch
))
421 while (!Separator(ch
))
431 *listseparator
= (ch
== ',');
435 wxString
rc2xml::GetQuoteField()
444 // !! Changed by MS, 15th/11/04. Can now read strings such as
445 // """Catapult"" - blah blah", ...
460 // real end of string..
464 // add a single quote - fall through
472 // string in stringtable may contain embedded quotes
473 // escape characters retained to allow strings to be rewritten
474 wxString
rc2xml::GetStringQuote()
488 if ((ch
==34)&&(lastch
!='\\'))
490 wxFileOffset p
= m_rc
.Tell();
492 // RC supports "", for embedded quote, as well as \"
504 ReadChar(ch
); // skip
505 if ((ch
=='\n')&&(lastch
=='\\')) // lastch <should> be this
506 phrase
+='n'; // escape
517 void rc2xml::ReadChar(int &ch
)
519 wxFileOffset result
= m_rc
.Tell();
521 if((result
>=m_filesize
))
524 result
= m_rc
.Read(&ch
,1);
526 if( result
== wxInvalidOffset
)
533 void rc2xml::ParseComboBox(wxString varname
)
535 /* COMBOBOX IDC_SCALECOMBO,10,110,48,52,CBS_DROPDOWNLIST | CBS_SORT |
536 WS_VSCROLL | WS_TABSTOP */
537 wxString token
,style
;
538 int x
,y
,width
,height
;
540 GotOrs
= ReadOrs(token
);
541 if (ReadRect(x
,y
,width
,height
))
545 m_xmlfile
.Write(_T("\t\t<object class=\"wxComboBox\""));
546 WriteBasicInfo(x
,y
,width
,height
,varname
);
547 if (token
.Find(_T("CBS_SIMPLE")) != wxNOT_FOUND
)
548 WriteStyle(_T("wxCB_SIMPLE"));
549 if (token
.Find(_T("CBS_SORT")) != wxNOT_FOUND
)
550 WriteStyle(_T("wxCB_SORT"));
551 if (token
.Find(_T("CBS_DISABLENOSCROLL")) != wxNOT_FOUND
)
552 WriteStyle(_T("wxLB_ALWAYS_SB"));
553 m_xmlfile
.Write(_T("\n\t\t</object>\n"));
557 void rc2xml::ParseMenu(wxString varname
)
559 wxString token
=wxEmptyString
;
561 //Write menubar to xml file
562 m_xmlfile
.Write(_T("\t<object class=\"wxMenuBar\""));
563 //Avoid duplicate names this way
564 varname
.Replace(_T("IDR_"),_T("MB_"));
566 m_xmlfile
.Write(_T(">\n"));
568 while ((token
!=_T("BEGIN"))&(token
!=_T("{")))
571 while ((token
!=_T("END"))&(token
!=_T("}")))
576 if (token
==_T("POPUP"))
581 m_xmlfile
.Write(_T("\t</object>\n"));
584 void rc2xml::ParsePopupMenu()
586 static int menucount
=0;
588 wxString token
,name
,msg
,longhelp
,tip
;
589 token
=GetQuoteField();
591 //Remove \t because it causes problems
593 //spot=token.First("\\t");
594 //token=token.Left(spot);
597 //Generate a fake name since RC menus don't have one
598 name
<< _T("Menu_") << menucount
;
599 m_xmlfile
.Write(_T("\t\t<object class=\"wxMenu\""));
601 m_xmlfile
.Write(_T(">\n"));
604 while ((token
!=_T("BEGIN"))&(token
!=_T("{")))
607 while ((token
!=_T("END"))&(token
!=_T("}")))
612 if (token
==_T("POPUP"))
615 if (token
==_T("MENUITEM"))
618 m_xmlfile
.Write(_T("\t\t\t</object>\n"));
621 wxString
rc2xml::PeekToken()
623 wxFileOffset p
= m_rc
.Tell();
624 wxString token
=GetToken();
630 //MS Windows pain in the butt CONTROL
631 void rc2xml::ParseControlMS()
633 wxString token
= PeekToken();
635 if (token
.Contains(_T("\"")))
636 ParseNormalMSControl();
638 ParseWeirdMSControl();
641 /* CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
642 TBS_NOTICKS | WS_TABSTOP,52,73,100,15
645 void rc2xml::ParseSlider(wxString
WXUNUSED(label
), wxString varname
)
647 wxString token
,style
;
649 if (token
.Find(_T("TBS_VERT"))!=wxNOT_FOUND
)
650 style
+=_T("wxSL_VERTICAL");
651 //MFC RC Default is horizontal
653 style
+=_T("wxSL_HORIZONTAL");
655 int x
,y
,width
,height
;
656 ReadRect(x
,y
,width
,height
);
657 m_xmlfile
.Write(_T("\t\t<object class=\"wxSlider\""));
658 WriteBasicInfo(x
,y
,width
,height
,varname
);
660 m_xmlfile
.Write(_T("\n\t\t</object>\n"));
664 CONTROL "Progress1",CG_IDC_PROGDLG_PROGRESS,"msctls_progress32",
665 WS_BORDER,15,52,154,13
667 void rc2xml::ParseProgressBar(wxString
WXUNUSED(label
), wxString varname
)
669 wxString token
,style
;
672 int x
,y
,width
,height
;
673 ReadRect(x
,y
,width
,height
);
675 //Always horizontal in MFC
676 m_xmlfile
.Write(_T("\t\t<object class=\"wxGauge\""));
677 WriteBasicInfo(x
,y
,width
,height
,varname
);
679 m_xmlfile
.Write(_T("\t\t</object>\n"));
682 bool rc2xml::ReadOrs(wxString
& orstring
)
687 if (token
.IsNumber())
691 while(PeekToken()==_T("|"))
694 orstring
+=GetToken();
696 orstring
+=GetToken();
701 //Is it a checkbutton or a radiobutton or a pushbutton or a groupbox
702 void rc2xml::ParseCtrlButton(wxString label
, wxString varname
)
705 wxFileOffset p
= m_rc
.Tell();
709 if (token
.Find(_T("BS_AUTOCHECKBOX"))!=wxNOT_FOUND
)
710 ParseCheckBox(label
, varname
);
711 else if ((token
.Find(_T("BS_AUTORADIOBUTTON"))!=wxNOT_FOUND
)||
712 (token
.Find(_T("BS_RADIOBUTTON"))!=wxNOT_FOUND
))
713 ParseRadioButton(label
, varname
);
714 else if (token
.Find(_T("BS_GROUPBOX"))!=wxNOT_FOUND
)
715 ParseGroupBox(label
, varname
);
716 else // if ((token.Find("BS_PUSHBUTTON")!=wxNOT_FOUND)||
717 // (token.Find("BS_DEFPUSHBUTTON")!=wxNOT_FOUND))
718 ParsePushButton(label
, varname
); // make default case
721 void rc2xml::WriteSize(int width
, int height
)
724 msg
<< _T(" <size>") << width
<< _T(",") << height
<< _T("d</size>");
725 m_xmlfile
.Write(msg
);
728 void rc2xml::WritePosition(int x
, int y
)
731 msg
<< _T(" <pos>") << x
<< _T(",") << y
<< _T("d</pos>");
732 m_xmlfile
.Write(msg
);
735 void rc2xml::WriteTitle(wxString title
)
738 msg
=_T("\t\t<title>")+title
+_T("</title>\n");
739 m_xmlfile
.Write(msg
);
742 void rc2xml::WriteName(wxString name
)
745 //Try to convert any number ids into names
747 //Replace common MS ids with wxWidgets ids
748 //I didn't do everyone of them
749 if (name
==_T("IDOK"))
751 else if (name
==_T("IDCANCEL"))
752 name
=_T("wxID_CANCEL");
753 else if (name
==_T("IDAPPLY"))
754 name
=_T("wxID_APPLY");
755 else if (name
==_T("ID_FILE_OPEN"))
756 name
=_T("wxID_OPEN");
757 else if (name
==_T("ID_FILE_CLOSE"))
758 name
=_T("wxID_CLOSE");
759 else if (name
==_T("ID_FILE_SAVE"))
760 name
=_T("wxID_SAVE");
761 else if (name
==_T("ID_FILE_SAVE_AS"))
762 name
=_T("wxID_SAVEAS");
763 else if (name
==_T("ID_APP_EXIT"))
764 name
=_T("wxID_EXIT");
765 else if (name
==_T("ID_FILE_PRINT"))
766 name
=_T("wxID_PRINT");
767 else if (name
==_T("ID_FILE_PRINT_PREVIEW"))
768 name
=_T("wxID_PREVIEW");
769 else if (name
==_T("ID_FILE_PRINT_SETUP"))
770 name
=_T("wxID_PRINT_SETUP");
771 else if (name
==_T("ID_APP_ABOUT"))
772 name
=_T("wxID_ABOUT");
773 else if (name
==_T("ID_EDIT_UNDO"))
774 name
=_T("wxID_UNDO");
775 else if (name
==_T("ID_EDIT_CUT"))
777 else if (name
==_T("ID_EDIT_COPY"))
778 name
=_T("wxID_COPY");
779 else if (name
==_T("ID_EDIT_PASTE"))
780 name
=_T("wxID_PASTE");
781 else if (name
==_T("IDYES"))
783 else if (name
==_T("IDNO"))
785 else if (name
==_T("IDHELP"))
786 name
=_T("wxID_HELP");
788 m_xmlfile
.Write(_T(" name= \"")+name
+_T("\""));
791 void rc2xml::WriteLabel(wxString label
)
793 label
.Replace(_T("&"),_T("$"));
794 // changes by MS, handle '<' '>' characters within a label.
795 label
.Replace(_T("<"),_T("<"));
796 label
.Replace(_T(">"),_T(">"));
797 m_xmlfile
.Write(_T("\t\t\t<label>")+label
+_T("</label>\n"));
800 void rc2xml::WriteBasicInfo(int x
, int y
, int width
, int height
, wxString name
)
803 m_xmlfile
.Write(_T(">\n"));
804 m_xmlfile
.Write(_T("\t\t\t"));
806 WriteSize(width
,height
);
807 m_xmlfile
.Write(_T("\n"));
810 void rc2xml::WriteStyle(wxString style
)
812 if (style
.Length()==0)
814 m_xmlfile
.Write(_T("\t\t\t<style>")+style
+_T("</style>\n"));
817 LISTBOX IDC_LIST1,16,89,48,40,LBS_SORT | LBS_MULTIPLESEL |
818 LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
820 void rc2xml::ParseListBox(wxString varname
)
824 while (!token
.IsNumber())
829 int x
,y
,width
,height
;
830 ReadRect(x
,y
,width
,height
);
832 m_xmlfile
.Write(_T("\t\t<object class=\"wxListBox\""));
833 WriteBasicInfo(x
,y
,width
,height
,varname
);
834 m_xmlfile
.Write(_T("\n\t\t</object>\n"));
838 CONTROL "",IDC_RICHEDIT1,"RICHEDIT",ES_AUTOHSCROLL | WS_BORDER |
839 WS_TABSTOP,103,110,40,14
841 void rc2xml::ParseRichEdit(wxString
WXUNUSED(label
), wxString varname
)
844 //while (ReadOrs(token));
846 int x
,y
,width
,height
;
847 ReadRect(x
,y
,width
,height
);
849 //Make it a rich text control
850 style
+=_T("wxTE_MULTILINE ");
851 m_xmlfile
.Write(_T("\t\t<object class=\"wxTextCtrl\""));
852 WriteBasicInfo(x
,y
,width
,height
,varname
);
854 m_xmlfile
.Write(_T("\t\t</object>\n"));
858 CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,209,72,
861 void rc2xml::ParseSpinCtrl(wxString
WXUNUSED(label
), wxString varname
)
863 wxString token
,style
;
866 if (token
.Find(_T("UDS_HORZ"))!=wxNOT_FOUND
)
867 style
=_T("wxSP_HORIZONTAL");
870 style
=_T("wxSP_VERTICAL");
872 int x
,y
,width
,height
;
873 ReadRect(x
,y
,width
,height
);
874 m_xmlfile
.Write(_T("\t\t<object class=\"wxSpinButton\""));
875 WriteBasicInfo(x
,y
,width
,height
,varname
);
877 m_xmlfile
.Write(_T("\n\t\t</object>\n"));
881 void rc2xml::FirstPass()
883 wxString token
,prevtok
;
887 if (token
==_T("BITMAP"))
888 ParseBitmap(prevtok
);
889 else if (token
==_T("STRINGTABLE"))
890 ParseStringTable(prevtok
);
891 else if (token
==_T("ICON"))
898 void rc2xml::ParseBitmap(wxString varname
)
901 wxString
*bitmapfile
;
904 //Microsoft notation?
905 if (token
==_T("DISCARDABLE"))
910 bitmapfile
=new wxString
;
911 *bitmapfile
=GetQuoteField();
912 m_bitmaplist
->Append(varname
,bitmapfile
);
917 void rc2xml::SecondPass()
919 wxString token
,prevtok
;
923 if ((token
==_T("DIALOG"))||(token
==_T("DIALOGEX")))
924 ParseDialog(prevtok
);
925 else if (token
==_T("MENU"))
927 else if (token
==_T("TOOLBAR"))
928 ParseToolBar(prevtok
);
935 void rc2xml::ParseToolBar(wxString varname
)
939 wxASSERT_MSG(token
==_T("DISCARDABLE"),_T("Error in toolbar parsing"));
940 //Look up bitmap for toolbar and load
941 wxNode
*node
=m_bitmaplist
->Find(LookUpId(varname
));
942 wxString
*bitmappath
;
943 bitmappath
=(wxString
*)node
->GetData();
945 if (!bitmap
.LoadFile(*bitmappath
,wxBITMAP_TYPE_BMP
))
946 wxLogError(_T("Unable to load bitmap:")+*bitmappath
);
948 //Write toolbar to xml file
949 m_xmlfile
.Write(_T("\t<object class=\"wxToolBar\""));
950 //Avoid duplicate names this way
951 varname
.Replace(_T("IDR_"),_T("TB_"));
953 m_xmlfile
.Write(_T(">\n"));
955 style
+=_T("wxTB_FLAT");
959 //Grab width and height
961 width
=wxAtoi(GetToken());
962 height
=wxAtoi(GetToken());
965 wxString buttonname
,msg
,tip
,longhelp
;
967 while ((token
!=_T("BEGIN"))&(token
!=_T("{")))
970 while ((token
!=_T("END"))&(token
!=_T("}")))
972 if (token
==_T("BUTTON"))
974 buttonname
=GetToken();
975 m_xmlfile
.Write(_T("\t\t\t<object class=\"tool\""));
976 WriteName(buttonname
);
977 m_xmlfile
.Write(_T(">\n"));
978 //Write tool tip if any
979 if (LookUpString(buttonname
,msg
))
981 SplitHelp(msg
,tip
,longhelp
);
982 m_xmlfile
.Write(_T("\t\t\t\t<tooltip>")+tip
+_T("</tooltip>\n"));
983 m_xmlfile
.Write(_T("\t\t<longhelp>")+longhelp
+_T("</longhelp>\n"));
985 //Make a bitmap file name
986 buttonname
=CleanName(buttonname
);
987 buttonname
+=_T(".bmp");
988 m_xmlfile
.Write(_T("\t\t\t\t<bitmap>")+buttonname
+_T("</bitmap>\n"));
989 WriteToolButton(buttonname
,c
,width
,height
,bitmap
);
990 m_xmlfile
.Write(_T("\t\t\t</object>\n"));
993 else if (token
==_T("SEPARATOR"))
995 m_xmlfile
.Write(_T("\t\t\t<object class=\"separator\"/>\n"));
999 m_xmlfile
.Write(_T("\t</object>\n"));
1002 //Extract bitmaps from larger toolbar bitmap
1003 void rc2xml::WriteToolButton(wxString name
,int index
, int width
, int height
, wxBitmap bitmap
)
1007 wxRect
r(x
,0,width
,height
);
1009 little
=bitmap
.GetSubBitmap(r
);
1010 little
.SaveFile(m_targetpath
+name
,wxBITMAP_TYPE_BMP
);
1013 void rc2xml::ParseStringTable(wxString
WXUNUSED(varname
))
1017 while ((token
!=_T("BEGIN"))&(token
!=_T("{")))
1022 while ((token
!=_T("END"))&(token
!=_T("}")))
1025 *msg
=GetStringQuote();
1026 m_stringtable
->Append(token
,msg
);
1031 bool rc2xml::LookUpString(wxString strid
,wxString
& st
)
1033 wxNode
*node
=m_stringtable
->Find(strid
);
1038 s
=(wxString
*)node
->GetData();
1044 bool rc2xml::SplitHelp(wxString msg
, wxString
&shorthelp
, wxString
&longhelp
)
1047 spot
=msg
.Find(_T("\\n"));
1048 if (spot
==wxNOT_FOUND
)
1054 longhelp
=msg
.Left(spot
);
1055 spot
=msg
.Length()-spot
-2;
1056 shorthelp
=msg
.Right(spot
);
1060 void rc2xml::ParseMenuItem()
1062 wxString token
,name
,msg
,tip
,longhelp
;
1064 if (PeekToken()==_T("SEPARATOR"))
1066 m_xmlfile
.Write(_T("\t\t\t<object class=\"separator\"/>\n"));
1070 token
=GetQuoteField();
1072 //Remove \t because it causes problems
1073 //spot=token.First("\\t");
1074 //token=token.Left(spot);
1075 m_xmlfile
.Write(_T("\t\t\t<object class=\"wxMenuItem\""));
1077 m_xmlfile
.Write(_T(">\n"));
1079 //Look up help if any listed in stringtable
1080 //can't assume numbers correlate, restrict to string identifiers
1081 if ((!name
.IsNumber())&&(LookUpString(name
,msg
)))
1083 SplitHelp(msg
,tip
,longhelp
);
1084 m_xmlfile
.Write(_T("\t\t\t<help>")
1085 +longhelp
+_T("</help>\n"));
1087 //look for extra attributes like checked and break
1091 while ((ptoken
!=_T("MENUITEM"))&(ptoken
!=_T("POPUP"))&(ptoken
!=_T("END")))
1095 if (token
==_T("CHECKED"))
1096 m_xmlfile
.Write(_T("\t\t\t<checkable>1</checkable>\n"));
1097 else if (token
==_T("MENUBREAK"))
1099 //m_xmlfile.Write("\t\t\t</break>\n");
1100 else if (token
==_T("GRAYED"))
1103 wxLogError(_T("Unknown Menu Item token:")+token
);
1108 m_xmlfile
.Write(_T("\t\t\t</object>\n"));
1112 //ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
1113 void rc2xml::ParseIconStatic()
1116 wxString varname
,iconname
;
1117 token
= PeekToken();
1118 if (token
.Contains(_T("\"")))
1119 iconname
= GetQuoteField();
1121 iconname
=GetToken();
1125 int x
,y
,width
,height
;
1126 ReadRect(x
,y
,width
,height
);
1128 m_xmlfile
.Write(_T("\t\t<object class=\"wxStaticBitmap\""));
1129 WriteBasicInfo(x
,y
,width
,height
,varname
);
1130 //Save icon as a bitmap
1131 WriteIcon(iconname
);
1132 m_xmlfile
.Write(_T("\t\t</object>\n"));
1135 //IDR_MAINFRAME ICON DISCARDABLE "res\\mfcexample.ico"
1136 void rc2xml::ParseIcon(wxString varname
)
1140 iconfile
=new wxString
;
1143 *iconfile
=GetQuoteField();
1144 m_iconlist
->Append(varname
,iconfile
);
1149 wxString
rc2xml::CleanName(wxString name
)
1152 name
.Replace(_T("id_"),wxEmptyString
);
1153 name
.Replace(_T("idr_"),wxEmptyString
);
1154 name
.Replace(_T("idb_"),wxEmptyString
);
1155 name
.Replace(_T("idc_"),wxEmptyString
);
1157 name
.Replace(_T(".ico"),wxEmptyString
);
1159 name
.Replace(_T(".bmp"),wxEmptyString
);
1162 // And the award for most messed up control goes to...
1163 // CONTROL IDB_FACE,IDC_STATIC,"Static",SS_BITMAP,26,62,32,30
1164 void rc2xml::ParseStaticBitmap(wxString bitmapname
, wxString varname
)
1171 int x
,y
,width
,height
;
1172 ReadRect(x
,y
,width
,height
);
1174 m_xmlfile
.Write(_T("\t\t<object class=\"wxStaticBitmap\""));
1175 WriteBasicInfo(x
,y
,width
,height
,varname
);
1176 WriteBitmap(bitmapname
);
1177 m_xmlfile
.Write(_T("\t\t</object>\n"));
1181 void rc2xml::ParseNormalMSControl()
1183 wxString label
=GetQuoteField();
1184 wxString varname
=GetToken();
1185 wxString kindctrl
=GetQuoteField();
1186 kindctrl
.MakeUpper();
1188 if (kindctrl
==_T("MSCTLS_UPDOWN32"))
1189 ParseSpinCtrl(label
,varname
);
1190 else if (kindctrl
==_T("MSCTLS_TRACKBAR32"))
1191 ParseSlider(label
,varname
);
1192 else if (kindctrl
==_T("MSCTLS_PROGRESS32"))
1193 ParseProgressBar(label
,varname
);
1194 else if (kindctrl
==_T("SYSTREEVIEW32"))
1195 ParseTreeCtrl(label
,varname
);
1196 else if (kindctrl
==_T("SYSMONTHCAL32"))
1197 ParseCalendar(label
,varname
);
1198 else if (kindctrl
==_T("SYSLISTVIEW32"))
1199 ParseListCtrl(label
,varname
);
1200 else if (kindctrl
==_T("BUTTON"))
1201 ParseCtrlButton(label
,varname
);
1202 else if (kindctrl
==_T("RICHEDIT"))
1203 ParseRichEdit(label
,varname
);
1204 else if (kindctrl
==_T("STATIC"))
1207 wxFileOffset p
= m_rc
.Tell();
1210 if (token
.Find(_T("SS_BITMAP"))!=wxNOT_FOUND
)
1211 ParseStaticBitmap(label
,varname
);
1213 ParseStaticText(label
,varname
);
1215 else if (kindctrl
==_T("EDIT"))
1216 ParseTextCtrl(varname
);
1217 else if (kindctrl
==_T("LISTBOX"))
1218 ParseListBox(varname
);
1219 else if (kindctrl
==_T("COMBOBOX"))
1220 ParseComboBox(varname
);
1223 void rc2xml::ParseWeirdMSControl()
1225 wxString id
= GetToken();
1226 wxString varname
= GetToken();
1227 wxString kindctrl
= GetQuoteField();
1228 kindctrl
.MakeUpper();
1229 // CONTROL IDB_FACE,IDC_STATIC,"Static",SS_BITMAP,26,62,32,30
1230 if (kindctrl
==_T("STATIC"))
1232 if (PeekToken()==_T("SS_BITMAP"))
1233 ParseStaticBitmap(id
,varname
);
1235 wxLogError(_T("Unknown MS Control Static token"));
1239 //SCROLLBAR IDC_SCROLLBAR1,219,56,10,40,SBS_VERT
1240 void rc2xml::ParseScrollBar()
1246 int x
,y
,width
,height
;
1247 ReadRect(x
,y
,width
,height
);
1252 if (token
.Find(_T("SBS_VERT"))!=wxNOT_FOUND
)
1253 style
=_T("wxSB_VERTICAL");
1254 //Default MFC style is horizontal
1256 style
=_T("wxSB_HORIZONTAL");
1258 m_xmlfile
.Write(_T("\t\t<object class=\"wxScrollBar\""));
1259 WriteBasicInfo(x
,y
,width
,height
,varname
);
1261 m_xmlfile
.Write(_T("\n\t\t</object>\n"));
1264 // CONTROL "Tree1",IDC_TREE1,"SysTreeView32",WS_BORDER | WS_TABSTOP,
1267 void rc2xml::ParseTreeCtrl(wxString
WXUNUSED(label
), wxString varname
)
1270 //while (ReadOrs(token));
1272 int x
,y
,width
,height
;
1273 ReadRect(x
,y
,width
,height
);
1274 m_xmlfile
.Write(_T("\t\t<object class=\"wxTreeCtrl\""));
1275 WriteBasicInfo(x
,y
,width
,height
,varname
);
1276 m_xmlfile
.Write(_T("\t\t</object>\n"));
1279 // CONTROL "MonthCalendar1",IDC_MONTHCALENDAR1,"SysMonthCal32",
1280 //MCS_NOTODAY | WS_TABSTOP,105,71,129,89
1282 void rc2xml::ParseCalendar(wxString
WXUNUSED(label
), wxString varname
)
1285 //while (ReadOrs(token));
1287 int x
,y
,width
,height
;
1288 ReadRect(x
,y
,width
,height
);
1289 m_xmlfile
.Write(_T("\t\t<object class=\"wxCalendarCtrl\""));
1290 WriteBasicInfo(x
,y
,width
,height
,varname
);
1291 m_xmlfile
.Write(_T("\t\t</object>\n"));
1293 // CONTROL "List1",IDC_LIST1,"SysListView32",WS_BORDER | WS_TABSTOP,
1296 void rc2xml::ParseListCtrl(wxString
WXUNUSED(label
), wxString varname
)
1299 //while (ReadOrs(token));
1301 int x
,y
,width
,height
;
1302 ReadRect(x
,y
,width
,height
);
1303 m_xmlfile
.Write(_T("\t\t<object class=\"wxListCtrl\""));
1304 WriteBasicInfo(x
,y
,width
,height
,varname
);
1305 m_xmlfile
.Write(_T("\t\t</object>\n"));
1309 void rc2xml::WriteBitmap(wxString bitmapname
)
1312 wxNode
*node
=m_bitmaplist
->Find(LookUpId(bitmapname
));
1315 m_xmlfile
.Write(_T("\t\t\t<bitmap>missingfile</bitmap>\n"));
1316 wxLogError(_T("Unable to find bitmap:")+bitmapname
);
1320 wxString
*bitmappath
;
1321 bitmappath
=(wxString
*)node
->GetData();
1323 bitmapname
=wxFileNameFromPath(*bitmappath
);
1325 if (!bitmap
.LoadFile(*bitmappath
,wxBITMAP_TYPE_BMP
))
1326 wxLogError(_T("Unable to load bitmap:")+*bitmappath
);
1328 //Make a bitmap file name
1329 bitmapname
=CleanName(bitmapname
);
1330 bitmapname
+=_T(".bmp");
1331 m_xmlfile
.Write(_T("\t\t\t<bitmap>")+bitmapname
+_T("</bitmap>\n"));
1332 bitmap
.SaveFile(m_targetpath
+bitmapname
,wxBITMAP_TYPE_BMP
);
1335 void rc2xml::WriteIcon(wxString iconname
)
1337 wxNode
*node
=m_iconlist
->Find(iconname
);
1340 m_xmlfile
.Write(_T("\t\t\t<bitmap>missing_file</bitmap>\n"));
1341 wxLogError(_T("Unable to find icon:")+iconname
);
1344 iconpath
=(wxString
*)node
->GetData();
1347 if (!icon
.LoadFile(*iconpath
,wxBITMAP_TYPE_ICO
))
1348 wxLogError(_T("Unable to load icon:")+*iconpath
);
1350 bitmap
.CopyFromIcon(icon
);
1354 iconname
=wxFileNameFromPath(*iconpath
);
1355 //Make a bitmap file name
1356 iconname
=CleanName(iconname
);
1357 iconname
+=_T(".bmp");
1358 m_xmlfile
.Write(_T("\t\t\t<bitmap>")+iconname
+_T("</bitmap>\n"));
1359 bitmap
.SaveFile(m_targetpath
+iconname
,wxBITMAP_TYPE_BMP
);
1363 /*Unfortunately sometimes the great MSVC Resource editor decides
1364 to use numbers instead of the word id. I have no idea why they
1365 do this, but that is the way it is.
1367 /* this is a quick and dirty way to parse the resource.h file
1368 it will not recognize #ifdef so it can be easily fooled
1370 void rc2xml::ParseResourceHeader()
1373 //Attempt to load resource.h in current path
1374 if (!r
.Open(_T("resource.h")))
1376 wxLogError(_T("Warining Unable to load resource.h file"));
1382 wxStringTokenizer tok
;
1388 //Read through entire file
1389 for ( str
= r
.GetFirstLine(); !r
.Eof(); str
= r
.GetNextLine() )
1391 if (str
.Find(_T("#define"))!=wxNOT_FOUND
)
1394 //Just ignore #define token
1396 v
=tok
.GetNextToken();
1397 id
=tok
.GetNextToken();
1400 varname
=new wxString
;
1403 m_resourcelist
->Append(n
,varname
);
1413 wxString
rc2xml::LookUpId(wxString id
)
1421 wxNode
*node
=m_resourcelist
->Find(n
);
1426 s
=(wxString
*)node
->GetData();