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