    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Wx - A Live Port</title>
        <link>https://members.accu.org/index.php/journals/703</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">CVu Journal Vol 16, #5 - Oct 2004 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c100/">165</a>
                    (13)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c100-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c100+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Wx - A Live Port</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 October 2004 13:16:08 +01:00 or Sun, 03 October 2004 13:16:08 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>This is a collection of notes I have made while porting an application from MFC to wxWidgets. It is intended partly as a tutorial and partly to document some of the roadblocks I met on the way.</p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e22" id="d0e22"></a></h2>
</div>
<p><span class="emphasis"><em>Moving beyond MFC and opening new
horizons with wxWidgets.</em></span></p>
<p>This is a collection of notes I have made while porting an
application from MFC to wxWidgets. It is intended partly as a
tutorial and partly to document some of the roadblocks I met on the
way. Right now it has gaping holes in it that are gradually being
filled. When I upgraded from DOS to Windows 3.1 and purchased
Microsoft Visual C++ version 1, a whole new world opened up. The
massive framework allowed me to be writing fully fledged GUI
applications in a few short weeks and a world of creative
opportunity was opened up.</p>
<p>The software was exceptional value coming with a formidable
array of manuals that I would leaf through in my spare time. Over
the years I and my software company built up a large software
library of applications related to marine weather, communication
and navigation, and our products sold well on the world market.
With recent events in the software world and a global shifting
towards Linux as a viable alternative there is a growing need for
code that is portable.</p>
<p>As this trend seemed to gather momentum, I started to refine my
search and start to look more actively for avenues to port my
software. With the launch of Visual Studio .NET I had to make a
decision. Most of what .NET was about seemed to lack co-ordination
and it did not seem to have relevance to ships at sea far away from
broadband internet. So I chose to stop with Visual Studio 6 and
keep up to date with MSDN subscriptions. Not allowed - my next set
of disks had &quot;For Use with Visual Studio .NET only&quot; written on
them. And that was the end of that - I was out in the pasture and
in need of a new approach to keep 20 man-years of work viable long
term.</p>
<p>I looked again at Linux and KDevelop, to mention a few
environments. While I am extremely encouraged by the progress Linux
is making it is still not up to Windows when it comes to bringing
new users in, and hardware installation though robust is still
extremely intimidating if you are not an expert. The documentation
is excellent but it does need somebody with a leaning towards
systems to get into it. This is changing though very rapidly and I
am predicting that Linux will overtake Windows in the very near
future as the momentum builds up. So this makes a port even more
urgent.</p>
<p>I discovered wxWidgets almost by accident. A friend mentioned in
passing and I visited the website, downloaded the kit and started
to play with it.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e37" id="d0e37"></a>The Initial
Impression</h2>
</div>
<p>I started with version 2.4.0 and compared it to MFC. I was
surprised to discover that the framework is 10 years old, very
mature and stable. Quite a few hands have contributed over the
years. Most important it is all source code, well written and
intuitive. Well the first job I had to do was compile it all. Oh
dear - here we go I thought, gritting my teeth, and selected
<span class="guimenuitem">Batch</span> build from the Visual Studio
options. I went off to make a cup of tea and almost spilled it over
the keyboard when I got back because the whole thing had compiled
properly and built all the libraries. A very encouraging start.</p>
<p>So what could the kit do?</p>
<p>I ran up the samples and they all compiled. I looked at the code
and although the architecture was not the same as I was used to I
could see the similarities. I was used to the Stygian macros and
confusing comments App Wizard puts in. Not being too concerned with
the nitty gritty, I would normally let App Wizard build a template
and I would plug in the bits as I learned in my old scribble
tutorial many years ago. So it took a little bit of exploring and
tracing to see what was actually going on.</p>
<p>At this point I went back on the internet to see if I could find
some resources.</p>
<p>I found two excellent articles by Marcus Neifer: <i class=
"citetitle">Porting MFC Applications to Linux</i>, and also a good
wxWidgets primer: <i class="citetitle">Looking Through wxWidgets:
An Intro to the Portable C++ and Python GUI Toolkit</i>.</p>
<p>These two articles convinced me that there was something worth
pursuing here. So I started my evaluation in earnest to see how the
kit could meet our needs. Firstly I looked at the DocView MDI
sample that emulates the Scribble sample that all MFC trainees used
to start with. The code is a good deal lighter in weight though. I
was particularly interested to see if all the little nuances our
clients were used to were supported. Tool tips and Help on the
status bar ware two I items I went looking for. Menu creation and
toolbar interaction with the code were other areas that differed
quite a bit from the old MFC way of doing things. I could not find
an easy way to make the toolbar dockable but I did not look very
hard - that is a bit of a gimmick at least in our apps. There was
the option of trying to convert the MFC <tt class=
"filename">.rc</tt> to the new XML format that wxWidgets is using.
I had only very limited success with that route and preferred to go
the conservative mothod of putting everything in C++ code, I
followed that methodology. In my opinion clearly commented code
beats everything else when it comes to reviewing something a few
years down the road.</p>
<p>Next the interaction with the users was examined. I latched on
to wxDesigner as the tool of choice. The tool uses a completely
different concept to the VC++ method of constructing a dialog. It
uses what we call sizers to group and encapsulate controls in boxes
or groups. Once you get the hang of it, it is a very quick way of
creating an attractive looking dialog. The software also generates
a wrapper so you can run the dialog as a stand alone program. An
excellent way to jump start an application.</p>
<p>However my main focus was to take an existing application and
port it to wxWidgets. This required an in-depth view as to how the
two architectures differ. It also needs a thorough review of all
the underlying capabilities of the GUI, how the tool bars and menus
behave, what context help support is around. One of the biggest
advantages of Windows is the redundancy of the help system and the
embedded context-sensitive actions that are available.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e68" id="d0e68"></a>Navigating the
Library</h2>
</div>
<p>Now we have decided that wxWidgets as the tool of choice, we now
have to come to grips with it. In my trainee programming days I was
taught to help myself and to find the resources I need in the
documentation. In those days this meant poring over voluminous
books. Today of course the CD-ROM and HTML have made this all a lot
easier. The wxWidgets help file comes in many flavours. My choice
is the HTML help version. Now we are going to be reading this a
lot. Unlike many programming tomes, I am not proposing to fill out
the pages with vast chunks from the manual. You are going to have
to go out there yourself and find it.</p>
<p>The first thing I did was to add the wxWidgets help into the
MSVC++ tools menu - an area where you can add custom features. In
the tools menu:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Go to <span class="guimenu">Customize</span></p>
</li>
<li>
<p>Go to the <span class="guisubmenu">Tools</span> tab and add an
entry <span class="guimenuitem">wxWidgets</span> help</p>
</li>
<li>
<p>Create a keyboard shortcut <span class="keysym">SHIFT
F1</span></p>
</li>
<li>
<p>Add the the following command: <tt class=
"filename">hh.exe</tt></p>
</li>
<li>
<p>Add as arguments: <tt class=
"filename">C:\wxWidgets_2.4.0\docs\htmlhelp\wx.chm</tt></p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e105" id="d0e105"></a>A Tour of the
wxWidgets Documentation</h2>
</div>
<p>The core of the wxWidgets documentation is the alphabetical
class library reference. It is largely complete however some
sections may be very terse. All the source code is available and if
you are struggling - why not use the MSVC browser and take a look
through some of the source code. Unlike some GUI libraries it is
very clear and well written.</p>
<p>Some of the tutorials I have mentioned to date can help although
to get a basic understanding of the framework components I strongly
recommend you take a tour of the samples supplied. They are clear
and address a very specific point. As a last resort there is
<tt class="email">&lt;<a href=
"mailto:wx-Users@lists.wxwidgets.org">wx-Users@lists.wxwidgets.org</a>&gt;</tt>.
Here you will get an answer to a question very quickly. Several of
the sticking points I encountered were answered, once within 3
minutes on a Sunday. Try getting commercial support of that
quality!</p>
<p>The downside is that you need to be patient and do not expect
anything. The open source model is a two-edged sword. The
contributors are not paid.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e117" id="d0e117"></a>Let's Create
a Window</h2>
</div>
<p>This is the very basis of a nugget of user interface code.</p>
<p>The class you will be using is <tt class=
"classname">wxFrame</tt> - derived from <tt class=
"classname">wxWindow</tt>. Like <tt class="classname">CWnd</tt>,
<tt class="classname">wxWidgets</tt> has a huge bewildering array
of sub functions that drive the application.</p>
<p>Here is the basic code to pop up a single window.</p>
<pre class="programlisting">
wxPoint pt(20,20); // where the window will
                   // appear
wxSize sz (600,400); // the window size

WxFrame *FrameWindow = new wxFrame;;
WxFrame-&gt;Create(frame, -1, &quot;Key&quot;,
                pt, sz, 
                wxDefault,
                &quot;wxWindow sample&quot;);
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e140" id="d0e140"></a>A More
Complex Window</h2>
</div>
<p>Both MFC and wxWidgets support the Document/View approach. The
concept here is the application launches a Main Frame that contains
the primary controls. The Main Frame has Child Frames (in the
Multiple Document Interface world) The Child Frame has views and
and a class that manipulates the document and supports reading,
writing, etc.</p>
<p>The Visual C++ App wizard makes one's life very easy by
generating a bare bones application with the following
components:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Application registration - Associating a file type with the
application.</p>
</li>
<li>
<p>Drag and drop support of files onto the application main
frame.</p>
</li>
<li>
<p>Context sensitive help</p>
</li>
<li>
<p>Command line processing</p>
</li>
<li>
<p>Print and Print Preview</p>
</li>
</ul>
</div>
<p>In wxWidgets all this has to be done yourself. Of course many
simple applications do not need all this baggage, however if you
are developing a full fledged application that meets the criteria
of a modern day system you must include this functionality. We will
start by laying out a bare bones framework and build our
application from there.</p>
<p>The MFC Document template approach has close parallels. You draw
up a document that has a filter for the <span class=
"guimenu">File</span> <span class="guimenuitem">open</span> and a
specific extension. The framework uses this template to manipulate
your data via file open, most recently used document etc.</p>
<p>In MFC the View is subclassed from the Child Frame, whereas in
wxWidgets you need to explicitly create your own Frame. This was
the most important difference I found and thus the <tt class=
"methodname">OnDraw</tt> member of the view class had to be invoked
from the Sub Frame Window class. I followed the design of the
<tt class="filename">docviewmdi</tt> sample and used the <tt class=
"classname">MyCanvas</tt> class from there. Other little
differences were the more modular way the menus work and especially
getting the help tips to show on the main frame status bar. I ended
up creating a second status bar on the <tt class=
"classname">Frame</tt> window for the time being for reading the
menu help tips. It is a good idea to port the App routine first.
Command line processing Drag and Drop, Document template, and
Registry profile strings should be sorted out at the very first
step. The <tt class="function">wxConfig</tt> function is very
useful here for storing profile data, windows size and other
variables you need to store. Non persistent applications where you
have to set everything up again when you run the program are a
trademark of the amateur.</p>
<p>Since we have the view creating a child window we need to make
sure it is closed when the view is closed. I followed the examples
and used a scroll window called canvas locally. This code is lifted
almost verbatim from the <tt class="filename">DocViewMDI</tt>
sample that forms a reasonable basis for starting.</p>
<pre class="programlisting">
// Clean up windows used for displaying the
// view.
bool WXWindPlotView::OnClose(
                          bool deleteWindow) {
  if(!GetDocument()-&gt;Close())
    return FALSE;

  // Clear the canvas in case we're in single-
  // window mode, and the canvas stays
  canvas-&gt;Clear();
  canvas-&gt;view = (WXWindPlotView *)NULL;
  canvas = (MyCanvas *)NULL;

  wxString s(wxTheApp-&gt;GetAppName());

  if (frame)
    frame-&gt;SetTitle(s);

  SetFrame((wxFrame*)NULL);
  Activate(FALSE);
  
  if(deleteWindow) {
    delete frame;
    return TRUE;
  }
  return TRUE;
}
</pre>
<p>Once I had everything in place I could start dropping in chunks
of code from the MFC app and let the compiler crank through the
errors.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e199" id="d0e199"></a>The Port in
Detail</h2>
</div>
<p>Step 1 was to remove all includes for <tt class=
"filename">windows.h</tt> and <tt class="filename">stdafx.h</tt>.
Now we are are a huge step to throwing off the Microsoft yoke and
out there in the real world at last. All those windows functions
that are not in the wxWidgets library are going to have to be found
in the the ANSI C libraries. The first one I came up against was
<tt class="function">GlobalLock</tt> to allocate memory. Several
lines of code were replaced with a simple <tt class=
"literal">malloc</tt> statement - and a <tt class=
"literal">free</tt> in the destructor.</p>
<p>The sidebar contains a great little macro to speed up your
work.</p>
<div class="sidebar">
<pre class="programlisting">
'-----------------
'FILE DESCRIPTION: New Macro File
'-----------------
Sub wxconvert()
'DESCRIPTION: Convert MFC to wxWindows
'Begin Recording
  ActiveDocument.ReplaceText &quot;Bool&quot;,&quot;bool&quot;
  ActiveDocument.ReplaceText &quot;CString&quot;,&quot;wxString&quot;
  ActiveDocument.ReplaceText &quot;CFile&quot;,&quot;wxFile&quot;
  ActiveDocument.ReplaceText &quot;CTime&quot;,&quot;wxDateTime&quot;
  ActiveDocument.ReplaceText &quot;.GetLength&quot;,&quot;.Length&quot;
  ActiveDocument.ReplaceText &quot;.GetBuffer&quot;,&quot;.GetData&quot;
  ActiveDocument.ReplaceText &quot;CCmdUI* pCmdUI&quot;,
                            &quot;wxUpdateUIEvent&amp; event&quot;
  ActiveDocument.ReplaceText &quot;ON_COMMAND&quot;,&quot;EVT_MENU&quot;
  ActiveDocument.ReplaceText &quot;ON_UPDATE_COMMAND_UI&quot;,
                                     &quot;EVT_UPDATE_UI&quot;
  ActiveDocument.ReplaceText &quot;  afx_msg &quot;,&quot;&quot;
  ActiveDocument.ReplaceText &quot;CSize&quot;,&quot;wxSize&quot;
  ActiveDocument.ReplaceText &quot;AfxGetApp()-&gt;&quot;,
                                       &quot;wxGetApp().&quot;
  ActiveDocument.ReplaceText &quot;AfxMessageBox&quot;,
                                      &quot;wxMessageBox&quot;
  ActiveDocument.ReplaceText &quot;CFrameWnd&quot;,&quot;wxFrame&quot;
  ActiveDocument.ReplaceText &quot;::modeRead&quot;,&quot;::Read&quot;
  ActiveDocument.ReplaceText &quot;DWORD&quot;,&quot;unsigned int&quot;
  ActiveDocument.ReplaceText &quot;GlobalAlloc(
                    GMEM_MOVEABLE | GMEM_ZEROINIT,&quot;,
                          &quot;(unsigned char *) malloc&quot;
  ActiveDocument.ReplaceText &quot;GlobalAlloc(
                   GMEM_MOVEABLE | GMEM_ZEROINIT, &quot;,
                          &quot;(unsigned char *) malloc&quot;
  ActiveDocument.ReplaceText &quot;LPSTR&quot;,&quot;char *&quot;
  ActiveDocument.ReplaceText &quot;pCmdUI-&gt;SetCheck&quot;,
                                       &quot;event.Check&quot;
  ActiveDocument.ReplaceText &quot;pCmdUI-&gt;&quot;,&quot;event.&quot;
  ActiveDocument.ReplaceText &quot;CPen&quot;,&quot;wxPen&quot;
  ActiveDocument.ReplaceText &quot;CBrush&quot;,&quot;wxBrush&quot;
  ActiveDocument.ReplaceText &quot;CRect&quot;,&quot;wxRect&quot;
  ActiveDocument.ReplaceText &quot;CPoint&quot;,&quot;wxPoint&quot;
  ActiveDocument.ReplaceText &quot;pDoc-&gt;&quot;,&quot;doc-&gt;&quot;
  ActiveDocument.ReplaceText &quot;-&gt;TextOut&quot;,&quot;-&gt;DrawText&quot;
  ActiveDocument.ReplaceText &quot;-&gt;LineTo&quot;,&quot;-&gt;DrawLine&quot;
  ActiveDocument.ReplaceText &quot;DWORD&quot;,&quot;unsigned int&quot;
'End Recording
End Sub
</pre></div>
<p>Most wxWidgets classes are counterparts of MFC and there is
normally a 1-to-1 correlation. <tt class="classname">wXstring</tt>
and <tt class="classname">CString</tt> are very similar as is
<tt class="classname">DC</tt> - <tt class="classname">wxDC</tt>.
Others are not quite the same. <tt class="classname">CTime</tt> is
replaced by <tt class="classname">wxDateTime</tt> that has slightly
different construction and considerably more functionality.
<tt class="classname">MoveTo</tt> and <tt class=
"classname">LineTo</tt> are replaced by one call in wxWidgets -
<tt class="classname">DrawLine</tt>. Eventually somebody will write
a porting macro. I was tempted to batch some edit commands together
but resisted. The process went quite fast and it is better to keep
an eye on where the code is changing.</p>
<p>One thing to look out for is making sure you have all the right
includes. If a class is not found whizz over to the documentation.
Every class has a <tt class="literal">#include</tt> associated with
it.</p>
<p>It is certainly not a plug compatibility and where there is a
difference you can be sure that wxWidgets is more intuitive and
better thought out. Best of all the compiler does all the hard
work. I linked the <span class="keysym">Shift F1</span> key in
Visual Studio to bring up the wxWidgets help file. It is very
complete and it is very easy to jump to the relevant section and
find out what each class is about. In a very short time I was
reaming out whole sections of code and getting them to run. File IO
was simplified. <tt class="literal">try</tt> and <tt class=
"literal">catch</tt> were not supported but then I do not use
exceptions much.</p>
<p>Certain things to look out for: <tt class=
"methodname">wxString::Format</tt> has the same syntax as the MFC
equivalent but with a difference you need to assign it i.e.</p>
<pre class="programlisting">
CString str;
str.Format(&quot;%i&quot;,Integer);

wxString str;
str = str.Format(&quot;%i&quot;,Integer);
</pre>
<p>I personally like to expand out my code for readability and thus
the wX implementation makes more sense.</p>
<p>Another difference is the drawing functions of <tt class=
"classname">wxDC</tt>.</p>
<p>Functions like ellipse (<tt class="methodname">DrawEllipse</tt>)
use starting coordinates and dimension as opposed to starting and
ending coordinates. <tt class="methodname">wXDC::DrawText</tt> is
similar to <tt class="methodname">CDC::TextOut</tt> but the text
only is drawn making an initial rectangle draw necessary to wipe
out the old text and avoid overlaying. This in fact solved a lot of
irritating quirks I experienced with MFC and trying to get a
mixture of text and graphics to stop interfering with each
other.</p>
<p>So you see that there is some work to do here and it is not a
straight conversion exercise at all. However the compiler is a
great help and guides your work. My methodology was to open up
little bits of functionality at a time. Now the first port is
behind me I will probably adopt a more confident holistic
strategy.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e296" id="d0e296"></a>Designing the
User Interface</h2>
</div>
<p>I started creating the toolbar manually from the samples. This
is reasonably easy but is time-consuming and takes a bit of care as
the coding is quite critical in places. Using wXDesigner automates
this process. The menus and tool bars can be very easily laid out
.</p>
<p>To generate an app from scratch using existing bitmaps and menu
structures from the old program took an hour and a half with 15
toolbar buttons and 8 main menus.</p>
<p>Visual C++ is a bit easier and more intuitive but of course you
are only coding for one platform. After a few minutes with
wXDesigner you will get the hang of it and you will find it is a
very much worth the money you have paid for it.</p>
<p>You need to be aware of the symbolic event Ids - some of them
exist already as system events. See Table 1 for these</p>
<div class="table"><a name="d0e307" id="d0e307"></a>
<table summary="Symbolic Event IDs" border="1" cellspacing="0">
&lt;colgroup&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;
&lt;col&gt;&lt;/colgroup&gt;
&lt;thead&gt;
<tr>
<th align="left">Name</th>
<th align="left">Value</th>
<th align="left">Name</th>
<th align="left">Value</th>
</tr>
&lt;/thead&gt;
&lt;tbody&gt;
<tr>
<td align="left">wxID_LOWEST</td>
<td align="left">4999</td>
<td align="left">wxID_PASTE</td>
<td align="left">5032</td>
</tr>
<tr>
<td align="left">wxID_OPEN</td>
<td align="left">5000</td>
<td align="left">wxID_CLEAR</td>
<td align="left">5033</td>
</tr>
<tr>
<td align="left">wxID_CLOSE</td>
<td align="left">5001</td>
<td align="left">wxID_FIND</td>
<td align="left">5034</td>
</tr>
<tr>
<td align="left">wxID_NEW</td>
<td align="left">5002</td>
<td align="left">wxID_DUPLICATE</td>
<td align="left">5035</td>
</tr>
<tr>
<td align="left">wxID_SAVE</td>
<td align="left">5003</td>
<td align="left">wxID_SELECTALL</td>
<td align="left">5036</td>
</tr>
<tr>
<td align="left">wxID_SAVEAS</td>
<td align="left">5004</td>
<td align="left">wxID_FILE1</td>
<td align="left">5050</td>
</tr>
<tr>
<td align="left">wxID_REVERT</td>
<td align="left">5005</td>
<td align="left">wxID_FILE2</td>
<td align="left">5051</td>
</tr>
<tr>
<td align="left">wxID_EXIT</td>
<td align="left">5006</td>
<td align="left">wxID_FILE3</td>
<td align="left">5052</td>
</tr>
<tr>
<td align="left">wxID_UNDO</td>
<td align="left">5007</td>
<td align="left">wxID_FILE4</td>
<td align="left">5053</td>
</tr>
<tr>
<td align="left">wxID_REDO</td>
<td align="left">5008</td>
<td align="left">wxID_FILE5</td>
<td align="left">5054</td>
</tr>
<tr>
<td align="left">wxID_HELP</td>
<td align="left">5009</td>
<td align="left">wxID_FILE6</td>
<td align="left">5055</td>
</tr>
<tr>
<td align="left">wxID_PRINT</td>
<td align="left">5010</td>
<td align="left">ID_FILE7</td>
<td align="left">5056</td>
</tr>
<tr>
<td align="left">wxID_PRINT_SETUP</td>
<td align="left">5011</td>
<td align="left">ID_FILE8</td>
<td align="left">5057</td>
</tr>
<tr>
<td align="left">wxID_PREVIEW</td>
<td align="left">5012</td>
<td align="left">wxID_FILE9</td>
<td align="left">5058</td>
</tr>
<tr>
<td align="left">wxID_ABOUT</td>
<td align="left">5013</td>
<td align="left">wxID_OK</td>
<td align="left">5100</td>
</tr>
<tr>
<td align="left">wxID_HELP_CONTENTS</td>
<td align="left">5014</td>
<td align="left">wxID_CANCEL</td>
<td align="left">5101</td>
</tr>
<tr>
<td align="left">wxID_HELP_COMMANDS</td>
<td align="left">5015</td>
<td align="left">wxID_APPLY</td>
<td align="left">5102</td>
</tr>
<tr>
<td align="left">wxID_HELP_PROCEDURES</td>
<td align="left">5016</td>
<td align="left">wxID_YES</td>
<td align="left">5103</td>
</tr>
<tr>
<td align="left">wxID_HELP_CONTEXT</td>
<td align="left">5017</td>
<td align="left">wxID_NO</td>
<td align="left">5104</td>
</tr>
<tr>
<td align="left">wxID_CUT</td>
<td align="left">5030</td>
<td align="left">wxID_STATIC</td>
<td align="left">5105</td>
</tr>
<tr>
<td align="left">wxID_COPY</td>
<td align="left">5031</td>
<td align="left">wxID_HIGHEST</td>
<td align="left">5999</td>
</tr>
&lt;/tbody&gt;
</table>
<p class="title c3">Table 1. Symbolic Event IDs</p>
</div>
<p>You need to add to the file <tt class="filename">Resource.h</tt>
to manually code in the ID number where your user interface
interacts with the above functions You can put the ID anywhere in a
header file, however, I like to use <tt class=
"filename">Resource.h</tt>.</p>
<p>Otherwise you leave the ID as -1 and wXDesigner will generate
the event entries for you. wXDesigner starts from ID=10000. All you
need to do is use the symbols in your code.</p>
<p>To generate the CPP code press the C++ button in the wXDesigner
and the file <tt class="filename">nnnn_wdr.cpp</tt> is generated,
this file contains all the nasty menu generation code you used to
have. Our Menu bar was called <tt class=
"classname">MainMenuBarFunc</tt>. All you need to do to invoke it
in your main app is to put the following line in the <tt class=
"methodname">App::OnInit()</tt> section:</p>
<pre class="programlisting">
m_mainFrame-&gt;SetMenuBar(MainMenuBarFunc());
</pre>
<p>wXDesigner has already created a shell for you but you probably
want to use your own template. The class browser in MSVC is very
useful. The code generated by wXDesigner does not parse well and
all the functions are in one file. The wrapper wXDesigner generates
it seems is primarily an example shell rather than a starting point
for a GUI application and so far we have been evolving a full scale
MDI program. The shell provided though is very useful to explain
where all the bits plug in.</p>
<p>On the creation of pop-up menus, WXDesigner forces you to use a
menu bar. You can try to override this however I found it easier to
dump the generated code right into the <tt class=
"classname">canvas</tt> class. This code is fairly static and if we
regenerate it is will be fairly easy to dump it in again.</p>
<p>This is what wXDesigner generates:</p>
<pre class="programlisting">
wxMenuBar *PopUpMenuBarFunc() {
  wxMenuBar *item0 = new wxMenuBar;
  wxMenu* item1 = new wxMenu(wxMENU_TEAROFF);
  item1-&gt;Append(wxID_NEW,
                wxT(&quot;&amp;New\tCtrl-N&quot;),
                wxT(&quot;New chart&quot;));
  item1-&gt;Append(ID_GRIB,
                wxT(&quot;&amp;Open\tCtrl-O&quot;),
                wxT(&quot;Open a Grib File&quot;));
  item1-&gt;AppendSeparator();
  item1-&gt;Append(ID_1X,
                wxT(&quot;&amp;1x&quot;),
                wxT(&quot;Zoom 1 times&quot;));
  item1-&gt;Append(ID_2X,
                wxT(&quot;&amp;2x&quot;),
                wxT(&quot;Zoom 2 times&quot;));
  item1-&gt;Append(ID_3X,
                wxT(&quot;&amp;3x&quot;),
                wxT(&quot;Zoom 3 times&quot;));
  item1-&gt;Append(ID_4X,
                wxT(&quot;&amp;4x&quot;),
                wxT(&quot;Zoom 4 times&quot;));
  item1-&gt;Append(ID_5X,
                wxT(&quot;&amp;5x&quot;),
                wxT(&quot;Zoom 5 times&quot;));

  item0-&gt;Append(item1,
                wxT(&quot;&quot;));
  return item0;
}
</pre>
<p>By stripping off the menubar class and implementing this
directly in your code you get:</p>
<pre class="programlisting">
void MyCanvas::ShowDContextMenu(
                        const wxPoint &amp;pos) {

  wxMenu* item1 = new wxMenu(wxMENU_TEAROFF);

  item1-&gt;Append(wxID_NEW,
                wxT(&quot;&amp;New\tCtrl-N&quot;),
                wxT(&quot;New chart&quot;));
  item1-&gt;Append(ID_GRIB,
                wxT(&quot;&amp;Open\tCtrl-O&quot;),
                wxT(&quot;Open a Grib File&quot;));

  item1-&gt;AppendSeparator();

  item1-&gt;Append(ID_1X,
                wxT(&quot;&amp;1x&quot;),
                wxT(&quot;Zoom 1 times&quot;));
  item1-&gt;Append(ID_2X,
                wxT(&quot;&amp;2x&quot;),
                wxT(&quot;Zoom 2 times&quot;));
  item1-&gt;Append(ID_3X,
                wxT(&quot;&amp;3x&quot;),
                wxT(&quot;Zoom 3 times&quot;));
  item1-&gt;Append(ID_4X,
                wxT(&quot;&amp;4x&quot;),
                wxT(&quot;Zoom 4 times&quot;));
  item1-&gt;Append(ID_5X,
                wxT(&quot;&amp;5x&quot;),
                wxT(&quot;Zoom 5 times&quot;));

  PopupMenu(item1,
            pos.x,
            pos.y);

  // test for destroying items in popup menus
#if 0 // doesn't work in wxGTK!
  menu.Destroy(Menu_Popup_Submenu);
  PopupMenu(&amp;menu,
            event.GetX(),
            event.GetY() );
#endif // 0
}
</pre>
<p>The above function is invoked via the <tt class=
"classname">Canvas</tt> class that handles all mouse events.</p>
<pre class="programlisting">
void MyCanvas::OnMouseEvent(
                       wxMouseEvent&amp; event) {
  wxClientDC dc(this);
  PrepareDC(dc);
  wxPoint pt=event.GetLogicalPosition(dc);

  // Popup support
  if(event.RightUp()) 
    ShowDContextMenu(pt);

  // Standard mouse events
  if(event.LeftDClick())
    view-&gt;OnLButtonDblClk(0, pt);
  if(event.Moving())
    view-&gt;OnMouseMove(0, pt);

  if(!view)
    return;
}
</pre>
<p>Now we have a path where the UI can be altered on the fly and we
just recompile. About as simple as using native MFC and Visual C++.
Only difference is that you have a lot more control over what is
going on.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e558" id="d0e558"></a>Finer
Points</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e561" id="d0e561"></a>Status Bar Under
Sub-Window</h3>
</div>
<p>Easy enough to do: in the Frame all you need to add is:</p>
<pre class="programlisting">
CreateStatusBar(4);
</pre>
<p>to create four equally sized panes, and then in your body code
you set the text:</p>
<pre class="programlisting">
SetStatusText(_(&quot;Ready&quot;),1);
</pre>
<p>to put the word Ready in the first pane.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e574" id="d0e574"></a>Persistence and
the Registry</h3>
</div>
<p>The function <tt class="function">GetApp()</tt> that returns
addressability is accessed by simply putting <tt class=
"filename">MyApp.h</tt> in the view path of the class you want to
allow access to the <tt class="classname">App</tt>. In the case of
<tt class="classname">MyDoc</tt> putting <tt class=
"filename">MyApp.h</tt> in the front of the file and calling
<tt class="methodname">GetApp()</tt> you can access variables. This
is very important when we use profile variables.</p>
<p>Those from the golden days of windows programming will remember
the ini file and <tt class="methodname">GetPrivateProfile</tt>
string and <tt class=
"methodname">WritePrivateProfileString</tt>.</p>
<p>Persistence in wxWidgets is similar in concept except the
concept is portable. For Win32 we will use the windows registry and
<tt class="classname">wxRegConfig</tt>. For Unix &amp; Linux we
will need to use the <tt class="classname">fileConfig</tt>. The
underlying philosophy is the same so the definitions will change
but the use of the config base will not. The wxWidgets documention
explains the concept very well.</p>
<p>In <tt class="filename">MyApp.h</tt> define the config base
variable config.</p>
<p>This will be our point of contact for all our persistent
variables.</p>
<pre class="programlisting">
wxRegConfig *config;
config = new wxRegConfig(&quot;MYKEY&quot;);
</pre>
<p>Now in the application code we can do something like this:</p>
<pre class="programlisting">
wxGetApp().config-&gt;Read(&quot;LAT&quot;,
                        &amp;LAT,
                        (double)0);

wxGetApp().config-&gt;Write(&quot;LAT&quot;,
                         worklat)
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e626" id="d0e626"></a>Posting
Messages</h3>
</div>
<p>You can issue messages within the code very much like making a
mouse click. Very useful for invoking functions or perhaps a
timer:</p>
<pre class="programlisting">
wxUpdateUIEvent ev(ID_TIMER);
frame-&gt;GetEventHandler()-&gt;ProcessEvent(ev);
</pre></div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e633" id="d0e633"></a>Next
time...</h2>
</div>
<p>Next time, we'll talk about connecting to the user
interface.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e638" id=
"d0e638"></a>Resources</h2>
</div>
<p>wxWidgets: <a href="http://www.wxwidgets.org" target=
"_top">http://www.wxwidgets.org</a></p>
<p>wxDesigner: <a href="http://www.roebling.de/" target=
"_top">http://www.roebling.de/</a></p>
<p>Another introduction to wxWidgets: <a href=
"http://www.all-the-johnsons.co.uk/accu/%20index.html" target=
"_top">http://www.all-the-johnsons.co.uk/accu/ index.html</a></p>
<p>Porting MFC to wxWidgets: <a href=
"http://www-106.ibm.com/developerworks/linux/library/l-mfc/"
target="_top">http://www-106.ibm.com/developerworks/linux/library/l-mfc/</a></p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
