home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / contrib / utils / convertrc / rc2xml.cpp < prev    next >
C/C++ Source or Header  |  2001-10-30  |  32KB  |  1,302 lines

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