    <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 - Part 3</title>
        <link>https://members.accu.org/index.php/articles/791</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>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 17, #1 - Feb 2005</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/articles/">All</a>

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

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

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

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

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

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c98/">171</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-98/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+98/">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 - Part 3</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 February 2005 13:16:10 +00:00 or Thu, 03 February 2005 13:16:10 +00:00</p>
<p><strong>Summary:</strong>&nbsp;<p>In this, the final part of the series, Jon rounds off the port of an application from MFC to wxWidgets.</p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p><span class="emphasis"><em>In this, the final part of the
series, Jon rounds off the port of an application from MFC to
wxWidgets.</em></span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e25" id="d0e25"></a>Internet
Access</h2>
</div>
<p>The <tt class="classname">wxSocket</tt> class provides a very
simple interface over the Internet. You will need to have a phone
connection or DSL/ISDN network connection established.</p>
<p>To get a web page is simplicity in itself.</p>
<p>The following is from the samples - Sockets - Client.</p>
<pre class="programlisting">
// define the URL
wxString urlname = &quot;your.url.com&quot;
wxURL url(urlname);
// Check to see url is valid
if(url.GetError() != wxURL_NOERR) {
  m_text-&gt;AppendText((&quot;Error: couldn't parse URL\n&quot;));
  m_text-&gt;AppendText((&quot;=== URL test ends ===\n&quot;));
  return;
}
// Get the data
wxInputStream *data = url.GetInputStream();
</pre>
<p>Read up in <tt class="classname">wxStringBase</tt> and
<tt class="classname">wxStringBuffer</tt> for data
manipulation.</p>
<p>This would take about a page in MFC.</p>
<p>For more sophisticated operations like perhaps talking to a mail
server on port 25 you have to establish a socket connection
directly using <tt class="classname">wxSocketClient</tt>. This is
derived from <tt class="classname">wxSocketBase</tt> which handles
both Server and Client connections.</p>
<p>Use <tt class="classname">wxIPV4address</tt> to store the
address.</p>
<pre class="programlisting">
wxIPV4address sockAddr;
sockAddr.Hostname(pszHostAddress);
sockAddr.Service(nPort);
</pre>
<p>The host address can be a server name or a resolved IP
Address.</p>
<p>Now we connect:</p>
<pre class="programlisting">
m_hSocket.Connect(lpSockAddr, TRUE);
</pre>
<p>Check we are OK</p>
<pre class="programlisting">
wxASSERT(m_hSocket.Error());
</pre>
<p><tt class="literal">TRUE</tt> has the instruction wait for the
connection to complete. The command returns true if a connection
was made.</p>
<p>To avoid long timeouts you may want to set this flag to
<tt class="literal">FALSE</tt> and use <tt class=
"classname">WaitForConnect</tt> after the connect. This will allow
you to specify your own timeout. Input and output is handled by
<tt class="classname">wxSocketBase</tt>.</p>
<pre class="programlisting">
To read use the following
if(m_hSocket.WaitForRead(-1))
  m_hSocket.Read(pszRecvBuffer,256)
To write
wxString Buffer = &quot;DATA&quot;;
  m_hSocket.Write(Buffer, Buffer.Length());
To close the connection:
if(!m_hSocket.Error()) {
  m_hSocket.Close();
</pre>
<p>For more advanced use of both client and server tools please
take a look at the Sockets sample in the wxWidgets samples. The
comments are very helpful.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e93" id="d0e93"></a>Context
Sensitive Help</h2>
</div>
<p>wxWidgets supports winHelp, Microsoft HTMLHelp and wxHTMLHelp.
The latter being a subset and useful for cross platform operation.
There are also a lot of internal hooks to put in fast context help
for dialogs.</p>
<p>Every wxWindow object can have some text associated with it. In
practice this type of help seems to have been the most popular.
Most users want a quick hint to get them on their way rather than a
huge tome presented when they press the F1 button. The old
Microsoft way was to pop up a document with the relevant passage.
With a quick hint this would consume a huge amount of real estate
on the screen and the many keystrokes required to get out of it
detracted from the experience and generally soured the user on the
F1 button.</p>
<p>So in this section we will design a simple window based help
structure where every item has help of some kind and the F1 key can
be used on the fly. Lastly we will create a hot link to the
documentation file via Shift F1 or a menu item that will allow us
to display the help.</p>
<p>If we have been using wxDesigner to its full extent the object
functionality of the tool bar and menu bars will be already in
place. You should see context sensitive help on the status bar as
you pass the cursor over the object and on the toolbar, a tool tip
should pop up. If this is not enough for our poor user, then they
will have to start reading the documentation.</p>
<p>To provide a clearing house for a single point in the
application to handle all help oriented commands (F1, context
help), we use in our mainframe an implementation of <tt class=
"classname">wxHelpProvider</tt> that allows a great deal of
flexibility here:</p>
<p>In the <tt class="classname">App Class</tt> header create:</p>
<pre class="programlisting">
wxHelpControllerHelpProvider* provider; 
</pre>
<p>In the mainframe class create as private:</p>
<pre class="programlisting">
private:
  wxHelpController m_help;
</pre>
<p>and then create an inline function to return the controller</p>
<pre class="programlisting">
wxHelpController&amp; GetHelpController() {return m_help;}
</pre>
<p>Now in the <tt class="classname">App</tt> inititialization
before and after the <tt class="classname">Mainframe</tt> creation
insert the help implementation:</p>
<pre class="programlisting">
&gt;&gt; provider = new wxHelpControllerHelpProvider;
&gt;&gt; wxHelpProvider::Set(provider);
</pre>
<p>Here we substantiate and set the controller class.</p>
<pre class="programlisting">
// create the main application window
m_mainFrame = new WXWindPlotFrame(m_docManager,
                    (wxFrame*) NULL, &quot;WindPlot &quot;+rs,
                    wxPoint(0, 0), wxSize(640, 480),
                    wxDEFAULT_FRAME_STYLE);
&gt;&gt; provider-&gt;SetHelpController(
                &amp; m_mainFrame-&gt;GetHelpController());
</pre>
<p>Here we link the controller with the main frame. We can now use
the <tt class="function">SetHelpText</tt> function of the
<tt class="classname">wxWindow</tt> class for any object derived
from <tt class="classname">wxWindow</tt> - views, dialogs etc. Just
add the following text to the constructor for example</p>
<pre class="programlisting">
WXWindPlotFrame::WXWindPlotFrame(
          wxDocManager *manager, wxFrame *frame,
          const wxString&amp; title, const wxPoint&amp; pos,
          const wxSize&amp; size, long type)
      : wxDocMDIParentFrame(manager, frame, -1,
               title, pos, size, type, &quot;myFrame&quot;) {
  SetHelpText((&quot;To review toolbar functions, rest
         mouse over the toolbar button and read the
         description on the bottom Status
         bar.\nSelect help menu Contents for
         detailed help&quot;));
</pre>
<p>When you are in a window that has control and you press F1 you
will see this text pop up in a neat compact frame window. It will
disappear on a single mouse click.</p>
<p>To use the traditional Context Help cursor (the ? And pointer)
we need to issue a context help command.</p>
<p>This is accomplished by associating a menu entry or toolbar
button with <tt class="literal">wxID_HELP_CONTEXT</tt>.</p>
<p>When the context message is received do the following:</p>
<pre class="programlisting">
BEGIN_EVENT_TABLE(WXWindPlotFrame,
                  wxDocMDIParentFrame)
  EVT_MENU(wxID_HELP_CONTEXT,
           WXWindPlotFrame::OnCHelp)
END_EVENT_TABLE()

void WXWindPlotFrame::OnCHelp() {
  wxContextHelp chp(this, TRUE);
}
</pre>
<p>The help controller will handle the rest for you. The Cursor
will change and you can take it where you will. Left Click to see
the help text</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e166" id="d0e166"></a>The First
Linux Compile</h2>
</div>
<p>The main weapon of choice here is the preprocessor. While we are
trying to make our code as portable as we can, some things will
have to be done a little differently.</p>
<p>Using the preprocessor command we can eliminate Unix code from
Windows compiles:</p>
<pre class="programlisting">
#ifndef WXMS_
-- Unix specific commands
#endif
</pre>
<p>Now comes the moment of truth. Prepare to be humbled and pay for
all those sloppy little habits you picked up when using MSVC++.</p>
<p>We are moving over to Linux which though not entirely unfriendly
is less forgiving in many respects. Firstly wxWidgets needs to be
installed.</p>
<p>On RedHat 9 this went without a problem - I downloaded the GTK+
tarball and unzipped it into a working directory.</p>
<p>Following the instructions: <span><b class=
"command">./config</b></span>, make and then a <span><b class=
"command">make install</b></span> (the last one as root), we were
up and running</p>
<p>wxWidgets sets up library and include paths. The command
<span><b class="command">ldconfig -v</b></span> sets up the linker
paths and you should see <tt class="filename">libwx_gtk</tt>
somewhere in there.</p>
<p>We need to be sensitive to shared libraries. I first tried to
compile and link everything statically. With GTK this is not
possible. Most of the high level widgets need to be loaded
dynamically at run time. We can link in all the wx libraries though
so when you configure use the command:</p>
<p><span><b class="command">./configure -with-gtk
-disable-shared</b></span></p>
<p>Now we need to get familiar with the development environment. I
use kdevelop as this has a lot of similar functionality to MSVC. I
am a GUI junkie and am more productive when I have a tool to relate
messages to code.</p>
<p>A good move now is to try to run up one of the samples.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e206" id="d0e206"></a>Follow These
Steps</h3>
</div>
<p>Navigate to the samples directory of the wx distribution and
look for a project. DocViewMDI is a good one. Rename the file
<tt class="filename">makefile.unx</tt> to <tt class=
"filename">Makefile</tt> and we have a make environment ready to
go.</p>
<p>Now run up kdevelop and from the project menu generate a project
file in same directory. You should now be able to press the
cogwheel toolbar button to compile and run the program and verify
that your wx build environment is ready to go.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e219" id="d0e219"></a>Now on to the
Port</h3>
</div>
<p>MSVC is a lot better when it comes to managing projects and
files and as a result my project was spread over several folders. I
was re-using source code in several projects and had a common
source folder. This is OK if you are on your own but in a
commercial environment with multiple programmers it is intolerably
sloppy. Common modules should be statically linked into a library
and then included on the link path. Include files should be in a
common include directory. Then all you need to do is put all your
C++ code in a working directory and all the wdr generated includes
in the .wdr/ folder.</p>
<p>The construct of the makefile becomes very simple in this case
and here it is:</p>
<pre class="programlisting">
# File: Generic Makefile for wxWidgets under GTK
CXX = $(shell wx-config -cxx)
PROGRAM = WxWindplot
#OBJECTS =  WXWindPlotApp.o *.o
OBJECTS =  $(patsubst %.cpp, %.o, $(SOURCES))
SOURCES = $(wildcard *.cpp)
# implementation
.SUFFIXES:      .o .cpp
.cpp.o :
  $(CXX) -c 'wx-config -cxxflags' -o $@ $&lt;
### Uncomment next line if you need debugging
### information
###     $(CXX) -c 'wx-config -cxxflags' -g -o $@ $&lt;
all:    $(PROGRAM)
$(PROGRAM):     $(OBJECTS)
  $(CXX) -o $(PROGRAM) $(OBJECTS) 'wx-config -libs
                                           --static'
clean: 
  rm -f *.o $(PROGRAM)
</pre>
<p>This makefile compiles all <tt class="filename">.cpp</tt>
programs in the same directory and links them. If you uncomment the
debugging line and comment out the line above you will get
debugging information.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e233" id="d0e233"></a>So Off We
Go</h3>
</div>
<p>Most of the errors you get will be due to include files not
properly resolved. There will also be a few MS specific library
calls and you will need to find ANSI equivalents or look in the
wxWidgets documentation. Specific examples will be platform issues
life file name resolution, variable persistence etc.</p>
<p>Remember Unix/Linux file names are case sensitive. Very soon all
your source files will be lower case. Microsoft does not care and
allows mixing of cases.</p>
<p>One thing to be aware of on the port. I have been quite sloppy
about defining variables on the fly. MSVC has a slightly different
visibility rule on dynamic variables. It is good practice to follow
the old C rule of declaring local variables at the beginning of the
subroutine to avoid porting problems. If you declare variable i
within a for loop</p>
<pre class="programlisting">
for(int i=0 ; i&lt;20 ; i++)
</pre>
<p>and you reference <tt class="varname">i</tt> again you will get
an error.</p>
<pre class="programlisting">
int i;
for(i=0;i&lt;20;i++)
</pre>
<p>The above is a better way of doing things.</p>
<p>Referencing the contents of <tt class="classname">wxString</tt>
- always use <tt class="methodname">wxString::GetData()</tt> and
<tt class="methodname">wxString::GetChar(i)</tt> as opposed to
referencing the data directly.</p>
<p>Put on your flying goggles and go to work. For my 5,000 line
windplot project over 10 cpp files we had clean compile in 4 hours.
It would have been faster had I done this before. Running the
program - Wow it ran first time. Not perfect but we were cooking.
More important I was able to single step with kdevelop and get an
idea where the problems lay.</p>
<p>Where classes have integral data types - <tt class=
"classname">wxString</tt> <tt class="classname">wxLonLong</tt> -
you need to use the access functions rather than the classes
themselves <tt class="classname">wxLongLong</tt> you need to pull
the long value via <tt class="methodname">wxLongLong::ToLong</tt>.
Very important if you are using time variables where everything is
<tt class="type">LongLong</tt> (takes us over the next rollover
event in 2034).</p>
<p>Regrettably a lot of the sexier features of MS Windows are not
all implemented on GTK and especially in things like MDI windows
there are some things lacking. The next step will be to look at
these deficiencies and see how we can address them.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e285" id="d0e285"></a>The Tuneup:
Basic Debugging</h2>
</div>
<p>When you get to work with Linux you experience a true multi
threaded multitasking environment. Compared to Windows where your
primary thread will hang on a dialog until you respond. Be prepared
for some very fast lock ups if you put a modal dialog in a the
OnDraw loop for instance.</p>
<p>I was having a dreadful time trying to sort out Windows Sockets
and and my breakpoints seemed to be activated at random until I got
the hang of what was going on. From then on it was plain sailing
and kdevelop was a big help. Looking inside classes was not
possible with the way I was using kdevelop and so I have to put in
debugging statements to pull values out of wxStrings to see them.
For those who are used to an IDE, kdevelop worked very well. Above
all the price is right.</p>
<p>The problems I encountered on my first run:</p>
<div class="variablelist">
<dl>
<dt><span class="term">File visibility:</span></dt>
<dd>
<p>This is very important and you need to agree on where your
working files will be based.</p>
</dd>
<dt><span class="term">Month 0 based:</span></dt>
<dd>
<p>July was August until I put in a conditional compile statement
to decrement the month.</p>
</dd>
</dl>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e307" id="d0e307"></a>Internet
Hang-up: Serial Port Access</h2>
</div>
<p>Could not open a COM port (<tt class="filename">/dev/cua0</tt>).
Using <span><b class="command">setserial -G /dev/cua0</b></span> I
verified the port was valid and then logged on as root and gave
read/write access to all. After that everything worked.
[<i><span class="remark">The name of the ports will vary - the
serial ports on my linux box are all ttySx - Ed</span></i>]</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e321" id="d0e321"></a>Back to
MSVC</h2>
</div>
<p>The last job was to do a release build and put the windows
version on the web. A nasty shock, every function crashed horribly.
In debug it was perfect. What to do ?</p>
<p>Finally after looking through the support base, I recompiled
wxWidgets specifically disabling optimizations and after the
libraries were re-built the code worked perfectly. All that is
needed is to go into the Project menu and in the settings go to the
C++ tab and set optimizations to Disable (Debug). I had visions of
a huge rewrite but fortunately a simple fix was all that was
required.</p>
<p>The most important thing I found in all this was that the
underlying thought process was similar so re-training in wxWidgets
from MFC is a very easy and refreshing process. The Class Wizard
and App Wizard that MFC prides itself on is in fact a great snare
and a delusion. The work it saves you is quite trivial. I am
convinced that this toolkit will be with us for a long time. As
open source, its future is assured. The modified GPL license it is
released under means that it will be attractive to commercial
operations and it could be one of the levers that finally puts
Linux in the forefront where it belongs.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e330" id=
"d0e330"></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/index.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>
