    <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  :: Understanding Windows (9)</title>
        <link>http://accu.org/index.php/journals/731</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 8, #2 - Apr 1996 + Programming Topics</span></div>

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

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

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

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

                     &gt;                         <a href="http://accu.org/index.php/journals/c136/">082</a>
                    (9)
<br />

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

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

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

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

                    -                        <a href="http://accu.org/index.php/journals/c136+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;Understanding Windows (9)</h1>
<p><strong>Author:</strong>&nbsp;Administrator</p>
<p>
<strong>Date:</strong> 03 April 1996 13:15:27 +01:00 or Wed, 03 April 1996 13:15:27 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e16" id="d0e16"></a></h2>
</div>
<p>Imagine that you want to write a simple text editor. This
happens to be extremely simple to achieve by creating an 'SDI'
(Single Document Interface) application, i.e. a frame window with
menu bar. You then place an edit control on the client area of that
window. In this case the edit control with appropriate style
settings will do nearly all of the work for you. In order to
complete a minimal program you simply need to handle the file
loading and saving. Communicating with the edit field is done
largely through SendMessage(). In order to edit multiple documents
the user need only start multiple instances of the application.
Obviously I have just described the bones of Microsoft Notepad
(which doesn't add much flesh to the above).</p>
<div class="sidebar">
<p>Interestingly this is an example of an application pulling
together a number of external components and using the minimum of
'glue' to hold them together. Most of the real functionality is
provided by the system. Components you could be using include the
window management (including menu) system, the edit control, common
dialogs (file and font) and the clipboard. In each case the total
amount of code that you need to write is very limited.</p>
</div>
<p>The most obvious problem with this scheme is that with each
instance of your editor leading an independent life, working on a
number of files at a time is too cumbersome for most purposes. The
approved solution is the 'MDI'(Multiple Document Interface) which
is directly supported by the API.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e25" id="d0e25"></a>MDI
Applications</h2>
</div>
<p>Windows provides a system global window class &quot;MDICLIENT&quot;. A
window of this class is placed on an application defined 'frame'
window. The MDI client window manages an indefinite number of
application defined 'MDI Child windows' within its borders. The
child window instances may be of any application registered class
but need to be created by the MDI client window.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e30" id="d0e30"></a>The Frame
Window</h3>
</div>
<p>This will be very like an SDI frame window with any combination
of menu, toolbar, status bar and any other user interface
components. It needs to create and determine the size and position
of just one MDI client window. Default message handling is handled
by the API function <tt class="literal">DefFrameProc()</tt> instead
of <tt class="literal">DefWindowProc()</tt>.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e41" id="d0e41"></a>The MDI Client
Window</h3>
</div>
<p>Being a child of the frame window and parent to the MDI child
windows, this window is in an excellent position to manage aspects
of both. The Frame's menu should include a 'Window' popup that the
client looks after. It appends child window titles to this popup
menu counting from '1' to '9' and then &quot;More windows...&quot;.</p>
<p>Creation of child windows is performed in response to <tt class=
"literal">WM_MDICREATE</tt> messages. Other <tt class=
"literal">WM_MDI*</tt> messages control the child windows and
return information.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e54" id="d0e54"></a>The MDI
Children</h3>
</div>
<p>If you are writing a multiple file editor then you may only need
one class of child window, if you are writing an I.D.E. then you
will probably want several classes.</p>
<p>These are child windows and don't have menus of their own.
Because the menu and any other source of commands is on the frame
window, the task of handling the commands and updating menu and
toolbar states has to be shared between the frame and the currently
active child window. Default message processing is handled by the
API function <tt class="literal">DefMdiChildProc()</tt>.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e64" id="d0e64"></a>Writing your
own</h3>
</div>
<p>Sadly there is just too much code needed to actually cover the
whole process here but there are plenty of examples to be found
within the SDK (specifically 'multipad' a multiple file version of
notepad) and in several books including Petzold's.</p>
<p>Assuming that we can assemble the source code to implement an
MDI application, there remains one problem that I haven't so far
touched upon...</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e71" id="d0e71"></a>Associating
with window instances</h2>
</div>
<p>The window procedure associated with each MDI child window is
also associated with any other window instance of the same class.
Remember, the window procedure is set for a registered window
class, that is one of these:</p>
<pre class="programlisting">
LRESULT __export CALLBACK OurWndProc(HWND hWnd, UINT Msg,
    WPARAM, LPARAM );
</pre>
<p>The only thing that gives us a clue as to which instance of the
window class this call arrived for is the hWnd (handle to window)
parameter. Clearly this handle will be associated with some data
object - such as a text file name in the case of an editor. A
little thought leads to the conclusion that the most generally
useful association will be with a pointer to a data structure
within our application.</p>
<p>There are in fact three possible ways of making this
association.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e82" id="d0e82"></a>Dictionary based
association</h3>
</div>
<p>When we created the window originally, we could have saved the
window handle and our data pointer in a dictionary of some sort.
Subsequently in our window procedure we can look up the hWnd value
in the dictionary and retrieve the associated pointer for use
within the procedure. This is essentially what is done by MFC and
other large Windows class libraries.</p>
<p>Another approach is to make the association within the
system.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e89" id="d0e89"></a>Window
properties</h3>
</div>
<p>Windows has an internal mechanism to associate data identified
by string field identifiers with window handles. The <tt class=
"literal">SetProp()</tt>, <tt class="literal">GetProp()</tt> and
<tt class="literal">RemoveProp()</tt> API functions are available
(see SDK documentation). These are relatively inefficient and
should not be used for this purpose as they have no obvious
advantages over the application dictionary approach except as a
quick and dirty solution.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e103" id="d0e103"></a>Padding the
window instance</h3>
</div>
<p>The alternative is to use extra bytes in the window instance
itself. When registering a window class, one member of the
<tt class="literal">WNDCLASS</tt> structure is '<tt class=
"literal">cbWndExtra</tt>' (count of bytes window extra). If this
is set to the size of a pointer to your data structure, then each
window instance of this class that is created will have space for
an extra pointer tacked on the end. Although the window handle is
an offset in a segment owned by the system and therefore not
directly accessible by the application, it can be accessed by a set
of API functions. These functions are <tt class=
"literal">SetWindowWord()</tt>, <tt class=
"literal">SetWindowLong()</tt>, <tt class=
"literal">GetWindowWord()</tt> and <tt class=
"literal">GetWindowLong()</tt>.</p>
<p>All of these functions take a window handle and an offset. The
offset is from the end of the base window structure. There are a
number of constant negative offsets that you can use to obtain
documented members of the window instance. An offset of zero will
give access to the start of the extra bytes, in this case our
pointer. It is a matter of choice whether to optimise the number of
the extra bytes and select the correct pair of access functions or
just use four bytes and use the long version. Obviously the less
bulky you make each window instance, the less strain on USER
resources they will cause.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e128" id="d0e128"></a>The C++
approach</h2>
</div>
<p>Anyone who knows me will have realised by now that this has been
leading up to a C++ approach. What we want to do is to derive our
classes from base classes provided by the Windows system,
specialising them for our own purposes. Of course if the Windows
API was C++ then this would be easy. It's easy to envisage having a
base window class from which we can derive all our specialised
ones. Sadly it won't turn out to be that easy!</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e133" id="d0e133"></a>Going at least
part of the hog</h3>
</div>
<p>If we can rely on every window having a pointer at an offset of
zero as accessed by the <tt class="literal">Get</tt>/<tt class=
"literal">SetWindowWord</tt>/ <tt class="literal">Long()</tt>
functions then it is easy to see that we could have just one window
procedure for all our windows. Suppose that we have a base class
like this:</p>
<pre class="programlisting">
class WinBase { HWND hWnd;
    static LRESULT __export CALLBACK AllWndProc( HWND, UINT, WPARAM, LPARAM );
    virtual LRESULT WndProc( UINT, WPARAM, LPARAM ); public: WinBase(); BOOL
    Create( /* params for window */ ); }; LRESULT __export CALLBACK
    WinBase::AllWndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM
    lParam ){ WinBase *pWB = GetWindowWord( hWnd, 0 ); return pWB-&gt;WndProc(
    uMessage, wParam, lParam ); } BOOL WinBase::Create( /* params for window
    */ ){ /* register the class with extra window bytes if not yet registered
    and set the callback to AllWndProc, Create the window, put the 'this'
    pointer into the window instance using SetWindowWord(hWnd, 0, this);
    assign hWnd */ }
</pre>
<p>This would nearly work! Unfortunately there are a number of
messages sent directly to the window procedure before <tt class=
"literal">CreateWindow()</tt> returns, so we need to set the
'<tt class="literal">this</tt>' pointer earlier.</p>
<p>This can be achieved by adding a <tt class="literal">static
WinBase</tt> pointer and picking this up in <tt class=
"literal">AllWndProc()</tt> on receipt of the first message and
setting the window instance pointer at that time. This can be made
to work but it needs the window procedure to check the return value
each time it retrieves it or to check another static flag set just
before the <tt class="literal">CreateWindow()</tt> call. Neither
option is totally satisfactory so here is an alternative.</p>
<p>Keep the <tt class="literal">static WinBase</tt> pointer:</p>
<pre class="programlisting">
static
    WinBase *pWBCreating;
</pre>
<p>In the <tt class="literal">WinBase::Create()</tt> function,
prior to calling <tt class="literal">CreateWindow()</tt> add:</p>
<pre class="programlisting">
pWBCreating
    = this;
</pre>
<p>Also instead of supplying <tt class="literal">AllWndProc</tt> as
the window class procedure, set it to <tt class=
"literal">FirstWndProc</tt>.</p>
<p>Define <tt class="literal">FirstWndProc</tt> thus:</p>
<pre class="programlisting">
LRESULT
    __export CALLBACK WinBase::FirstWndProc( HWND hWnd, UINT uMessage, WPARAM
    wParam, LPARAM lParam ){ SetWindowWord( hWnd, 0, pWBCreating );
    SetWindowLong( hWnd, GWL_WNDPROC, (LONG)WinBase::AllWndProc );
    pWBCreating-&gt;hWnd = hWnd; return pWBCreating-&gt;WndProc( uMessage,
    wParam, lParam ); }
</pre>
<p>This results in the first message to each window instance being
handled by <tt class="literal">WinBase::FirstWndProc()</tt> which
sets our pointer and sets the instance's copy of the window handle.
The window then has its window procedure changed to <tt class=
"literal">AllWndProc</tt> for all future messages. Finally the
virtual <tt class="literal">WndProc()</tt> function is called for
the class instance.</p>
<p>The <tt class="literal">WinBase::WndProc()</tt> function could
call <tt class="literal">DefWindowProc()</tt>, thus making it
equivalent to the base window class as provided by the system.</p>
<div class="sidebar">
<p>This scheme suffers from the drawback that not all windows are
of application declared classes, particularly dialogs and controls
that use window extra bytes already. In the case of Dialogs there
is a special offset - DWL_USER - that can be used to store our
pointer.</p>
<p>On the other hand, controls don't have any such space to use, so
we need to tackle them differently. A complicated but efficient
solution is to use the 'super-classing' technique where a new class
is created based on an existing one. Alternatively the dictionary
approach discussed above will handle these windows just like any
other.</p>
</div>
<p>This scheme achieves the association of window messages with our
own data objects but still leaves the derived <tt class=
"literal">WndProc()</tt> implementation to crack the messages with
a large <tt class="literal">switch - case</tt>. As this is one of
the most criticised aspects of conventional Windows programming it
would be nice to do this in some cleaner way.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e232" id="d0e232"></a>Message cracking
one way</h3>
</div>
<p>In practice, messages can be divided into two categories -
commands and everything else. So we could hive off commands and
have a separate virtual function for them:</p>
<pre class="programlisting">
virtual void DoCommand( WPARAM idItem, HWND
    hWndCtrl, WORD wNotify );
</pre>
<p>This discards the <tt class="literal">WM_COMMAND</tt> part of
the message as it is implicit and splits the lParam into its
components for a command.</p>
<p>Other messages can be treated in a similar way. Some are so
important that they necessarily deserve functions of their own.
Particular examples are <tt class="literal">WM_CREATE</tt> and
<tt class="literal">WM_PAINT</tt>, prototypes could be:</p>
<pre class="programlisting">
virtual LRESULT DoCreate(); virtual
    LRESULT DoPaint( PAINTSTRUCT&amp; ps );
</pre>
<p>Although the <tt class="literal">WM_CREATE</tt> message has a
pointer to <tt class="literal">CREATESTRUCT</tt> in the lParam,
this isn't likely to be needed in this circumstance, after all it's
our <tt class="literal">CREATESTRUCT</tt>! For the <tt class=
"literal">WM_PAINT</tt> message, <tt class=
"literal">AllWndProc()</tt> can call <tt class=
"literal">BeginPaint()</tt> - <tt class="literal">EndPaint()</tt>
around the virtual function call.</p>
<p>Other messages such as client and non client mouse messages come
in convenient groups and these could also have functions of their
own:</p>
<pre class="programlisting">
virtual LRESULT DoMouse(
    UINT iMessage, WPARAM wKeyFlags, int x, int y ); virtual LRESULT
    DoNcMouse( UINT iMessage, WPARAM wKeyFlags, int x, int y
    );
</pre>
<p>Obviously you will need one general purpose message handler for
all those messages not covered already.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e283" id="d0e283"></a>Message cracking
another way</h3>
</div>
<p>The current consensus (partly led by MFC and OWL) is that each
message should be mapped to handler functions one to one. This also
applies to commands.</p>
<p>One way that this could be done is to declare one virtual
function for each message, the problem with this is that each
derived class would need a huge virtual method table (compared to
most VMTs that is). The job of deciding which function to call
remains difficult for the static window procedure (it could be a
very long switch - case). A natural solution would be to design a
cunning hashed dictionary (as above when mapping window handles to
class pointers).</p>
<p>In practice the hashed map is used but without the virtual
functions, after all if you're going to the trouble of writing the
hashed map then you can just call the functions directly!</p>
<p>I have to admit that although this mechanism is quite efficient
I find it less elegant than the partial cracking described above.
However I'm probably in a minority of one on this issue.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e294" id="d0e294"></a>If it was that
easy...</h3>
</div>
<p>Sadly, the above remains an over simplification of the issues
but I don't think I could get away with another ten thousand words.
The discussion so far raises more questions than it answers but
that's programming for you.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e299" id="d0e299"></a>Free
Software</h3>
</div>
<p>With the kind permission of Pat Fuller, I'm making available a
small class library that we wrote some time ago that can be used to
build simple SDI and MDI applications. I think that it may be of
use to help in understanding some of the concepts that I've been
covering. Some aspects of it may form the basis of a future
article.</p>
<p>It isn't in competition with MFC which seems to have become the
dominant Windows specific class library. We wrote it with the idea
of making it as simple and efficient as possible. I have only used
it for a couple of serious jobs since but I was thinking of
resurrecting it and extending it in various ways. If anyone else is
interested then please contact me.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
