]> git.saurik.com Git - wxWidgets.git/blame - contrib/utils/convertrc/rc2xml.cpp
give focus to show top level windows
[wxWidgets.git] / contrib / utils / convertrc / rc2xml.cpp
CommitLineData
2193517f
VS
1// rc2xml.cpp: implementation of the rc2xml class.
2//Author: Brian Gavin 9/24/00
3//License: wxWindows License
4/*
5How to use:
6#include "rc2xml.h"
7...
8rc2xml trans;
9trans->Convert("Myfile.rc","Myfile.xml");
10*/
11/* TODO
121. Figure how to fix memory leaks in all wxLists in this class
132. Find a way to rename MS Windows fonts so that they work
14cross platform (wxGTK,etc)
153. Be able to abort incorrectly formated files without crashing
16*/
17
18#ifdef __GNUG__
19#pragma implementation "rc2xml.cpp"
20#pragma interface "rc2xml.cpp"
21#endif
22
88d42654 23// For compilers that support precompilation, includes "wx/wx.h".
2193517f
VS
24#include <wx/wxprec.h>
25
26#ifdef __BORLANDC__
27#pragma hdrstop
28#endif
29
30// for all others, include the necessary headers (this file is usually all you
31// need because it includes almost all "standard" wxWindows headers
32#ifndef WX_PRECOMP
33#include <wx/wx.h>
34#endif
35
88d42654
VS
36
37#include "rc2xml.h"
38#include "wx/image.h"
39#include "wx/resource.h"
2193517f
VS
40#include <wx/textfile.h>
41#include <wx/tokenzr.h>
42
43
44
88d42654
VS
45//////////////////////////////////////////////////////////////////////
46// Construction/Destruction
47//////////////////////////////////////////////////////////////////////
48
2193517f 49rc2xml::rc2xml()
88d42654 50{
2193517f
VS
51 m_done=FALSE;
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);
88d42654
VS
56}
57
2193517f 58rc2xml::~rc2xml()
88d42654 59{
2193517f
VS
60 delete m_bitmaplist;
61 delete m_stringtable;
62 delete m_iconlist;
63 delete m_resourcelist;
88d42654
VS
64}
65
2193517f 66bool rc2xml::Convert(wxString rcfile, wxString xmlfile)
88d42654 67{
2193517f
VS
68 m_rc.Open(rcfile.c_str());
69 m_filesize=m_rc.Length();
70
2c99715a
VS
71 m_workingpath=wxPathOnly(rcfile);
72 m_targetpath=wxPathOnly(xmlfile)+"\\";
73
74 wxSetWorkingDirectory(m_workingpath);
75
2193517f
VS
76 bool result;
77 result=m_xmlfile.Open(xmlfile.c_str(),"w+t");
78 wxASSERT_MSG(result,"Couldn't create XML file");
79 if (!result)
80 return FALSE;
88d42654
VS
81
82
83/* Write Basic header for XML file */
2193517f
VS
84 m_xmlfile.Write("<?xml version=\"1.0\" ?>\n");
85 m_xmlfile.Write("<resource>\n");
86
87//Read resource.h
88 ParseResourceHeader();
88d42654 89//Gather all the resource we need for toolbars,menus, and etc
2193517f
VS
90 FirstPass();
91 m_done=FALSE;
92 m_rc.Seek(0);
88d42654 93//Read in dialogs, toolbars,menus
2193517f 94 SecondPass();
88d42654 95
2193517f
VS
96 m_xmlfile.Write("</resource>\n");
97 m_xmlfile.Close();
98 m_rc.Close();
88d42654
VS
99
100return TRUE;
101}
102
103
2193517f 104void rc2xml::ParseDialog(wxString dlgname)
88d42654 105{
2193517f
VS
106 wxString token;
107 static int dlgid=999;
108 dlgid++;
109/* Make sure that this really is a dialog
110microsoft reuses the keyword DIALOG for other things
111*/
112 token=PeekToken();
113//Microsoft notation?
114 if (token=="DISCARDABLE")
115 {
116 token=GetToken();
117 token=PeekToken();
118 }
119//Error isn't a Dialog resource eject eject
120 if (!token.IsNumber())
121 return;
88d42654
VS
122
123//Record x,y,width,height
2193517f
VS
124 int x,y,width,height;
125 ReadRect(x,y,width,height);
88d42654 126//Get Title
2193517f
VS
127 token=GetToken();
128 wxString title;
129 wxString ptsize,face;
130
e066e256 131 m_xmlfile.Write("\t<object class=\"wxDialog\"");
2193517f
VS
132 //Avoid duplicate names this way
133 dlgname.Replace("IDD_","DLG_");
134 WriteBasicInfo(x,y,width,height,dlgname);
135 WriteTitle(title);
136
137
138 while ((token!="BEGIN")&(token!="{"))
139 {
140 if (token=="CAPTION")
141 {
142 title=GetQuoteField();
143 }
144
145//TODO fix face name so that it is cross platform name
146// FONT 8, "MS Sans Serif"
147 if (token=="FONT")
148 {
149 ptsize=GetToken();
150 face=GetQuoteField();
151 m_xmlfile.Write("\t\t<font>\n");
152 m_xmlfile.Write("\t\t\t<size>"+ptsize+"</size>\n");
153 m_xmlfile.Write("\t\t\t<face>"+face+"</face>\n");
154 m_xmlfile.Write("\t\t</font>\n");
155 }
156
157 token=GetToken();
158 }
88d42654 159
2193517f 160 ParseControls();
e066e256 161 m_xmlfile.Write("\t</object>\n");
88d42654
VS
162}
163
164/*
165BEGIN
166 EDITTEXT IDC_BANDS,36,83,22,14,ES_AUTOHSCROLL | ES_NUMBER | NOT
167 WS_TABSTOP
168 LTEXT "Bands",IDC_STATIC,11,86,21,8
169 EDITTEXT IDC_NAME,10,3,75,14,ES_AUTOHSCROLL
170END
171*/
2193517f 172void rc2xml::ParseControls()
88d42654 173{
2193517f
VS
174 wxString token;
175
176 token=GetToken();
177 while ((token!="END")&(token!="}"))
178 {
11ad1132
VS
179 if (token=="AUTOCHECKBOX")
180 ParseCheckBox();
181 else
182 if (token=="AUTORADIOBUTTON")
183 ParseRadioButton();
184 else
2193517f
VS
185 if (token=="LTEXT")
186 ParseStaticText();
187 else if (token=="EDITTEXT")
188 ParseTextCtrl();
189 else if (token=="PUSHBUTTON")
190 ParsePushButton();
191 else if (token=="DEFPUSHBUTTON")
192 ParsePushButton();
193 else if (token=="GROUPBOX")
194 ParseGroupBox();
195 else if (token=="COMBOBOX")
196 ParseComboBox();
197 else if (token=="CONTROL")
198 ParseControlMS();
199 else if (token=="LISTBOX")
200 ParseListBox();
201 else if (token=="ICON")
202 ParseIconStatic();
203 else if (token=="SCROLLBAR")
204 ParseScrollBar();
205 token=GetToken();
206 }
88d42654
VS
207
208}
209//LTEXT "Radius",IDC_STATIC,9,67,23,8
2193517f 210void rc2xml::ParseStaticText()
88d42654 211{
2193517f
VS
212 wxString token;
213 wxString phrase,varname;
214 phrase=GetQuoteField();
215 varname=GetToken();
216 int x,y,width,height;
217 ReadRect(x,y,width,height);
88d42654 218
e066e256 219 m_xmlfile.Write("\t\t<object class=\"wxStaticText\"");
2193517f 220 WriteBasicInfo(x,y,width,height,varname);WriteLabel(phrase);
e066e256 221 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
222
223}
224//EDITTEXT IDC_RADIUS,36,65,40,14,ES_AUTOHSCROLL
2193517f 225void rc2xml::ParseTextCtrl()
88d42654 226{
2193517f
VS
227 wxString token;
228 wxString varname,style;
229 varname=GetToken();
230 int x,y,width,height;
231 ReadRect(x,y,width,height);
88d42654
VS
232//TODO
233//style=GetToken();
11ad1132 234 m_xmlfile.Write("\t\t<object class=\"wxTextCtrl\"");
2193517f 235 WriteBasicInfo(x,y,width,height,varname);
e066e256 236 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
237
238}
11ad1132
VS
239//AUTOCHECKBOX "&log.", ID_XLOG, 25, 24, 21, 12
240void rc2xml::ParseCheckBox()
241{
242 wxString token;
243 wxString phrase,varname;
244 phrase=GetQuoteField();
245 varname=GetToken();
246
247 int x,y,width,height;
248 ReadRect(x,y,width,height);
249
250 m_xmlfile.Write("\t\t<object class=\"wxCheckBox\"");
251 WriteBasicInfo(x,y,width,height,varname);
252 WriteLabel(phrase);
253 m_xmlfile.Write("\t\t</object>\n");
254
255}
256//AUTORADIOBUTTON "&text", ID_SW10, 13, 12, 68, 10, BS_AUTORADIOBUTTON | WS_GROUP
257void rc2xml::ParseRadioButton()
258{
259 wxString token,style;
260 wxString phrase,varname;
261 phrase=GetQuoteField();
262 varname=GetToken();
263
264 int x,y,width,height;
265 if (ReadRect(x,y,width,height))
266 ReadOrs(token);
267 if (token.Find("WS_GROUP") != -1)
268 style += "wxRB_GROUP";
269
270 m_xmlfile.Write("\t\t<object class=\"wxRadioButton\"");
271 WriteBasicInfo(x,y,width,height,varname);
272 WriteLabel(phrase);
273 WriteStyle(style);
274 m_xmlfile.Write("\t\t</object>\n");
275
276}
277
88d42654 278//PUSHBUTTON "Create/Update",IDC_CREATE,15,25,53,13,NOT WS_TABSTOP
2193517f 279void rc2xml::ParsePushButton()
88d42654 280{
2193517f
VS
281 wxString token;
282 wxString phrase,varname;
283 phrase=GetQuoteField();
284 varname=GetToken();
88d42654 285
2193517f
VS
286 int x,y,width,height;
287 ReadRect(x,y,width,height);
88d42654 288
2c99715a 289 m_xmlfile.Write("\t\t<object class=\"wxButton\"");
2193517f
VS
290 WriteBasicInfo(x,y,width,height,varname);
291 WriteLabel(phrase);
e066e256 292 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
293
294}
295
296
2193517f 297bool rc2xml::Seperator(int ch)
88d42654
VS
298{
299//if ((ch==' ')|(ch==',')|(ch==13)|(ch==10)|(ch=='|')|(ch=='\t'))
2193517f
VS
300 if ((ch==' ')|(ch==',')|(ch==13)|(ch==10)|(ch=='\t'))
301 return TRUE;
302
303 if (ch==EOF)
304 {
305 m_done=TRUE;
306 return TRUE;
307 }
308
309 return FALSE;
88d42654
VS
310}
311
2193517f 312void rc2xml::ParseGroupBox()
88d42654
VS
313{
314// GROUPBOX "Rotate",IDC_STATIC,1,1,71,79
2193517f
VS
315 wxString token;
316 wxString phrase,varname;
317 phrase=GetQuoteField();
318 varname=GetToken();
319 int x,y,width,height;
320 ReadRect(x,y,width,height);
321
e066e256 322 m_xmlfile.Write("\t\t<object class=\"wxStaticBox\"");
2193517f
VS
323 WriteBasicInfo(x,y,width,height,varname);
324 WriteLabel(phrase);
e066e256 325 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
326}
327
11ad1132 328bool rc2xml::ReadRect(int & x, int & y, int & width, int & height)
88d42654 329{
2193517f
VS
330 x=atoi(GetToken());
331 y=atoi(GetToken());
332 width=atoi(GetToken());
11ad1132
VS
333 bool ret;
334 wxString tmp = GetToken(&ret);
335 height=atoi(tmp);
336 return ret; // check for more parameters
88d42654
VS
337}
338
11ad1132 339wxString rc2xml::GetToken(bool *listseperator)
88d42654 340{
2193517f 341 wxString token="";
88d42654 342
2193517f
VS
343 if (m_rc.Eof())
344 {
345 m_done=TRUE;
346 return token;
88d42654
VS
347}
348
2193517f
VS
349 int ch=0;
350 ReadChar(ch);
351 if (ch==EOF)
352 {
353 m_done=TRUE;
354 return token;
355 }
88d42654 356
2193517f
VS
357 while (Seperator(ch))
358 {
359 ReadChar(ch);
360 if (m_done)
361 return token;
362 }
88d42654 363
2193517f
VS
364 if (ch==EOF)
365 {
366 m_done=TRUE;
367 }
88d42654
VS
368
369
2193517f
VS
370 while (!Seperator(ch))
371 {
11ad1132 372 token += (char)ch;
2193517f
VS
373 ReadChar(ch);
374 }
88d42654 375
11ad1132
VS
376 if (ch == EOF)
377 m_done = TRUE;
88d42654 378
11ad1132
VS
379 if (listseperator)
380 *listseperator = (ch == ',');
2193517f 381 return token;
88d42654
VS
382}
383
2193517f 384wxString rc2xml::GetQuoteField()
88d42654 385{
2193517f
VS
386 wxString phrase;
387 //ASCII code 34 "
388 int ch=0;
389 ReadChar(ch);
88d42654 390
2193517f
VS
391 while (ch!=34)
392 ReadChar(ch);
88d42654 393
2193517f 394 ReadChar(ch);
88d42654 395
2193517f
VS
396 while (ch!=34)
397 {
398 phrase+=(char)ch;
399 ReadChar(ch);
400 }
401 return phrase;
88d42654
VS
402}
403
2193517f 404void rc2xml::ReadChar(int &ch)
88d42654 405{
2193517f
VS
406 int result;
407 result=m_rc.Tell();
88d42654 408
2193517f
VS
409 if((result>=m_filesize))
410 m_done=TRUE;
88d42654 411
2193517f 412 result=m_rc.Read(&ch,1);
88d42654 413
2193517f
VS
414 if((result==-1))
415 m_done=TRUE;
88d42654 416
2193517f
VS
417 if(ch==EOF)
418 m_done=TRUE;
88d42654
VS
419}
420
2193517f 421void rc2xml::ParseComboBox()
88d42654
VS
422{
423/* COMBOBOX IDC_SCALECOMBO,10,110,48,52,CBS_DROPDOWNLIST | CBS_SORT |
424 WS_VSCROLL | WS_TABSTOP */
11ad1132 425 wxString token,style;
2193517f
VS
426 wxString varname;
427 varname=GetToken();
428 int x,y,width,height;
11ad1132
VS
429 if (ReadRect(x,y,width,height))
430 ReadOrs(token);
88d42654 431
e066e256 432 m_xmlfile.Write("\t\t<object class=\"wxComboBox\"");
2193517f 433 WriteBasicInfo(x,y,width,height,varname);
11ad1132
VS
434 if (token.Find("CBS_SIMPLE") != -1)
435 WriteStyle("wxCB_SIMPLE");
436 if (token.Find("CBS_SORT") != -1)
437 WriteStyle("wxCB_SORT");
438 if (token.Find("CBS_DISABLENOSCROLL") != -1)
439 WriteStyle("wxLB_ALWAYS_SB");
e066e256 440 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
441
442}
443
2193517f 444void rc2xml::ParseMenu(wxString varname)
88d42654 445{
2193517f
VS
446 wxString token="";
447
448 //Write menubar to xml file
e066e256 449 m_xmlfile.Write("\t<object class=\"wxMenuBar\"");
2193517f
VS
450 //Avoid duplicate names this way
451 varname.Replace("IDR_","MB_");
452 WriteName(varname);
453 m_xmlfile.Write(">\n");
2193517f
VS
454
455 while ((token!="BEGIN")&(token!="{"))
456 token=GetToken();
457
458 while ((token!="END")&(token!="}"))
459 {
460 token=GetToken();
461 if (token=="POPUP")
462 {
463 ParsePopupMenu();
464 }
465 }
e066e256 466 m_xmlfile.Write("\t</object>\n");
88d42654
VS
467}
468
2193517f 469void rc2xml::ParsePopupMenu()
88d42654 470{
2193517f
VS
471 static int menucount=0;
472 menucount++;
473 wxString token,name,msg,longhelp,tip;
474 token=GetQuoteField();
475
476//Remove \t because it causes problems
88d42654 477
2193517f
VS
478//spot=token.First("\\t");
479//token=token.Left(spot);
88d42654
VS
480
481//Write Menu item
482//Generate a fake name since RC menus don't have one
2193517f 483 name<<"Menu_"<<menucount;
e066e256 484 m_xmlfile.Write("\t\t<object class=\"wxMenu\"");
2193517f
VS
485 WriteName(name);
486 m_xmlfile.Write(">\n");
487 WriteLabel(token);
2193517f
VS
488
489 while ((token!="BEGIN")&(token!="{"))
490 token=GetToken();
491
492 while ((token!="END")&(token!="}"))
493 {
494 token=GetToken();
495 if (token=="POPUP")
496 ParsePopupMenu();
88d42654 497
2193517f
VS
498 if (token=="MENUITEM")
499 ParseMenuItem();
500 }
e066e256 501 m_xmlfile.Write("\t\t\t</object>\n");
88d42654
VS
502}
503
2193517f 504wxString rc2xml::PeekToken()
88d42654 505{
2193517f
VS
506 wxString token;
507 int p;
508 p=m_rc.Tell();
509 token=GetToken();
88d42654 510
2193517f
VS
511 m_rc.Seek(p);
512 return token;
88d42654
VS
513}
514//MS Windows pain in the butt CONTROL
2193517f 515void rc2xml::ParseControlMS()
88d42654 516{
2193517f
VS
517 wxString label,varname,kindctrl,token;
518 token=PeekToken();
88d42654 519
2193517f
VS
520 if (token.Contains("\""))
521 ParseNormalMSControl();
522 else
523 ParseWeirdMSControl();
88d42654
VS
524
525}
526
527/* CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
528 TBS_NOTICKS | WS_TABSTOP,52,73,100,15
529*/
530
2193517f 531void rc2xml::ParseSlider(wxString label, wxString varname)
88d42654 532{
2193517f
VS
533 wxString token,style;
534 ReadOrs(token);
535 if (token.Find("TBS_VERT")!=-1)
536 style+="wxSL_VERTICAL";
537 //MFC RC Default is horizontal
538 else
539 style+="wxSL_HORIZONTAL";
540
541 int x,y,width,height;
542 ReadRect(x,y,width,height);
e066e256 543 m_xmlfile.Write("\t\t<object class=\"wxSlider\"");
2193517f
VS
544 WriteBasicInfo(x,y,width,height,varname);
545 WriteStyle(style);
e066e256 546 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
547
548}
549/*
550CONTROL "Progress1",CG_IDC_PROGDLG_PROGRESS,"msctls_progress32",
551 WS_BORDER,15,52,154,13
552*/
2193517f 553void rc2xml::ParseProgressBar(wxString label, wxString varname)
88d42654 554{
2193517f
VS
555 wxString token,style;
556 ReadOrs(token);
557
558 int x,y,width,height;
559 ReadRect(x,y,width,height);
560
88d42654 561//Always horizontal in MFC
e066e256 562 m_xmlfile.Write("\t\t<object class=\"wxGauge\"");
2193517f
VS
563 WriteBasicInfo(x,y,width,height,varname);
564 WriteStyle(style);
e066e256 565 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
566}
567
2193517f 568bool rc2xml::ReadOrs(wxString & orstring)
88d42654 569{
2193517f
VS
570 wxString token;
571
572 token=PeekToken();
573 if (token.IsNumber())
574 return FALSE;
575 orstring=GetToken();
576
577 while(PeekToken()==_T("|"))
578 {
579 //Grab |
580 orstring+=GetToken();
581 //Grab next token
582 orstring+=GetToken();
583 }
584 return TRUE;
88d42654
VS
585}
586
587//Is it a check button or a radio button
2193517f 588void rc2xml::ParseCtrlButton(wxString label, wxString varname)
88d42654 589{
2193517f
VS
590 wxString token;
591 ReadOrs(token);
592 int x,y,width,height;
593
594 if (token.Find("BS_AUTOCHECKBOX")!=-1)
595 {
596 ReadRect(x,y,width,height);
e066e256 597 m_xmlfile.Write("\t\t<object class=\"wxCheckBox\"");
2193517f
VS
598 WriteBasicInfo(x,y,width,height,varname);
599 WriteLabel(label);
e066e256 600 m_xmlfile.Write("\t\t</object>\n");
2193517f
VS
601 }
602
603 if (token.Find("BS_AUTORADIOBUTTON")!=-1)
604 {
605 ReadRect(x,y,width,height);
e066e256 606 m_xmlfile.Write("\t\t<object class=\"wxRadioButton\"");
2193517f
VS
607 WriteBasicInfo(x,y,width,height,varname);
608 WriteLabel(label);
e066e256 609 m_xmlfile.Write("\t\t</object>\n");
2193517f 610 }
88d42654
VS
611
612}
613
614
2193517f 615void rc2xml::WriteSize(int width, int height)
88d42654 616{
2193517f
VS
617 wxString msg;
618 msg<<" <size>"<<width<<","<<height<<"d</size>";
619 m_xmlfile.Write(msg);
88d42654
VS
620}
621
2193517f 622void rc2xml::WritePosition(int x, int y)
88d42654 623{
2193517f
VS
624 wxString msg;
625 msg<<" <pos>"<<x<<","<<y<<"d</pos>";
626 m_xmlfile.Write(msg);
88d42654
VS
627}
628
2193517f 629void rc2xml::WriteTitle(wxString title)
88d42654 630{
2193517f
VS
631 wxString msg;
632 msg=_T("\t\t<title>"+title+"</title>\n");
633 m_xmlfile.Write(msg);
88d42654
VS
634}
635
2193517f 636void rc2xml::WriteName(wxString name)
88d42654
VS
637{
638
2193517f
VS
639//Try to convert any number ids into names
640name=LookUpId(name);
88d42654
VS
641//Replace common MS ids with wxWindows ids
642//I didn't do everyone of them
2193517f
VS
643 if (name=="IDOK")
644 name="wxID_OK";
645 else if (name=="IDCANCEL")
646 name="wxID_CANCEL";
647 else if (name=="IDAPPLY")
648 name="wxID_APPLY";
649 else if (name=="ID_FILE_OPEN")
650 name="wxID_OPEN";
651 else if (name=="ID_FILE_CLOSE")
652 name="wxID_CLOSE";
653 else if (name=="ID_FILE_SAVE")
654 name="wxID_SAVE";
655 else if (name=="ID_FILE_SAVE_AS")
656 name="wxID_SAVEAS";
657 else if (name=="ID_APP_EXIT")
658 name="wxID_EXIT";
659 else if (name=="ID_FILE_PRINT")
660 name="wxID_PRINT";
661 else if (name=="ID_FILE_PRINT_PREVIEW")
662 name="wxID_PREVIEW";
663 else if (name=="ID_FILE_PRINT_SETUP")
664 name="wxID_PRINT_SETUP";
665 else if (name=="ID_APP_ABOUT")
666 name="wxID_ABOUT";
667 else if (name=="ID_EDIT_UNDO")
668 name="wxID_UNDO";
669 else if (name=="ID_EDIT_CUT")
670 name="wxID_CUT";
671 else if (name=="ID_EDIT_COPY")
672 name="wxID_COPY";
673 else if (name=="ID_EDIT_PASTE")
674 name="wxID_PASTE";
11ad1132
VS
675 else if (name=="IDYES")
676 name="wxID_YES";
677 else if (name=="IDNO")
678 name="wxID_NO";
679 else if (name=="IDHELP")
680 name="wxID_HELP";
2193517f
VS
681
682 m_xmlfile.Write(" name= \""+name+"\"");
88d42654
VS
683}
684
2193517f 685void rc2xml::WriteLabel(wxString label)
88d42654 686{
2193517f
VS
687 label.Replace("&","$");
688 m_xmlfile.Write("\t\t\t<label>"+label+"</label>\n");
88d42654
VS
689}
690
2193517f 691void rc2xml::WriteBasicInfo(int x, int y, int width, int height, wxString name)
88d42654 692{
2193517f
VS
693 WriteName(name);
694 m_xmlfile.Write(">\n");
695 m_xmlfile.Write("\t\t\t");
696 WritePosition(x,y);
697 WriteSize(width,height);
698 m_xmlfile.Write("\n");
88d42654
VS
699}
700
2193517f 701void rc2xml::WriteStyle(wxString style)
88d42654 702{
2193517f
VS
703 if (style.Length()==0)
704 return;
11ad1132 705 m_xmlfile.Write("\t\t\t<style>"+style+"</style>\n");
88d42654
VS
706}
707/*
708 LISTBOX IDC_LIST1,16,89,48,40,LBS_SORT | LBS_MULTIPLESEL |
709 LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
710*/
2193517f 711void rc2xml::ParseListBox()
88d42654 712{
2193517f
VS
713 wxString token;
714 wxString varname;
715 varname=GetToken();
716 int x,y,width,height;
717 ReadRect(x,y,width,height);
88d42654 718
e066e256 719 m_xmlfile.Write("\t\t<object class=\"wxListBox\"");
2193517f 720 WriteBasicInfo(x,y,width,height,varname);
e066e256 721 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
722
723}
724/*
725 CONTROL "",IDC_RICHEDIT1,"RICHEDIT",ES_AUTOHSCROLL | WS_BORDER |
726 WS_TABSTOP,103,110,40,14
727*/
2193517f 728void rc2xml::ParseRichEdit(wxString label, wxString varname)
88d42654 729{
2193517f
VS
730 wxString token;
731 //while (ReadOrs(token));
732 ReadOrs(token);
733 int x,y,width,height;
734 ReadRect(x,y,width,height);
735 wxString style;
88d42654 736//Make it a rich text control
2193517f 737 style+="wxTE_MULTILINE ";
e066e256 738 m_xmlfile.Write("\t\t<object class=\"wxTextCtrl\"");
2193517f
VS
739 WriteBasicInfo(x,y,width,height,varname);
740 WriteStyle(style);
e066e256 741 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
742
743}
744/*
745CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,209,72,
746 19,26
747*/
2193517f 748void rc2xml::ParseSpinCtrl(wxString label, wxString varname)
88d42654 749{
2193517f
VS
750 wxString token,style;
751
752 ReadOrs(token);
753 if (token.Find("UDS_HORZ")!=-1)
754 style="wxSP_HORIZONTAL";
755 //MFC default
756 else
757 style="wxSP_VERTICAL";
758
759 int x,y,width,height;
760 ReadRect(x,y,width,height);
e066e256 761 m_xmlfile.Write("\t\t<object class=\"wxSpinButton\"");
2193517f
VS
762 WriteBasicInfo(x,y,width,height,varname);
763 WriteStyle(style);
e066e256 764 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
765
766}
767
2193517f 768void rc2xml::FirstPass()
88d42654 769{
2193517f
VS
770 wxString token,prevtok;
771 while (!m_done)
772 {
773 token=GetToken();
774 if (token=="BITMAP")
775 ParseBitmap(prevtok);
776 else if (token=="STRINGTABLE")
777 ParseStringTable(prevtok);
778 else if (token=="ICON")
779 ParseIcon(prevtok);
780
781 prevtok=token;
782 }
88d42654
VS
783}
784
2193517f 785void rc2xml::ParseBitmap(wxString varname)
88d42654 786{
2193517f
VS
787 wxString token,*bitmapfile;
788
789 token=PeekToken();
790 //Microsoft notation?
791 if (token=="DISCARDABLE")
792 {
793 token=GetToken();
794 token=PeekToken();
795 }
796 bitmapfile=new wxString;
797 *bitmapfile=GetQuoteField();
798 m_bitmaplist->Append(varname,bitmapfile);
88d42654
VS
799
800}
801
802
2193517f 803void rc2xml::SecondPass()
88d42654 804{
2193517f
VS
805 wxString token,prevtok;
806 while (!m_done)
807 {
808 token=GetToken();
809 if (token=="DIALOG")
810 ParseDialog(prevtok);
811 else if (token=="MENU")
812 ParseMenu(prevtok);
813 else if (token=="TOOLBAR")
814 ParseToolBar(prevtok);
815
816 prevtok=token;
817 }
88d42654
VS
818
819}
820
2193517f 821void rc2xml::ParseToolBar(wxString varname)
88d42654 822{
2193517f
VS
823 wxString token;
824 token=GetToken();
825 wxASSERT_MSG(token=="DISCARDABLE","Error in toolbar parsing");
88d42654 826//Look up bitmap for toolbar and load
2193517f
VS
827 wxNode *node=m_bitmaplist->Find(LookUpId(varname));
828 wxString *bitmappath;
829 bitmappath=(wxString *)node->Data();
830 wxBitmap bitmap;
831 if (!bitmap.LoadFile(*bitmappath,wxBITMAP_TYPE_BMP ))
832 wxLogError("Unable to load bitmap:"+*bitmappath);
88d42654
VS
833
834//Write toolbar to xml file
e066e256 835 m_xmlfile.Write(" <object class=\"wxToolBar\"");
88d42654 836//Avoid duplicate names this way
2193517f
VS
837 varname.Replace("IDR_","TB_");
838 WriteName(varname);
839 m_xmlfile.Write(">\n");
840 wxString style;
841 style+="wxTB_FLAT";
842 WriteStyle(style);
88d42654 843
88d42654
VS
844
845//Grab width and height
2193517f
VS
846 int width,height;
847 width=atoi(GetToken());
848 height=atoi(GetToken());
849
850 int c=0;
851 wxString buttonname,msg,tip,longhelp;
852 token=GetToken();
853 while ((token!="BEGIN"))
854 token=GetToken();
855
856 while ((token!="END")&(token!="}"))
857 {
858 if (token=="BUTTON")
859 {
860 buttonname=GetToken();
e066e256 861 m_xmlfile.Write("\t\t\t<object class=\"tool\"");
2193517f
VS
862 WriteName(buttonname);
863 m_xmlfile.Write(">\n");
864 //Write tool tip if any
865 if (LookUpString(buttonname,msg))
866 {
867 SplitHelp(msg,tip,longhelp);
868 m_xmlfile.Write("\t\t\t\t<tooltip>"+tip+"</tooltip>\n");
869 m_xmlfile.Write(" <longhelp>"+longhelp+"</longhelp>\n");
870 }
871 //Make a bitmap file name
872 buttonname=CleanName(buttonname);
873 buttonname+=".bmp";
874 m_xmlfile.Write("\t\t\t\t<bitmap>"+buttonname+"</bitmap>\n");
875 WriteToolButton(buttonname,c,width,height,bitmap);
e066e256 876 m_xmlfile.Write("\t\t\t</object>\n");
2193517f
VS
877 c++;
878 }
879 else if (token=="SEPARATOR")
880 {
e066e256 881 m_xmlfile.Write("\t\t\t<object class=\"separator\"/>\n");
2193517f
VS
882 }
883 token=GetToken();
884 }
e066e256 885 m_xmlfile.Write("\t</object>\n");
88d42654
VS
886}
887
888//Extract bitmaps from larger toolbar bitmap
2193517f 889void rc2xml::WriteToolButton(wxString name,int index, int width, int height, wxBitmap bitmap)
88d42654 890{
2193517f
VS
891 int x;
892 x=index*width;
893 wxRect r(x,0,width,height);
894 wxBitmap little;
895 little=bitmap.GetSubBitmap(r);
2c99715a 896 little.SaveFile(m_targetpath+name,wxBITMAP_TYPE_BMP);
88d42654
VS
897}
898
2193517f 899void rc2xml::ParseStringTable(wxString varname)
88d42654 900{
2193517f
VS
901 wxString token;
902 token=GetToken();
903 while ((token!="BEGIN"))
904 token=GetToken();
905 token=GetToken();
906 wxString *msg;
907
908 while ((token!="END")&(token!="}"))
909 {
910 msg=new wxString;
911 *msg=GetQuoteField();
912 m_stringtable->Append(token,msg);
913 token=GetToken();
914 }
88d42654
VS
915
916}
917
2193517f 918bool rc2xml::LookUpString(wxString strid,wxString & st)
88d42654 919{
2193517f
VS
920 wxNode *node=m_stringtable->Find(strid);
921 wxString *s;
922 if (node==NULL)
923 return FALSE;
88d42654 924
2193517f
VS
925 s=(wxString *)node->Data();
926 st=*s;
88d42654 927
2193517f 928 return TRUE;
88d42654
VS
929}
930
2193517f 931bool rc2xml::SplitHelp(wxString msg, wxString &shorthelp, wxString &longhelp)
88d42654 932{
2193517f
VS
933 int spot;
934 spot=msg.Find("\\n");
935 if (spot==-1)
936 {
937 shorthelp=msg;
938 longhelp=msg;
939 }
940
941 longhelp=msg.Left(spot);
942 spot=msg.Length()-spot-2;
943 shorthelp=msg.Right(spot);
944 return TRUE;
88d42654
VS
945}
946
2193517f 947void rc2xml::ParseMenuItem()
88d42654 948{
2193517f
VS
949 wxString token,name,msg,tip,longhelp;
950//int spot;
951 if (PeekToken()=="SEPARATOR")
952 {
e066e256 953 m_xmlfile.Write("\t\t\t<object class=\"separator\"/>\n");
2193517f
VS
954 return;
955 }
956
957 token=GetQuoteField();
958 name=GetToken();
959//Remove \t because it causes problems
960//spot=token.First("\\t");
961//token=token.Left(spot);
e066e256 962 m_xmlfile.Write("\t\t\t<object class=\"wxMenuItem\"");
2193517f
VS
963 WriteName(name);
964 m_xmlfile.Write(">\n");
965 WriteLabel(token);
88d42654 966//Look up help if any listed in stringtable
2193517f
VS
967 if (LookUpString(name,msg))
968 {
969 SplitHelp(msg,tip,longhelp);
970 m_xmlfile.Write("\t\t\t<help>"
971 +longhelp+"</help>\n");
972 }
88d42654 973//look for extra attributes like checked and break
2193517f
VS
974 wxString ptoken;
975 ptoken=PeekToken();
976 while ((ptoken!="MENUITEM")&(ptoken!="POPUP")&(ptoken!="END"))
977 {
978 token=GetToken();
979 if (token=="CHECKED")
980 m_xmlfile.Write("\t\t\t<checkable>1</checkable>\n");
981 else if (token=="MENUBREAK");
982//m_xmlfile.Write("\t\t\t</break>\n");
983 else if (token=="GRAYED");
984 else
985 wxLogError("Unknown Menu Item token:"+token);
986
987 ptoken=PeekToken();
988 }
e066e256 989 m_xmlfile.Write("\t\t\t</object>\n");
88d42654
VS
990
991}
992
993//ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
2193517f 994void rc2xml::ParseIconStatic()
88d42654 995{
2193517f
VS
996 wxString token;
997 wxString varname,iconname;
998 iconname=GetToken();
88d42654 999//Look up icon
2193517f 1000 varname=GetToken();
88d42654 1001
2193517f
VS
1002 int x,y,width,height;
1003 ReadRect(x,y,width,height);
88d42654 1004
e066e256 1005 m_xmlfile.Write("\t\t<object class=\"wxStaticBitmap\"");
2193517f 1006 WriteBasicInfo(x,y,width,height,varname);
88d42654 1007//Save icon as a bitmap
2193517f 1008 WriteIcon(iconname);
e066e256 1009 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1010
1011}
1012//IDR_MAINFRAME ICON DISCARDABLE "res\\mfcexample.ico"
2193517f 1013void rc2xml::ParseIcon(wxString varname)
88d42654 1014{
2193517f
VS
1015 wxString token,*iconfile;
1016 iconfile=new wxString;
1017 token=PeekToken();
88d42654 1018
2193517f
VS
1019 *iconfile=GetQuoteField();
1020 m_iconlist->Append(varname,iconfile);
1021
88d42654
VS
1022
1023}
1024
2193517f 1025wxString rc2xml::CleanName(wxString name)
88d42654 1026{
2193517f
VS
1027 name.MakeLower();
1028 name.Replace("id_","");
1029 name.Replace("idr_","");
1030 name.Replace("idb_","");
1031 name.Replace("idc_","");
2c99715a
VS
1032 name.Replace(".ico","");
1033 name.Replace(".bmp","");
2193517f 1034 return name;
88d42654
VS
1035}
1036// And the award for most messed up control goes to...
1037// CONTROL IDB_FACE,IDC_STATIC,"Static",SS_BITMAP,26,62,32,30
2193517f 1038void rc2xml::ParseStaticBitmap(wxString bitmapname, wxString varname)
88d42654 1039{
2193517f
VS
1040 wxString token;
1041 //Grab SS_BITMAP
1042 token=GetToken();
1043
88d42654 1044
88d42654 1045
2193517f
VS
1046 int x,y,width,height;
1047 ReadRect(x,y,width,height);
1048
e066e256 1049 m_xmlfile.Write("\t\t<object class=\"wxStaticBitmap\"");
2193517f
VS
1050 WriteBasicInfo(x,y,width,height,varname);
1051 WriteBitmap(bitmapname);
e066e256 1052 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1053
1054}
1055
2193517f 1056void rc2xml::ParseNormalMSControl()
88d42654
VS
1057{
1058wxString label,varname,kindctrl;
1059
1060label=GetQuoteField();
1061varname=GetToken();
1062kindctrl=GetQuoteField();
1063kindctrl.MakeUpper();
1064
2193517f
VS
1065 if (kindctrl=="MSCTLS_UPDOWN32")
1066 ParseSpinCtrl(label,varname);
1067 if (kindctrl=="MSCTLS_TRACKBAR32")
1068 ParseSlider(label,varname);
1069 if (kindctrl=="MSCTLS_PROGRESS32")
1070 ParseProgressBar(label,varname);
1071 if (kindctrl=="SYSTREEVIEW32")
1072 ParseTreeCtrl(label,varname);
1073 if (kindctrl=="SYSMONTHCAL32")
1074 ParseCalendar(label,varname);
1075 if (kindctrl=="SYSLISTVIEW32")
1076 ParseListCtrl(label,varname);
1077 if (kindctrl=="BUTTON")
1078 ParseCtrlButton(label,varname);
1079 if (kindctrl=="RICHEDIT")
1080 ParseRichEdit(label,varname);
88d42654
VS
1081
1082}
1083
2193517f 1084void rc2xml::ParseWeirdMSControl()
88d42654 1085{
2193517f
VS
1086 wxString kindctrl;
1087 wxString varname;
1088 wxString id;
1089 id=GetToken();
1090 varname=GetToken();
1091 kindctrl=GetQuoteField();
1092 kindctrl.MakeUpper();
88d42654 1093// CONTROL IDB_FACE,IDC_STATIC,"Static",SS_BITMAP,26,62,32,30
2193517f
VS
1094 if (kindctrl=="STATIC")
1095 {
1096 if (PeekToken()=="SS_BITMAP")
1097 ParseStaticBitmap(id,varname);
1098 else
1099 wxLogError("Unknown MS Control Static token");
1100 }
88d42654
VS
1101
1102}
1103//SCROLLBAR IDC_SCROLLBAR1,219,56,10,40,SBS_VERT
1104
2193517f 1105void rc2xml::ParseScrollBar()
88d42654 1106{
2193517f
VS
1107 wxString token;
1108 wxString varname;
1109
1110 varname=GetToken();
1111 int x,y,width,height;
1112 ReadRect(x,y,width,height);
1113 wxString style;
1114
1115 ReadOrs(token);
1116
1117if (token.Find("SBS_VERT")!=-1)
1118 style=_T("wxSB_VERTICAL");
88d42654 1119//Default MFC style is horizontal
2193517f
VS
1120 else
1121 style=_T("wxSB_HORIZONTAL");
88d42654 1122
e066e256 1123 m_xmlfile.Write("\t\t<object class=\"wxScrollBar\"");
2193517f
VS
1124 WriteBasicInfo(x,y,width,height,varname);
1125 WriteStyle(style);
e066e256 1126 m_xmlfile.Write("\n\t\t</object>\n");
88d42654
VS
1127
1128}
1129// CONTROL "Tree1",IDC_TREE1,"SysTreeView32",WS_BORDER | WS_TABSTOP,
1130// 7,7,66,61
1131
2193517f 1132void rc2xml::ParseTreeCtrl(wxString label, wxString varname)
88d42654 1133{
2193517f
VS
1134 wxString token;
1135//while (ReadOrs(token));
1136 ReadOrs(token);
1137 int x,y,width,height;
1138 ReadRect(x,y,width,height);
e066e256 1139 m_xmlfile.Write("\t\t<object class=\"wxTreeCtrl\"");
2193517f 1140 WriteBasicInfo(x,y,width,height,varname);
e066e256 1141 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1142
1143}
1144// CONTROL "MonthCalendar1",IDC_MONTHCALENDAR1,"SysMonthCal32",
1145 //MCS_NOTODAY | WS_TABSTOP,105,71,129,89
1146
2193517f 1147void rc2xml::ParseCalendar(wxString label, wxString varname)
88d42654 1148{
2193517f
VS
1149 wxString token;
1150//while (ReadOrs(token));
1151 ReadOrs(token);
1152 int x,y,width,height;
1153 ReadRect(x,y,width,height);
e066e256 1154 m_xmlfile.Write("\t\t<object class=\"wxCalendarCtrl\"");
2193517f 1155 WriteBasicInfo(x,y,width,height,varname);
e066e256 1156 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1157}
1158// CONTROL "List1",IDC_LIST1,"SysListView32",WS_BORDER | WS_TABSTOP,
1159 // 7,89,68,71
1160
2193517f 1161void rc2xml::ParseListCtrl(wxString label, wxString varname)
88d42654 1162{
2193517f
VS
1163 wxString token;
1164 //while (ReadOrs(token));
1165 ReadOrs(token);
1166 int x,y,width,height;
1167 ReadRect(x,y,width,height);
e066e256 1168 m_xmlfile.Write("\t\t<object class=\"wxListCtrl\"");
2193517f 1169 WriteBasicInfo(x,y,width,height,varname);
e066e256 1170 m_xmlfile.Write("\t\t</object>\n");
88d42654
VS
1171
1172}
2193517f
VS
1173
1174void rc2xml::WriteBitmap(wxString bitmapname)
1175{
1176//Look up bitmap
1177 wxNode *node=m_bitmaplist->Find(LookUpId(bitmapname));
1178 if (node==NULL)
1179 {
1180 m_xmlfile.Write("\t\t\t<bitmap>missingfile</bitmap>\n");
1181 wxLogError("Unable to find bitmap:"+bitmapname);
1182 return;
1183 }
1184
1185 wxString *bitmappath;
1186 bitmappath=(wxString *)node->Data();
2c99715a 1187 bitmapname=wxFileNameFromPath(*bitmappath);
2193517f
VS
1188 wxBitmap bitmap;
1189 if (!bitmap.LoadFile(*bitmappath,wxBITMAP_TYPE_BMP ))
1190 wxLogError("Unable to load bitmap:"+*bitmappath);
1191
1192 //Make a bitmap file name
1193 bitmapname=CleanName(bitmapname);
1194 bitmapname+=".bmp";
1195 m_xmlfile.Write("\t\t\t<bitmap>"+bitmapname+"</bitmap>\n");
2c99715a 1196 bitmap.SaveFile(m_targetpath+bitmapname,wxBITMAP_TYPE_BMP);
2193517f
VS
1197}
1198
1199void rc2xml::WriteIcon(wxString iconname)
1200{
1201wxNode *node=m_iconlist->Find(iconname);
1202 if (node==NULL)
1203 {
1204 m_xmlfile.Write("\t\t\t<bitmap>missing_file</bitmap>\n");
1205 wxLogError("Unable to find icon:"+iconname);
1206 }
1207 wxString *iconpath;
1208 iconpath=(wxString *)node->Data();
1209 wxIcon icon;
1210 wxBitmap bitmap;
1211 if (!icon.LoadFile(*iconpath,wxBITMAP_TYPE_ICO ))
1212 wxLogError("Unable to load icon:"+*iconpath);
1213#ifdef __WXMSW__
1214 bitmap.CopyFromIcon(icon);
1215#else
1216 bitmap = icon;
1217#endif
2c99715a 1218 iconname=wxFileNameFromPath(*iconpath);
2193517f
VS
1219 //Make a bitmap file name
1220 iconname=CleanName(iconname);
1221 iconname+=".bmp";
1222 m_xmlfile.Write("\t\t\t<bitmap>"+iconname+"</bitmap>\n");
2c99715a 1223 bitmap.SaveFile(m_targetpath+iconname,wxBITMAP_TYPE_BMP);
2193517f
VS
1224
1225
1226}
1227/*Unfortunately sometimes the great MSVC Resource editor decides
1228to use numbers instead of the word id. I have no idea why they
1229do this, but that is the way it is.
1230*/
1231/* this is a quick and dirty way to parse the resource.h file
1232it will not recognize #ifdef so it can be easily fooled
1233*/
1234void rc2xml::ParseResourceHeader()
1235{
1236wxTextFile r;
1237//Attempt to load resource.h in current path
1238 if (!r.Open("resource.h"))
1239 {
1240 wxLogError("Warining Unable to load resource.h file");
1241 return;
1242 }
1243
1244 wxString str;
1245 wxString id,v;
1246 wxStringTokenizer tok;
1247 wxString *varname;
1248
1249
1250 long n;
1251
1252//Read through entire file
1253 for ( str = r.GetFirstLine(); !r.Eof(); str = r.GetNextLine() )
1254 {
1255 if (str.Find("#define")!=-1)
1256 {
1257 tok.SetString(str);
1258 //Just ignore #define token
1259 tok.GetNextToken();
1260 v=tok.GetNextToken();
1261 id=tok.GetNextToken();
1262 if (id.IsNumber())
1263 {
1264 varname=new wxString;
1265 id.ToLong(&n);
1266 *varname=v;
1267 m_resourcelist->Append(n,varname);
1268 }
1269 }
1270 }
1271
1272
1273
1274}
1275
1276
1277wxString rc2xml::LookUpId(wxString id)
1278{
1279wxString st;
1280
1281if (!id.IsNumber())
1282 return id;
1283long n;
1284id.ToLong(&n);
1285wxNode *node=m_resourcelist->Find(n);
1286 wxString *s;
1287 if (node==NULL)
1288 return id;
1289
1290 s=(wxString *)node->Data();
1291 st=*s;
1292return st;
1293}