]> git.saurik.com Git - wxWidgets.git/commitdiff
1. wxMSW seems to work (please test and send your bug reports!)
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 19 May 1999 00:53:27 +0000 (00:53 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 19 May 1999 00:53:27 +0000 (00:53 +0000)
2. accelerators in the menus a la GTK (actually slightly better) implemented
3. wxSplitter now uses events (and so the code which was broken by recent changes
   works again)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2504 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

62 files changed:
docs/latex/wx/splitevt.tex [new file with mode: 0644]
docs/latex/wx/splitter.tex
include/wx/dc.h
include/wx/defs.h
include/wx/event.h
include/wx/generic/splitter.h
include/wx/log.h
include/wx/msw/app.h
include/wx/msw/control.h
include/wx/msw/dc.h
include/wx/msw/dialog.h
include/wx/msw/frame.h
include/wx/msw/listctrl.h
include/wx/msw/mdi.h
include/wx/msw/menu.h
include/wx/msw/notebook.h
include/wx/msw/private.h
include/wx/msw/spinbutt.h
include/wx/msw/statbmp.h
include/wx/msw/statbox.h
include/wx/msw/stattext.h
include/wx/msw/tabctrl.h
include/wx/msw/tbar95.h
include/wx/msw/textctrl.h
include/wx/msw/treectrl.h
include/wx/msw/window.h
include/wx/msw/wx.rc
include/wx/window.h
src/common/event.cpp
src/common/wincmn.cpp
src/generic/splitter.cpp
src/msw/accel.cpp
src/msw/app.cpp
src/msw/bmpbuttn.cpp
src/msw/button.cpp
src/msw/choice.cpp
src/msw/control.cpp
src/msw/data.cpp
src/msw/dc.cpp
src/msw/dcprint.cpp
src/msw/dialog.cpp
src/msw/frame.cpp
src/msw/listbox.cpp
src/msw/mdi.cpp
src/msw/menu.cpp
src/msw/menuitem.cpp
src/msw/metafile.cpp
src/msw/notebook.cpp
src/msw/ole/automtn.cpp
src/msw/ownerdrw.cpp
src/msw/printdlg.cpp
src/msw/printwin.cpp
src/msw/radiobox.cpp
src/msw/statbox.cpp
src/msw/statbr95.cpp
src/msw/tabctrl.cpp
src/msw/tbar95.cpp
src/msw/textctrl.cpp
src/msw/thread.cpp
src/msw/treectrl.cpp
src/msw/utils.cpp
src/msw/window.cpp

diff --git a/docs/latex/wx/splitevt.tex b/docs/latex/wx/splitevt.tex
new file mode 100644 (file)
index 0000000..c525bca
--- /dev/null
@@ -0,0 +1,49 @@
+\section{\class{wxSplitterEvent}}\label{wxsplitterevent}
+
+This class represents the events generated by a splitter control.
+
+\wxheading{Derived from}
+
+\helpref{wxCommandEvent}{wxcommandevent}\\
+\helpref{wxEvent}{wxevent}\\
+\helpref{wxEvtHandler}{wxevthandler}\\
+\helpref{wxObject}{wxobject}
+
+\wxheading{Include files}
+
+<wx/splitter.h>
+
+\wxheading{Event table macros}
+
+To process a splitter event, use these event handler macros to direct input to member
+functions that take a wxSplitterEvent argument.
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_SPLITTER\_SASH\_POS\_CHANGED(id, func)}
+    {The sash position was changed. May be used to prevent the change from
+     taking place. Processes wxEVT\_COMMAND\_SPLITTER\_SASH\_POS\_CHANGED event.}
+\twocolitem{{\bf EVT\_SPLITTER\_UNSPLIT(id, func)}}
+    {The splitter has been just unsplit. Processes wxEVT\_COMMAND\_SPLITTER\_UNSPLIT
+     event.}
+\twocolitem{{\bf EVT\_SPLITTER\_DOUBLECLICKED(id, func)}}
+    {The sash was double clicked. The default behaviour is to unsplit the
+     window when this happens (unless the minimum pane size has been set to a
+     value greater than zero). Processes wxEVT\_COMMAND\_SPLITTER\_DOUBLECLICKED
+     event}
+\end{twocollist}%
+
+\wxheading{See also}
+
+\helpref{wxSplitterWindow}{wxsplitterwindow}
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxSplitterEvent::wxSplitterEvent}\label{wxsplittereventconstr}
+
+\func{}{wxSplitterEvent}{\param{wxEventType}{ eventType = wxEVT\_NULL},
+                         \param{wxSplitterWindow *}{ splitter = NULL}}
+
+Constructor. Used internally by wxWindows only.
+
+% TODO
index 135fbe299e232b70e9d0f592ba80c146547c87b7..e6b53d0f35ccec7819593cd0e73c494a6005bd3a 100644 (file)
@@ -28,6 +28,31 @@ See also \helpref{window styles overview}{windowstyles}.
 
 <wx/splitter.h>
 
+\wxheading{Event handling}
+
+To process input from a splitter control, use the following event handler
+macros to direct input to member functions that take a 
+\helpref{wxSplitterEvent}{wxsplitterevent} argument.
+
+\twocolwidtha{7cm}
+\begin{twocollist}\itemsep=0pt
+\twocolitem{{\bf EVT\_SPLITTER\_SASH\_POS\_CHANGED(id, func)}
+    {The sash position was changed. May be used to prevent the change from
+     taking place. Processes wxEVT\_COMMAND\_SPLITTER\_SASH\_POS\_CHANGED event.}
+\twocolitem{{\bf EVT\_SPLITTER\_UNSPLIT(id, func)}}
+    {The splitter has been just unsplit. Processes wxEVT\_COMMAND\_SPLITTER\_UNSPLIT
+     event.}
+\twocolitem{{\bf EVT\_SPLITTER\_DOUBLECLICKED(id, func)}}
+    {The sash was double clicked. The default behaviour is to unsplit the
+     window when this happens (unless the minimum pane size has been set to a
+     value greater than zero). Processes wxEVT\_COMMAND\_SPLITTER\_DOUBLECLICKED
+     event}
+\end{twocollist}%
+
+\wxheading{See also}
+
+\helpref{wxSplitterEvent}{wxsplitterevent}
+
 \latexignore{\rtfignore{\wxheading{Members}}}
 
 \membersection{wxSplitterWindow::wxSplitterWindow}\label{wxsplitterwindowconstr}
index 21f4542bd3a32045e4d6556d1e5b3faa29d1456c..4ce01bb4bda7274323574d64e0e91f56a4e2d7c2 100644 (file)
@@ -398,8 +398,6 @@ public:
         if ( x ) *x = m_userScaleX;
         if ( y ) *y = m_userScaleY;
     }
-    void SetSystemScale(double x, double y)
-        { SetUserScale(x, y); }
     virtual void SetUserScale(double x, double y) = 0;
 
     virtual void GetLogicalScale(double *x, double *y)
index eeca285224cfe1ab0a9309e55e86b13ebdd01be0..55deb62757b3e9f2d90fe5100bff67d6fc6d9978 100644 (file)
 
 typedef unsigned char wxByte;
 typedef short int WXTYPE;
+
+// special care should be taken with this type under Windows where the real
+// window id is unsigned, so we must always do the cast before comparing them
+// (or else they would be always different!). Usign wxGetWindowId() which does
+// the cast itself is recommended. Note that this type can't be unsigned
+// because -1 is a valid (and largely used) value for window id.
 typedef int wxWindowID;
 
 // Macro to cut down on compiler warnings.
index 692d9f18d57328ed6ad869fc65f44fa1cd0ba161..fc04af3fbaaac2b212c0c0d0677b00ecdaed4a2f 100644 (file)
@@ -19,8 +19,9 @@
 #include "wx/defs.h"
 #include "wx/object.h"
 #include "wx/gdicmn.h"
+
 #if wxUSE_THREADS
-#include "wx/thread.h"
+    #include "wx/thread.h"
 #endif
 
 /*
@@ -217,6 +218,11 @@ const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED =     wxEVT_FIRST + 802;
 const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING =    wxEVT_FIRST + 803;
 #endif
 
+/* Splitter events */
+const wxEventType wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED = wxEVT_FIRST + 850;
+const wxEventType wxEVT_COMMAND_SPLITTER_DOUBLECLICKED = wxEVT_FIRST + 851;
+const wxEventType wxEVT_COMMAND_SPLITTER_UNSPLIT = wxEVT_FIRST + 852;
+
 const wxEventType wxEVT_USER_FIRST =                        wxEVT_FIRST + 2000;
 
 /* Compatibility */
@@ -307,13 +313,12 @@ public:
     void CopyObject(wxObject& object_dest) const;
 
 public:
-    bool              m_skipped;
     wxObject*         m_eventObject;
-    char*             m_eventHandle;         // Handle of an underlying windowing system event
     wxEventType       m_eventType;
     long              m_timeStamp;
     int               m_id;
     wxObject*         m_callbackUserData;
+    bool              m_skipped;
 
     // optimization: instead of using costly IsKindOf() we keep a flag telling
     // whether we're a command event (by far the most common case)
@@ -1166,7 +1171,7 @@ protected:
  wxEVT_NAVIGATION_KEY
  */
 // must derive from command event to be propagated to the parent
-class WXDLLEXPORT wxNavigationKeyEvent  : public wxCommandEvent
+class WXDLLEXPORT wxNavigationKeyEvent : public wxCommandEvent
 {
     DECLARE_DYNAMIC_CLASS(wxNavigationKeyEvent)
 
@@ -1188,10 +1193,38 @@ public:
     void SetCurrentFocus(wxWindow *win) { m_clientData = (void *)win; }
 };
 
+// Window creation/destruction events: the first is sent as soon as window is
+// created (i.e. the underlying GUI object exists), but when the C++ object is
+// fully initialized (so virtual functions may be called). The second,
+// wxEVT_DESTROY, is sent right before the window is destroyed - again, it's
+// still safe to call virtual functions at this moment
+/*
+ wxEVT_CREATE
+ wxEVT_DESTROY
+ */
+
+class WXDLLEXPORT wxWindowCreateEvent : public wxEvent
+{
+    DECLARE_DYNAMIC_CLASS(wxWindowCreateEvent)
+
+public:
+    wxWindowCreateEvent(wxWindow *win = NULL);
+
+    wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); }
+};
+
+class WXDLLEXPORT wxWindowDestroyEvent : public wxEvent
+{
+    DECLARE_DYNAMIC_CLASS(wxWindowDestroyEvent)
+
+public:
+    wxWindowDestroyEvent(wxWindow *win = NULL);
+
+    wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); }
+};
+
 /* TODO
  wxEVT_POWER,
- wxEVT_CREATE,
- wxEVT_DESTROY,
  wxEVT_MOUSE_CAPTURE_CHANGED,
  wxEVT_SETTING_CHANGED, // WM_WININICHANGE (NT) / WM_SETTINGCHANGE (Win95)
 // wxEVT_FONT_CHANGED,  // WM_FONTCHANGE: roll into wxEVT_SETTING_CHANGED, but remember to propagate
@@ -1242,6 +1275,7 @@ public:
     void SetEvtHandlerEnabled(bool en) { m_enabled = en; }
     bool GetEvtHandlerEnabled() const { return m_enabled; }
 
+#if WXWIN_COMPATIBILITY_2
     virtual void OnCommand(wxWindow& WXUNUSED(win),
                            wxCommandEvent& WXUNUSED(event))
     {
@@ -1252,6 +1286,7 @@ public:
     // Default behaviour
     virtual long Default()
         { return GetNextHandler() ? GetNextHandler()->Default() : 0; };
+#endif // WXWIN_COMPATIBILITY_2
 
 #if WXWIN_COMPATIBILITY
     virtual bool OnClose();
@@ -1295,7 +1330,7 @@ protected:
     wxEvtHandler*       m_previousHandler;
     bool                m_enabled;           // Is event handler enabled?
     wxList*             m_dynamicEvents;
-    wxList*                m_pendingEvents;
+    wxList*             m_pendingEvents;
 #if wxUSE_THREADS
     wxCriticalSection*  m_eventsLocker;
 #endif
@@ -1388,6 +1423,8 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
 #define EVT_NAVIGATION_KEY(func) { wxEVT_NAVIGATION_KEY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNavigationKeyEventFunction) & func, (wxObject *) NULL },
 #define EVT_PALETTE_CHANGED(func) { wxEVT_PALETTE_CHANGED, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxPaletteChangedEventFunction) & func, (wxObject *) NULL },
 #define EVT_QUERY_NEW_PALETTE(func) { wxEVT_QUERY_NEW_PALETTE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL },
+#define EVT_WINDOW_CREATE(func) { wxEVT_CREATE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL },
+#define EVT_WINDOW_DESTROY(func) { wxEVT_DESTROY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL },
 
 // Mouse events
 #define EVT_LEFT_DOWN(func) { wxEVT_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func, (wxObject *) NULL },
index 6cbb3453ecc833eebfe655e19a05ea759dcf5d7d..55c78919087516c794021bfa08dfc5a23ccec9af 100644 (file)
 #define __SPLITTERH_G__
 
 #ifdef __GNUG__
-#pragma interface "splitter.h"
+    #pragma interface "splitter.h"
 #endif
 
-#include "wx/defs.h"
-#include "wx/window.h"
-#include "wx/string.h"
+#include "wx/window.h"                      // base class declaration
 
-#define WXSPLITTER_VERSION      1.0
+class WXDLLEXPORT wxSplitterEvent;
 
-#define wxSPLIT_HORIZONTAL      1
-#define wxSPLIT_VERTICAL        2
+// ---------------------------------------------------------------------------
+// splitter constants
+// ---------------------------------------------------------------------------
 
-#define wxSPLIT_DRAG_NONE       0
-#define wxSPLIT_DRAG_DRAGGING   1
-#define wxSPLIT_DRAG_LEFT_DOWN  2
+enum
+{
+    wxSPLIT_HORIZONTAL = 1,
+    wxSPLIT_VERTICAL
+};
 
-/*
- * wxSplitterWindow maintains one or two panes, with
- * an optional vertical or horizontal split which
- * can be used with the mouse or programmatically.
- */
+enum
+{
+    wxSPLIT_DRAG_NONE,
+    wxSPLIT_DRAG_DRAGGING,
+    wxSPLIT_DRAG_LEFT_DOWN
+};
+
+// ---------------------------------------------------------------------------
+// wxSplitterWindow maintains one or two panes, with
+// an optional vertical or horizontal split which
+// can be used with the mouse or programmatically.
+// ---------------------------------------------------------------------------
 
 // TODO:
 // 1) Perhaps make the borders sensitive to dragging in order to create a split.
@@ -114,7 +122,7 @@ public:
     int GetBorderSize() const { return m_borderSize; }
 
     // Set the sash position
-    void SetSashPosition(int position, bool redaw = TRUE);
+    void SetSashPosition(int position, bool redraw = TRUE);
 
     // Gets the sash position
     int GetSashPosition() const { return m_sashPosition; }
@@ -127,17 +135,18 @@ public:
     // FALSE from here to prevent the change from taking place.
     // Repositions sash to minimum position if pane would be too small.
     // newSashPosition here is always positive or zero.
-    virtual bool OnSashPositionChange(int& newSashPosition);
+    virtual bool OnSashPositionChange(int WXUNUSED(newSashPosition))
+        { return TRUE; }
 
     // If the sash is moved to an extreme position, a subwindow
     // is removed from the splitter window, and the app is
     // notified. The app should delete or hide the window.
-    virtual void OnUnsplit(wxWindow *removed) { removed->Show(FALSE); }
+    virtual void OnUnsplit(wxWindow *WXUNUSED(removed)) { }
 
     // Called when the sash is double-clicked.
     // The default behaviour is to remove the sash if the
     // minimum pane size is zero.
-    virtual void OnDoubleClickSash(int x, int y);
+    virtual void OnDoubleClickSash(int WXUNUSED(x), int WXUNUSED(y)) { }
 
 ////////////////////////////////////////////////////////////////////////////
 // Implementation
@@ -170,6 +179,13 @@ public:
     void InitColours();
 
 protected:
+    // our event handlers
+    void OnSashPosChanged(wxSplitterEvent& event);
+    void OnDoubleClick(wxSplitterEvent& event);
+    void OnUnsplitEvent(wxSplitterEvent& event);
+
+    void SendUnsplitEvent(wxWindow *winRemoved);
+
     int         m_splitMode;
     wxWindow*   m_windowOne;
     wxWindow*   m_windowTwo;
@@ -197,4 +213,109 @@ private:
     DECLARE_EVENT_TABLE()
 };
 
+// ----------------------------------------------------------------------------
+// event class and macros
+// ----------------------------------------------------------------------------
+
+// we reuse the same class for all splitter event types because this is the
+// usual wxWin convention, but the three event types have different kind of
+// data associated with them, so the accessors can be only used if the real
+// event type matches with the one for which the accessors make sense
+class WXDLLEXPORT wxSplitterEvent : public wxCommandEvent
+{
+public:
+    wxSplitterEvent(wxEventType type = wxEVT_NULL,
+                    wxSplitterWindow *splitter = (wxSplitterWindow *)NULL)
+        : wxCommandEvent(type)
+    {
+        SetEventObject(splitter);
+    }
+
+    // SASH_POS_CHANGED methods
+
+    // setting the sash position to -1 prevents the change from taking place at
+    // all
+    void SetSashPosition(int pos)
+    {
+        wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED );
+
+        m_data.pos = pos;
+    }
+
+    int GetSashPosition() const
+    {
+        wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED );
+
+        return m_data.pos;
+    }
+
+    // UNSPLIT event methods
+    wxWindow *GetWindowBeingRemoved() const
+    {
+        wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_UNSPLIT );
+
+        return m_data.win;
+    }
+
+    // DCLICK event methods
+    int GetX() const
+    {
+        wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED );
+
+        return m_data.pt.x;
+    }
+
+    int GetY() const
+    {
+        wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_DOUBLECLICKED );
+
+        return m_data.pt.y;
+    }
+
+private:
+    friend wxSplitterWindow;
+
+    // data for the different types of event
+    union
+    {
+        int pos;            // position for SASH_POS_CHANGED event
+        wxWindow *win;      // window being removed for UNSPLIT event
+        struct
+        {
+            int x, y;
+        } pt;               // position of double click for DCLICK event
+    } m_data;
+
+    DECLARE_DYNAMIC_CLASS(wxSplitterEvent)
+};
+
+typedef void (wxEvtHandler::*wxSplitterEventFunction)(wxSplitterEvent&);
+
+#define EVT_SPLITTER_SASH_POS_CHANGED(id, fn)                               \
+  {                                                                         \
+    wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED,                                \
+    id,                                                                     \
+    -1,                                                                     \
+    (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \
+    NULL                                                                    \
+  },
+
+#define EVT_SPLITTER_DCLICK(id, fn)                                   \
+  {                                                                         \
+    wxEVT_COMMAND_SPLITTER_DOUBLECLICKED,                                    \
+    id,                                                                     \
+    -1,                                                                     \
+    (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \
+    NULL                                                                    \
+  },
+
+#define EVT_SPLITTER_UNSPLIT(id, fn)                                        \
+  {                                                                         \
+    wxEVT_COMMAND_SPLITTER_UNSPLIT,                                         \
+    id,                                                                     \
+    -1,                                                                     \
+    (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn,  \
+    NULL                                                                    \
+  },
+
 #endif // __SPLITTERH_G__
index 63665e86916d60cd3743db4ce1da711860cc5742..d84f142a5437fddfd8e195de8eff4994c2f03298 100644 (file)
@@ -431,11 +431,23 @@ extern void WXDLLEXPORT wxLog##level(arg1, const wxChar *szFormat, ...)
 #endif
 
 #ifdef  __WXDEBUG__
-#define wxLogApiError(api, rc)                                              \
-    wxLogDebug(_T("At %s(%d) '%s' failed with error %lx (%s)."),  \
-            __TFILE__, __LINE__, api,                       \
-            rc, wxSysErrorMsg(rc))
-#define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode())
+    // make life easier for people using VC++ IDE: clicking on the message
+    // will take us immediately to the place of the failed API
+#ifdef __VISUALC__
+    #define wxLogApiError(api, rc)                                              \
+        wxLogDebug(_T("%s(%d): '%s' failed with error 0x%08lx (%s)."),          \
+                   __TFILE__, __LINE__, api,                                    \
+                   rc, wxSysErrorMsg(rc))
+#else // !VC++
+    #define wxLogApiError(api, rc)                                              \
+        wxLogDebug(_T("In file %s at line %d: '%s' failed with "                \
+                      "error 0x%08lx (%s)."),                                   \
+                   __TFILE__, __LINE__, api,                                    \
+                   rc, wxSysErrorMsg(rc))
+#endif // VC++/!VC++
+
+    #define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode())
+
 #else   //!debug
     inline void wxLogApiError(const wxChar *, long) { }
     inline void wxLogLastError(const wxChar *) { }
index 85a0e6cd34f64734aafd3daa6aef0f5f78c4414f..bc0dd1528f29d3126a825f72b51a05016a4456e1 100644 (file)
@@ -26,8 +26,8 @@ class WXDLLEXPORT wxApp ;
 class WXDLLEXPORT wxKeyEvent;
 class WXDLLEXPORT wxLog;
 
-#define wxPRINT_WINDOWS         1
-#define wxPRINT_POSTSCRIPT      2
+static const int wxPRINT_WINDOWS = 1;
+static const int wxPRINT_POSTSCRIPT = 2;
 
 WXDLLEXPORT_DATA(extern wxApp*) wxTheApp;
 
@@ -72,30 +72,30 @@ class WXDLLEXPORT wxApp: public wxEvtHandler
   // to do anything which might provoke a nested exception!
   virtual void OnFatalException() { }
 
-  inline void SetPrintMode(int mode) { m_printMode = mode; }
-  inline int GetPrintMode() const { return m_printMode; }
+  void SetPrintMode(int mode) { m_printMode = mode; }
+  int GetPrintMode() const { return m_printMode; }
 
-  inline void SetExitOnFrameDelete(bool flag) { m_exitOnFrameDelete = flag; }
-  inline bool GetExitOnFrameDelete() const { return m_exitOnFrameDelete; }
+  void SetExitOnFrameDelete(bool flag) { m_exitOnFrameDelete = flag; }
+  bool GetExitOnFrameDelete() const { return m_exitOnFrameDelete; }
 
-  inline const wxString& GetAppName() const {
+  const wxString& GetAppName() const {
       if (m_appName != _T(""))
         return m_appName;
       else return m_className;
     }
 
-  inline void SetAppName(const wxString& name) { m_appName = name; };
-  inline wxString GetClassName() const { return m_className; }
-  inline void SetClassName(const wxString& name) { m_className = name; }
+  void SetAppName(const wxString& name) { m_appName = name; };
+  wxString GetClassName() const { return m_className; }
+  void SetClassName(const wxString& name) { m_className = name; }
 
   void SetVendorName(const wxString& vendorName) { m_vendorName = vendorName; }
   const wxString& GetVendorName() const { return m_vendorName; }
 
   wxWindow *GetTopWindow() const ;
-  inline void SetTopWindow(wxWindow *win) { m_topWindow = win; }
+  void SetTopWindow(wxWindow *win) { m_topWindow = win; }
 
-  inline void SetWantDebugOutput(bool flag) { m_wantDebugOutput = flag; }
-  inline bool GetWantDebugOutput() { return m_wantDebugOutput; }
+  void SetWantDebugOutput(bool flag) { m_wantDebugOutput = flag; }
+  bool GetWantDebugOutput() { return m_wantDebugOutput; }
 
   // Send idle event to all top-level windows.
   // Returns TRUE if more idle time is requested.
@@ -105,14 +105,13 @@ class WXDLLEXPORT wxApp: public wxEvtHandler
   // Returns TRUE if more idle time is requested.
   bool SendIdleEvents(wxWindow* win);
 
-  inline void SetAuto3D(bool flag) { m_auto3D = flag; }
-  inline bool GetAuto3D() const { return m_auto3D; }
+  void SetAuto3D(bool flag) { m_auto3D = flag; }
+  bool GetAuto3D() const { return m_auto3D; }
 
   // Creates a log object
   virtual wxLog* CreateLogTarget();
 
 public:
-//  void (*work_proc)(wxApp*app); // work procedure;
   int               argc;
   char **           argv;
 
@@ -127,7 +126,7 @@ protected:
   int               m_printMode; // wxPRINT_WINDOWS, wxPRINT_POSTSCRIPT
   bool              m_auto3D ;   // Always use 3D controls, except
                                  // where overriden
-  static wxAppInitializerFunction      m_appInitFn;
+  static wxAppInitializerFunction m_appInitFn;
 
 /* Windows-specific wxApp definitions */
 
@@ -150,7 +149,6 @@ public:
   int GetComCtl32Version() const;
 
 public:
-  static long       sm_lastMessageTime;
   int               m_nCmdShow;
 
 protected:
index e4410e7b0d640a013d552d69af526ef19cee6799..35d5d8c4c3f51259478c287b146e084b5ce92599 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     01/02/97
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_CONTROL_H_
@@ -29,34 +29,15 @@ public:
    virtual ~wxControl();
 
    // Simulates an event
-   virtual void Command(wxCommandEvent& WXUNUSED(event)) { }
-   // Calls the callback and appropriate event handlers
-   virtual void ProcessCommand(wxCommandEvent& event); 
-
-   virtual void SetClientSize(int width, int height);
-   virtual void SetClientSize(const wxSize& sz) { wxWindow::SetClientSize(sz); }
-
-   virtual void SetLabel(const wxString& label);
-   virtual wxString GetLabel() const;
+   bool Command(wxCommandEvent& event) { return ProcessCommand(event); }
 
-#if WXWIN_COMPATIBILITY
-   virtual void SetButtonColour(const wxColour& WXUNUSED(col)) { }
-   wxColour* GetButtonColour() const { return NULL; }
-
-   inline virtual void SetLabelFont(const wxFont& font);
-   inline virtual void SetButtonFont(const wxFont& font);
-   inline wxFont& GetLabelFont() const;
-   inline wxFont& GetButtonFont() const;
-#endif
+   // Calls the callback and appropriate event handlers
+   bool ProcessCommand(wxCommandEvent& event);
 
    // Places item in centre of panel - so can't be used BEFORE panel->Fit()
    void Centre(int direction = wxHORIZONTAL);
 
-   // Adds callback
-   inline void Callback(const wxFunction function);
-
    // MSW-specific
-   
 #ifdef __WIN95__
    virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
 #endif // Win95
@@ -65,33 +46,44 @@ public:
    virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *WXUNUSED(item)) { return FALSE; };
    virtual bool MSWOnMeasure(WXMEASUREITEMSTRUCT *WXUNUSED(item)) { return FALSE; };
 
-   wxFunction GetCallback() { return m_callback; }
    wxList& GetSubcontrols() { return m_subControls; }
 
    void OnEraseBackground(wxEraseEvent& event);
 
+#if WXWIN_COMPATIBILITY
+   virtual void SetButtonColour(const wxColour& WXUNUSED(col)) { }
+   wxColour* GetButtonColour() const { return NULL; }
+
+   inline virtual void SetLabelFont(const wxFont& font);
+   inline virtual void SetButtonFont(const wxFont& font);
+   inline wxFont& GetLabelFont() const;
+   inline wxFont& GetButtonFont() const;
+
+   // Adds callback
+   inline void Callback(const wxFunction function);
+
+   wxFunction GetCallback() { return m_callback; }
+
 protected:
    wxFunction       m_callback;     // Callback associated with the window
-   // MSW implementation
-   wxList           m_subControls; // For controls like radiobuttons which are really composite
+#endif // WXWIN_COMPATIBILITY
+
+protected:
+   // For controls like radiobuttons which are really composite
+   wxList           m_subControls;
 
 private:
    DECLARE_EVENT_TABLE()
 };
 
-// Adds callback
-inline void wxControl::Callback(const wxFunction function)
-{
-    m_callback = function;
-};
 
 #if WXWIN_COMPATIBILITY
+    inline void wxControl::Callback(const wxFunction f) { m_callback = f; };
     inline wxFont& wxControl::GetLabelFont() const { return GetFont() ; }
     inline wxFont& wxControl::GetButtonFont() const { return GetFont() ; }
     inline void wxControl::SetLabelFont(const wxFont& font) { SetFont(font); }
     inline void wxControl::SetButtonFont(const wxFont& font) { SetFont(font); }
-#endif
+#endif // WXWIN_COMPATIBILITY
 
 #endif
     // _WX_CONTROL_H_
index f2ca533725a8c21aa3f92a3b5e41adb891861343..88516932353bef2b18203157cfad2f75084c41c5 100644 (file)
@@ -167,67 +167,5 @@ protected:
     WXHPALETTE        m_oldPalette;
 };
 
-// Logical to device
-// Absolute
-#define XLOG2DEV(x) (x)
-#define YLOG2DEV(y) (y)
-
-// Relative
-#define XLOG2DEVREL(x) (x)
-#define YLOG2DEVREL(y) (y)
-
-// Device to logical
-// Absolute
-#define XDEV2LOG(x) (x)
-
-#define YDEV2LOG(y) (y)
-
-// Relative
-#define XDEV2LOGREL(x) (x)
-#define YDEV2LOGREL(y) (y)
-
-/*
- * Have the same macros as for XView but not for every operation:
- * just for calculating window/viewport extent (a better way of scaling).
- */
-
-// Logical to device
-// Absolute
-#define MS_XLOG2DEV(x) LogicalToDevice(x)
-
-#define MS_YLOG2DEV(y) LogicalToDevice(y)
-
-// Relative
-#define MS_XLOG2DEVREL(x) LogicalToDeviceXRel(x)
-#define MS_YLOG2DEVREL(y) LogicalToDeviceYRel(y)
-
-// Device to logical
-// Absolute
-#define MS_XDEV2LOG(x) DeviceToLogicalX(x)
-
-#define MS_YDEV2LOG(y) DeviceToLogicalY(y)
-
-// Relative
-#define MS_XDEV2LOGREL(x) DeviceToLogicalXRel(x)
-#define MS_YDEV2LOGREL(y) DeviceToLogicalYRel(y)
-
-#define MM_POINTS      9
-#define MM_METRIC     10
-
-// Conversion
-#define METRIC_CONVERSION_CONSTANT  0.0393700787
-
-// Scaling factors for various unit conversions
-#define mm2inches (METRIC_CONVERSION_CONSTANT)
-#define inches2mm (1/METRIC_CONVERSION_CONSTANT)
-
-#define mm2twips (METRIC_CONVERSION_CONSTANT*1440)
-#define twips2mm (1/(METRIC_CONVERSION_CONSTANT*1440))
-
-#define mm2pt (METRIC_CONVERSION_CONSTANT*72)
-#define pt2mm (1/(METRIC_CONVERSION_CONSTANT*72))
-
-#define     wx_round(a)    (int)((a)+.5)
-
 #endif
     // _WX_DC_H_
index c4e4a0b6ce19e0c90c5adf891418e6290be33fd0..899febae544a301ad5142d919bb5c6181bfb3889 100644 (file)
@@ -110,6 +110,8 @@ public:
     // implementation
     // --------------
 
+    long MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+
     virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
                                 WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
 
index efa973ec85153c6eb52a7619dc5c07e7f9022d1c..36458bf83a49dc41367727408fcebe0017bc6491 100644 (file)
@@ -13,7 +13,7 @@
 #define _WX_FRAME_H_
 
 #ifdef __GNUG__
-#pragma interface "frame.h"
+    #pragma interface "frame.h"
 #endif
 
 #include "wx/window.h"
@@ -30,7 +30,7 @@ class WXDLLEXPORT wxStatusBar;
 
 class WXDLLEXPORT wxFrame : public wxWindow
 {
-DECLARE_DYNAMIC_CLASS(wxFrame)
+    DECLARE_DYNAMIC_CLASS(wxFrame)
 
 public:
     wxFrame();
@@ -70,17 +70,13 @@ public:
 
     // Set menu bar
     void SetMenuBar(wxMenuBar *menu_bar);
-    virtual wxMenuBar *GetMenuBar() const ;
-
-    // Set title
-    void SetTitle(const wxString& title);
-    wxString GetTitle() const ;
-
-    void Centre(int direction = wxBOTH);
+    virtual wxMenuBar *GetMenuBar() const;
 
     // Call this to simulate a menu command
-    virtual void Command(int id);
-    virtual void ProcessCommand(int id);
+    bool Command(int id) { ProcessCommand(id); }
+
+    // process menu command: returns TRUE if processed
+    bool ProcessCommand(int id);
 
     // Set icon
     virtual void SetIcon(const wxIcon& icon);
@@ -123,16 +119,13 @@ public:
     static void UseNativeStatusBar(bool useNative) { m_useNativeStatusBar = useNative; };
     static bool UsesNativeStatusBar() { return m_useNativeStatusBar; };
 
-    // Fit frame around subwindows
-    virtual void Fit();
-
     // Iconize
     virtual void Iconize(bool iconize);
 
-    virtual bool IsIconized() const ;
+    virtual bool IsIconized() const;
 
     // Is it maximized?
-    virtual bool IsMaximized() const ;
+    virtual bool IsMaximized() const;
 
     // Compatibility
     bool Iconized() const { return IsIconized(); }
@@ -147,7 +140,7 @@ public:
     void DoMenuUpdates();
     void DoMenuUpdates(wxMenu* menu, wxWindow* focusWin);
 
-    WXHMENU GetWinMenu() const ;
+    WXHMENU GetWinMenu() const { return m_hMenu; }
 
     // Returns the origin of client area (may be different from (0,0) if the
     // frame has a toolbar)
@@ -155,19 +148,15 @@ public:
 
     // Implementation only from here
         // event handlers
-    bool MSWOnPaint();
-    WXHICON MSWOnQueryDragIcon();
-    bool MSWOnSize(int x, int y, WXUINT flag);
-    bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control);
-    bool MSWOnMenuHighlight(WXWORD item, WXWORD flags, WXHMENU sysmenu);
-    bool MSWProcessMessage(WXMSG *msg);
-    bool MSWTranslateMessage(WXMSG *msg);
+    bool HandlePaint();
+    bool HandleSize(int x, int y, WXUINT flag);
+    bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control);
+    bool HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu);
+
     bool MSWCreate(int id, wxWindow *parent, const char *wclass,
                    wxWindow *wx_win, const char *title,
                    int x, int y, int width, int height, long style);
 
-    bool HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu);
-
   // tooltip management
 #if wxUSE_TOOLTIPS
     WXHWND GetToolTipCtrl() const { return m_hwndToolTip; }
@@ -177,17 +166,24 @@ public:
 protected:
     // override base class virtuals
     virtual void DoGetClientSize(int *width, int *height) const;
-    virtual void DoGetSize(int *width, int *height) const ;
-    virtual void DoGetPosition(int *x, int *y) const ;
+    virtual void DoGetSize(int *width, int *height) const;
+    virtual void DoGetPosition(int *x, int *y) const;
 
     virtual void DoSetSize(int x, int y,
                            int width, int height,
                            int sizeFlags = wxSIZE_AUTO);
     virtual void DoSetClientSize(int width, int height);
 
+    // a plug in for MDI frame classes which need to do something special when
+    // the menubar is set
+    virtual void InternalSetMenuBar();
+
     // propagate our state change to all child frames
     void IconizeChildFrames(bool bIconize);
 
+    // we add menu bar accel processing
+    bool MSWTranslateMessage(WXMSG* pMsg);
+
     // window proc for the frames
     long MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
 
@@ -196,7 +192,7 @@ protected:
     wxIcon                m_icon;
     bool                  m_iconized;
     WXHICON               m_defaultIcon;
-    wxToolBar *           m_frameToolBar ;
+    wxToolBar *           m_frameToolBar;
 
     static bool           m_useNativeStatusBar;
 
index 8ee5162ed27c4b6984cee26eadb3c0e473c363f2..dbde573c9fab36263634c5d1eee9b10629b41989 100644 (file)
@@ -407,16 +407,6 @@ class WXDLLEXPORT wxListCtrl: public wxControl
   // data is arbitrary data to be passed to the sort function.
   bool SortItems(wxListCtrlCompare fn, long data);
 
-/* Why should we need this function? Leave for now.
- * WE NEED IT because item data may have changed,
- * but the display needs refreshing (in string callback mode)
-  // Updates an item. If the list control has the wxLI_AUTO_ARRANGE style,
-  // the items will be rearranged.
-  bool Update(long item);
-*/
-
-  void Command(wxCommandEvent& event) { ProcessCommand(event); };
-
   // IMPLEMENTATION
   virtual bool MSWCommand(WXUINT param, WXWORD id);
   virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
index f19bf39b8ec1e7530d27ca5bfb0dc1ce02ec7aba..397ab3f1ddd91c7cf2f2e1ff823f10c47715dbd9 100644 (file)
@@ -58,17 +58,15 @@ public:
     // accessors
     // ---------
 
-    void SetMenuBar(wxMenuBar *menu_bar);
-
     // Get the active MDI child window (Windows only)
-    wxMDIChildFrame *GetActiveChild() const ;
+    wxMDIChildFrame *GetActiveChild() const;
 
     // Get the client window
     wxMDIClientWindow *GetClientWindow() const { return m_clientWindow; }
 
     // Create the client window class (don't Create the window,
     // just return a new class)
-    virtual wxMDIClientWindow *OnCreateClient(void) ;
+    virtual wxMDIClientWindow *OnCreateClient(void);
 
     WXHMENU GetWindowMenu() const { return m_windowMenu; }
 
@@ -87,25 +85,25 @@ public:
     void OnSysColourChanged(wxSysColourChangedEvent& event);
 
     void OnSize(wxSizeEvent& event);
-    void OnActivate(wxActivateEvent& event);
 
-    virtual bool MSWOnActivate(int state, bool minimized, WXHWND activate);
-    virtual bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control);
+    bool HandleActivate(int state, bool minimized, WXHWND activate);
+    bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control);
 
     // override window proc for MDI-specific message processing
     virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
 
     virtual long MSWDefWindowProc(WXUINT, WXWPARAM, WXLPARAM);
-    virtual bool MSWProcessMessage(WXMSG* msg);
     virtual bool MSWTranslateMessage(WXMSG* msg);
 
 protected:
+    virtual void InternalSetMenuBar();
+
     wxMDIClientWindow *             m_clientWindow;
     wxMDIChildFrame *               m_currentChild;
     WXHMENU                         m_windowMenu;
 
     // TRUE if MDI Frame is intercepting commands, not child
-    bool m_parentFrameActive; 
+    bool m_parentFrameActive;
 
 private:
     friend class WXDLLEXPORT wxMDIChildFrame;
@@ -144,9 +142,6 @@ public:
                 long style = wxDEFAULT_FRAME_STYLE,
                 const wxString& name = wxFrameNameStr);
 
-    // Set menu bar
-    void SetMenuBar(wxMenuBar *menu_bar);
-
     // MDI operations
     virtual void Maximize();
     virtual void Restore();
@@ -154,21 +149,24 @@ public:
 
     // Handlers
 
-    bool MSWOnMDIActivate(long bActivate, WXHWND, WXHWND);
-    bool MSWOnSize(int x, int y, WXUINT);
-    bool MSWOnWindowPosChanging(void *lpPos);
-    bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control);
-    long MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
-    bool MSWProcessMessage(WXMSG *msg);
-    bool MSWTranslateMessage(WXMSG *msg);
-    void MSWDestroyWindow();
+    bool HandleMDIActivate(long bActivate, WXHWND, WXHWND);
+    bool HandleSize(int x, int y, WXUINT);
+    bool HandleWindowPosChanging(void *lpPos);
+    bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control);
+
+    virtual long MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+    virtual long MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+    virtual bool MSWTranslateMessage(WXMSG *msg);
+
+    virtual void MSWDestroyWindow();
 
     // Implementation
     bool ResetWindowStyle(void *vrect);
 
 protected:
-    virtual void DoGetPosition(int *x, int *y) const ;
+    virtual void DoGetPosition(int *x, int *y) const;
     virtual void DoSetClientSize(int width, int height);
+    virtual void InternalSetMenuBar();
 };
 
 // ---------------------------------------------------------------------------
@@ -180,14 +178,14 @@ class WXDLLEXPORT wxMDIClientWindow : public wxWindow
     DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
 
 public:
-    wxMDIClientWindow();
+    wxMDIClientWindow() { Init(); }
     wxMDIClientWindow(wxMDIParentFrame *parent, long style = 0)
     {
+        Init();
+
         CreateClient(parent, style);
     }
 
-    ~wxMDIClientWindow();
-
     // Note: this is virtual, to allow overridden behaviour.
     virtual bool CreateClient(wxMDIParentFrame *parent,
                               long style = wxVSCROLL | wxHSCROLL);
@@ -195,13 +193,9 @@ public:
     // Explicitly call default scroll behaviour
     void OnScroll(wxScrollEvent& event);
 
-    // Window procedure
-    virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
-
-    // Calls an appropriate default window procedure
-    virtual long MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
-
 protected:
+    void Init() { m_scrollX = m_scrollY = 0; }
+
     int m_scrollX, m_scrollY;
 
 private:
index c0e08f9d78d0af8804a796919975ffcaac15e77a..f01dafd08061662b8a5615cfa55de960005db2eb 100644 (file)
@@ -103,20 +103,12 @@ public:
     // menu or associated window will be used.
     void UpdateUI(wxEvtHandler* source = (wxEvtHandler*)NULL);
 
-    void ProcessCommand(wxCommandEvent& event);
+    bool ProcessCommand(wxCommandEvent& event);
 
     virtual void SetParent(wxEvtHandler *parent) { m_parent = parent; }
     void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; }
     wxEvtHandler *GetEventHandler() const { return m_eventHandler; }
 
-#ifdef WXWIN_COMPATIBILITY
-    void Callback(const wxFunction func) { m_callback = func; }
-
-    // compatibility: these functions are deprecated
-    bool Enabled(int id) const { return IsEnabled(id); }
-    bool Checked(int id) const { return IsChecked(id); }
-#endif // WXWIN_COMPATIBILITY
-
     // IMPLEMENTATION
     bool MSWCommand(WXUINT param, WXWORD id);
 
@@ -133,6 +125,20 @@ public:
     void Attach(wxMenuBar *menubar);
     void Detach();
 
+    size_t GetAccelCount() const { return m_accelKeyCodes.GetCount(); }
+    size_t CopyAccels(wxAcceleratorEntry *accels) const;
+
+#ifdef WXWIN_COMPATIBILITY
+    void Callback(const wxFunction func) { m_callback = func; }
+
+    // compatibility: these functions are deprecated
+    bool Enabled(int id) const { return IsEnabled(id); }
+    bool Checked(int id) const { return IsChecked(id); }
+
+private:
+    wxFunction        m_callback;
+#endif // WXWIN_COMPATIBILITY
+
 private:
     bool              m_doBreak;
 
@@ -142,7 +148,6 @@ private:
     // Might be better to have a flag saying whether it's deleteable or not.
     WXHMENU           m_savehMenu ; // Used for Enable() on popup
     WXHMENU           m_hMenu;
-    wxFunction        m_callback;
 
     int               m_noItems;
     wxString          m_title;
@@ -153,6 +158,9 @@ private:
     wxEvtHandler *    m_eventHandler;
     wxWindow         *m_pInvokingWindow;
     void*             m_clientData;
+
+    // the accelerators data
+    wxArrayInt        m_accelKeyCodes, m_accelFlags, m_accelIds;
 };
 
 // ----------------------------------------------------------------------------
@@ -235,12 +243,10 @@ public:
         // get the frame we live in
     wxFrame *GetFrame() const { return m_menuBarFrame; }
         // attach to a frame
-    void Attach(wxFrame *frame)
-    {
-        wxASSERT_MSG( !m_menuBarFrame, _T("menubar already attached!") );
+    void Attach(wxFrame *frame);
 
-        m_menuBarFrame = frame;
-    }
+        // get the accel table for the menus
+    const wxAcceleratorTable& GetAccelTable() const { return m_accelTable; }
         // get the menu handle
     WXHMENU GetHMenu() const { return m_hMenu; }
 
@@ -258,6 +264,9 @@ protected:
     wxString     *m_titles;
     wxFrame      *m_menuBarFrame;
     WXHMENU       m_hMenu;
+
+    // the accelerator table for all accelerators in all our menus
+    wxAcceleratorTable m_accelTable;
 };
 
 #endif // _WX_MENU_H_
index 7ad3e36e142b9147d76ef316543b3ab4726dd47d..60a4942b279bb765a3464a027c8981fc30143410 100644 (file)
@@ -172,15 +172,13 @@ public:
 
   // callbacks
   // ---------
-  void OnSize(wxSizeEvent& event);
+  void OnWindowCreate(wxWindowCreateEvent& event);
   void OnSelChange(wxNotebookEvent& event);
   void OnSetFocus(wxFocusEvent& event);
   void OnNavigationKey(wxNavigationKeyEvent& event);
-  void OnEraseBackground(wxEraseEvent& event);
 
   // base class virtuals
   // -------------------
-  virtual void Command(wxCommandEvent& event);
   virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
   virtual void SetConstraintSizes(bool recurse = TRUE);
   virtual bool DoPhase(int nPhase);
index 39292f3c980a3aacc77e2e009ea36496b7bf1d4d..e960fad8806bb6d9b8c92f55d929bd34cafe858a 100644 (file)
 
 #include <windows.h>
 
+// undefine conflicting symbols which were defined in windows.h
+#include "wx/msw/winundef.h"
+
 class WXDLLEXPORT wxFont;
 
+// ---------------------------------------------------------------------------
+// private constants
+// ---------------------------------------------------------------------------
+
+// Conversion
+static const double METRIC_CONVERSION_CONSTANT = 0.0393700787;
+
+// Scaling factors for various unit conversions
+static const double mm2inches = (METRIC_CONVERSION_CONSTANT);
+static const double inches2mm = (1/METRIC_CONVERSION_CONSTANT);
+
+static const double mm2twips = (METRIC_CONVERSION_CONSTANT*1440);
+static const double twips2mm = (1/(METRIC_CONVERSION_CONSTANT*1440));
+
+static const double mm2pt = (METRIC_CONVERSION_CONSTANT*72);
+static const double pt2mm = (1/(METRIC_CONVERSION_CONSTANT*72));
+
 // ---------------------------------------------------------------------------
 // standard icons from the resources
 // ---------------------------------------------------------------------------
@@ -178,7 +198,9 @@ extern LONG APIENTRY _EXPORT
 #endif // USE_DBWIN32
 
 // ---------------------------------------------------------------------------
-// macros to make casting between WXFOO and FOO a bit easier
+// macros to make casting between WXFOO and FOO a bit easier: the GetFoo()
+// returns Foo cast to the Windows type for oruselves, while GetFoosFoo() takes
+// an argument which should be a pointer to wxFoo (is this really clear?)
 // ---------------------------------------------------------------------------
 
 #define GetHwnd()               ((HWND)GetHWND())
@@ -186,8 +208,11 @@ extern LONG APIENTRY _EXPORT
 
 #define GetHdc()                ((HDC)GetHDC())
 
+#define GetHicon()              ((HICON)GetHICON())
+#define GetIconHicon(icon)      ((HICON)(icon).GetHICON())
+
 #define GetHaccel()             ((HACCEL)GetHACCEL())
-#define GetTableHaccel(table)   ((HACCEL)((table)->GetHACCEL()))
+#define GetTableHaccel(table)   ((HACCEL)((table).GetHACCEL()))
 
 // ---------------------------------------------------------------------------
 // global data
@@ -226,8 +251,9 @@ WXDLLEXPORT extern wxString wxGetWindowText(WXHWND hWnd);
 // get the window class name
 WXDLLEXPORT extern wxString wxGetWindowClass(WXHWND hWnd);
 
-// get the window id
-WXDLLEXPORT extern wxWindowID wxGetWindowId(WXHWND hWnd);
+// get the window id (should be unsigned, hence this is not wxWindowID which
+// is, for mainly historical reasons, signed)
+WXDLLEXPORT extern WXWORD wxGetWindowId(WXHWND hWnd);
 
 // Does this window style specify any border?
 inline bool wxStyleHasBorder(long style)
index 98d4410feb9512027c9e5c0cd12b8e0347be6b72..161df41293a9fee20fe5be870ab3213b347f53af 100644 (file)
@@ -73,8 +73,6 @@ public:
     // Operations
     ////////////////////////////////////////////////////////////////////////////
 
-    void Command(wxCommandEvent& event) { ProcessCommand(event); };
-
     // IMPLEMENTATION
     virtual bool MSWCommand(WXUINT param, WXWORD id);
     virtual bool MSWOnScroll(int orientation, WXWORD wParam,
index 42cb47350a0722cc5a1f2589ea52134d856700e1..1d0b3fb8098a05eea86a425d50ab694ca1be1a19 100644 (file)
@@ -63,9 +63,6 @@ public:
     virtual bool AcceptsFocus() const { return FALSE; }
 
     // IMPLEMENTATION
-    virtual void Command(wxCommandEvent& WXUNUSED(event)) { }
-    virtual void ProcessCommand(wxCommandEvent& WXUNUSED(event)) { }
-
 #ifdef __WIN16__
     virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *item);
     virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
index ed02305c74c8699390a20f93b986a94862a93416..9a4cd8ff4f07a0eb61fae48453582428c2a25558 100644 (file)
@@ -45,9 +45,6 @@ public:
         long style = 0,
         const wxString& name = wxStaticBoxNameStr);
     
-    virtual void Command(wxCommandEvent& WXUNUSED(event)) { }
-    virtual void ProcessCommand(wxCommandEvent& WXUNUSED(event)) { }
-    
     void OnEraseBackground(wxEraseEvent& event);
     
     virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
index 053651b819b6852e9fc817cffc3d775917e7cea2..090e96eec1fdebece4fe5d5993564f395336baa2 100644 (file)
@@ -47,16 +47,12 @@ public:
     // accessors
     void SetLabel(const wxString& label);
     
-    // operations
-    virtual void Command(wxCommandEvent& WXUNUSED(event)) { }
-    virtual void ProcessCommand(wxCommandEvent& WXUNUSED(event)) { }
-    
     // overriden base class virtuals
     virtual bool AcceptsFocus() const { return FALSE; }
     
     // callbacks
     virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
-        WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+                                WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
     virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
 
 protected:
index 9f425689f18b5948eaa32dcbdeebd8d3d34552ed..ced0e85065e4252d7031e69be35d5ad8b359d166 100644 (file)
@@ -113,17 +113,8 @@ class WXDLLEXPORT wxTabCtrl: public wxControl
     // Insert an item
     bool InsertItem(int item, const wxString& text, int imageId = -1, void* data = NULL);
 
-// Implementation
+    // Implementation
 
-    // Call default behaviour
-    void OnPaint(wxPaintEvent& event) { Default() ; }
-    void OnSize(wxSizeEvent& event) { Default() ; }
-    void OnMouseEvent(wxMouseEvent& event) { Default() ; }
-    void OnKillFocus(wxFocusEvent& event) { Default() ; }
-
-    void Command(wxCommandEvent& event);
-
-    virtual bool MSWCommand(WXUINT param, WXWORD id);
     virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
 
     // Responds to colour changes
index 6485d207f5ba389a9cbd323c9b102028f0754d7f..dcc678db06c28b38a7a6c788f0c0697ea2cee2c4 100644 (file)
@@ -29,24 +29,21 @@ class WXDLLEXPORT wxToolBar95: public wxToolBarBase
    * Public interface
    */
 
-  wxToolBar95(void);
+  wxToolBar95();
 
-  inline wxToolBar95(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+  wxToolBar95(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
             long style = wxNO_BORDER|wxTB_HORIZONTAL,
             const wxString& name = wxToolBarNameStr)
   {
     Create(parent, id, pos, size, style, name);
   }
-  ~wxToolBar95(void);
+  ~wxToolBar95();
 
   bool Create(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
             long style = wxNO_BORDER|wxTB_HORIZONTAL,
             const wxString& name = wxToolBarNameStr);
 
   // Call default behaviour
-  void OnPaint(wxPaintEvent& WXUNUSED(event)) { Default() ; }
-  void OnSize(wxSizeEvent& WXUNUSED(event)) { Default() ; }
-  void OnKillFocus(wxFocusEvent& WXUNUSED(event)) { Default() ; }
   void OnMouseEvent(wxMouseEvent& event);
 
   // Handle wxToolBar95 events
@@ -62,21 +59,21 @@ class WXDLLEXPORT wxToolBar95: public wxToolBarBase
   void SetToolBitmapSize(const wxSize& size);
   void EnableTool(int toolIndex, bool enable); // additional drawing on enabling
   void ToggleTool(int toolIndex, bool toggle); // toggle is TRUE if toggled on
-  void ClearTools(void);
+  void ClearTools();
 
   // The button size is bigger than the bitmap size
-  wxSize GetToolSize(void) const;
+  wxSize GetToolSize() const;
 
-  wxSize GetMaxSize(void) const;
+  wxSize GetMaxSize() const;
 
   void GetSize(int *w, int *y) const;
 
   virtual bool GetToolState(int toolIndex) const;
 
   // Add all the buttons: required for Win95.
-  virtual bool CreateTools(void);
+  virtual bool CreateTools();
   virtual void SetRows(int nRows);
-  virtual void LayoutButtons(void) {}
+  virtual void LayoutButtons() {}
 
   // The post-tool-addition call
   bool Realize() { return CreateTools(); };
index 94c365b597a2a0c1937cd3c429c5698139b41f14..7b0864f5b5b29fd82206ae0e618d0607b9a91aff 100644 (file)
@@ -152,7 +152,6 @@ public:
     // ---------
     void OnDropFiles(wxDropFilesEvent& event);
     void OnChar(wxKeyEvent& event); // Process 'enter' if required
-    void OnEraseBackground(wxEraseEvent& event);
 
     void OnCut(wxCommandEvent& event);
     void OnCopy(wxCommandEvent& event);
index 105b5674479b251aadd4e57f229fdd9b1a30d7d4..429aa6983ea5fdcb38bf9fac618b309b88cd6250 100644 (file)
@@ -447,7 +447,6 @@ public:
 
     // implementation
     // --------------
-    void Command(wxCommandEvent& event) { ProcessCommand(event); };
     virtual bool MSWCommand(WXUINT param, WXWORD id);
     virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
 
index 7d2e8bd7a3967ae1e377fd830cb41a7f392965f0..febe2c9b2e884355d741842b24e10378349fafa8 100644 (file)
     #pragma interface "window.h"
 #endif
 
-// windows.h #defines the following identifiers which are also used in wxWin
-#ifdef GetCharWidth
-    #undef GetCharWidth
-#endif
-
-#ifdef FindWindow
-    #undef FindWindow
-#endif
+#include "wx/msw/winundef.h"
 
 // VZ: apparently some version of Windows send extra mouse move messages after
 //     a mouse click. My tests under NT 4.0 and 95 didn't show it so I'm
@@ -84,6 +77,9 @@ public:
                 const wxString& name = wxPanelNameStr);
 
     // implement base class pure virtuals
+    virtual void SetTitle( const wxString& title);
+    virtual wxString GetTitle() const;
+
     virtual void Raise();
     virtual void Lower();
 
@@ -145,6 +141,14 @@ public:
     virtual void SetScrollPage(int orient, int page, bool refresh = TRUE);
     virtual int OldGetScrollRange(int orient) const;
     virtual int GetScrollPage(int orient) const;
+
+    // event handlers
+        // Handle a control command
+    virtual void OnCommand(wxWindow& win, wxCommandEvent& event);
+
+        // Override to define new behaviour for default action (e.g. double
+        // clicking on a listbox)
+    virtual void OnDefaultAction(wxControl * WXUNUSED(initiatingItem)) { }
 #endif // WXWIN_COMPATIBILITY
 
     // caret manipulation (MSW only)
@@ -155,20 +159,12 @@ public:
     virtual void SetCaretPos(int x, int y);
     virtual void GetCaretPos(int *x, int *y) const;
 
-    // event handlers (FIXME: shouldn't they be inside WXWIN_COMPATIBILITY?)
-        // Handle a control command
-    virtual void OnCommand(wxWindow& win, wxCommandEvent& event);
-
-        // Override to define new behaviour for default action (e.g. double
-        // clicking on a listbox)
-    virtual void OnDefaultAction(wxControl *initiatingItem);
-
     // Native resource loading (implemented in src/msw/nativdlg.cpp)
     // FIXME: should they really be all virtual?
     virtual bool LoadNativeDialog(wxWindow* parent, wxWindowID& id);
     virtual bool LoadNativeDialog(wxWindow* parent, const wxString& name);
-    virtual wxWindow* GetWindowChild1(wxWindowID id);
-    virtual wxWindow* GetWindowChild(wxWindowID id);
+    wxWindow* GetWindowChild1(wxWindowID id);
+    wxWindow* GetWindowChild(wxWindowID id);
 
     // implementation from now on
     // --------------------------
@@ -206,14 +202,12 @@ public:
     // Windows subclassing
     void SubclassWin(WXHWND hWnd);
     void UnsubclassWin();
-    virtual bool MSWCommand(WXUINT param, WXWORD id);
 
     WXFARPROC MSWGetOldWndProc() const { return m_oldWndProc; }
     void MSWSetOldWndProc(WXFARPROC proc) { m_oldWndProc = proc; }
 
-    virtual wxWindow *FindItem(int id) const;
-    virtual wxWindow *FindItemByHWND(WXHWND hWnd, bool controlOnly = FALSE) const ;
-    virtual void PreDelete(WXHDC dc);              // Allows system cleanup
+    wxWindow *FindItem(int id) const;
+    wxWindow *FindItemByHWND(WXHWND hWnd, bool controlOnly = FALSE) const;
 
     // Make a Windows extended style from the given wxWindows window style
     virtual WXDWORD MakeExtendedStyle(long style, bool eliminateBorders = TRUE);
@@ -223,8 +217,6 @@ public:
     // MSW only: TRUE if this control is part of the main control
     virtual bool ContainsHWND(WXHWND WXUNUSED(hWnd)) const { return FALSE; };
 
-    wxObject *GetChild(int number) const ;
-
     // returns TRUE if the window has been created
     bool MSWCreate(int id,
                    wxWindow *parent,
@@ -235,9 +227,12 @@ public:
                    WXDWORD style,
                    const char *dialog_template = NULL,
                    WXDWORD exendedStyle = 0);
+    virtual bool MSWCommand(WXUINT param, WXWORD id);
 
-    // Actually defined in wx_canvs.cc since requires wxCanvas declaration
-    virtual void MSWDeviceToLogical(float *x, float *y) const ;
+#if WXWIN_COMPATIBILITY
+    wxObject *GetChild(int number) const;
+    virtual void MSWDeviceToLogical(float *x, float *y) const;
+#endif // WXWIN_COMPATIBILITY
 
     // Create an appropriate wxWindow from a HWND
     virtual wxWindow* CreateWindowFromHWND(wxWindow* parent, WXHWND hWnd);
@@ -248,33 +243,68 @@ public:
     // Setup background and foreground colours correctly
     virtual void SetupColours();
 
+    // ------------------------------------------------------------------------
+    // helpers for message handlers: these perform the same function as the
+    // message crackers from <windowsx.h> - they unpack WPARAM and LPARAM into
+    // the correct parameters
+    // ------------------------------------------------------------------------
+
+    void UnpackCommand(WXWPARAM wParam, WXLPARAM lParam,
+                       WXWORD *id, WXHWND *hwnd, WXWORD *cmd);
+    void UnpackActivate(WXWPARAM wParam, WXLPARAM lParam,
+                        WXWORD *state, WXWORD *minimized, WXHWND *hwnd);
+    void UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
+                      WXWORD *code, WXWORD *pos, WXHWND *hwnd);
+    void UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
+                        WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd);
+    void UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
+                          WXWORD *item, WXWORD *flags, WXHMENU *hmenu);
+
     // ------------------------------------------------------------------------
     // internal handlers for MSW messages: all handlers return a boolen value:
     // TRUE means that the handler processed the event and FALSE that it didn't
     // ------------------------------------------------------------------------
 
-    // TODO: all this should go away, overriding MSWWindowProc() is enough to
-    //       implement this functionality
-    virtual bool MSWOnCreate(WXLPCREATESTRUCT cs, bool *mayCreate);
-    virtual bool MSWOnPaint();
-    virtual bool MSWOnEraseBkgnd(WXHDC pDC);
-    virtual bool MSWOnSize(int x, int y, WXUINT flag);
-
-    virtual bool MSWOnQueryDragIcon(WXHICON *hIcon);
-    virtual bool MSWOnWindowPosChanging(void *lpPos);
+    // there are several cases where we have virtual functions for Windows
+    // message processing: this is because these messages often require to be
+    // processed in a different manner in the derived classes. For all other
+    // messages, however, we do *not* have corresponding MSWOnXXX() function
+    // and if the derived class wants to process them, it should override
+    // MSWWindowProc() directly.
 
-    // both horizontal and vertical
+    // scroll event (both horizontal and vertical)
     virtual bool MSWOnScroll(int orientation, WXWORD nSBCode,
                              WXWORD pos, WXHWND control);
 
-    virtual bool MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control);
-    virtual bool MSWOnSysCommand(WXWPARAM wParam, WXLPARAM lParam);
-
+    // child control notifications
 #ifdef __WIN95__
     virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
 #endif // __WIN95__
 
-    virtual bool MSWOnCtlColor(WXHBRUSH *hBrush,
+    // owner-drawn controls need to process these messages
+    virtual bool MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *item);
+    virtual bool MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *item);
+
+    // the rest are not virtual
+    bool HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate);
+    bool HandleInitDialog(WXHWND hWndFocus);
+    bool HandleDestroy();
+
+    bool HandlePaint();
+    bool HandleEraseBkgnd(WXHDC pDC);
+
+    bool HandleMinimize();
+    bool HandleMaximize();
+    bool HandleSize(int x, int y, WXUINT flag);
+    bool HandleGetMinMaxInfo(void *mmInfo);
+
+    bool HandleShow(bool show, int status);
+    bool HandleActivate(int flag, bool minimized, WXHWND activate);
+
+    bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control);
+    bool HandleSysCommand(WXWPARAM wParam, WXLPARAM lParam);
+
+    bool HandleCtlColor(WXHBRUSH *hBrush,
                                WXHDC hdc,
                                WXHWND hWnd,
                                WXUINT nCtlColor,
@@ -282,31 +312,28 @@ public:
                                WXWPARAM wParam,
                                WXLPARAM lParam);
 
-    virtual bool MSWOnPaletteChanged(WXHWND hWndPalChange);
-    virtual bool MSWOnQueryNewPalette();
+    bool HandlePaletteChanged(WXHWND hWndPalChange);
+    bool HandleQueryNewPalette();
+    bool HandleSysColorChange();
 
-    virtual bool MSWOnQueryEndSession(long logOff, bool *mayEnd);
-    virtual bool MSWOnEndSession(bool endSession, long logOff);
+    bool HandleQueryEndSession(long logOff, bool *mayEnd);
+    bool HandleEndSession(bool endSession, long logOff);
 
-    virtual bool MSWOnDestroy();
-    virtual bool MSWOnSetFocus(WXHWND wnd);
-    virtual bool MSWOnKillFocus(WXHWND wnd);
-    virtual bool MSWOnDropFiles(WXWPARAM wParam);
-    virtual bool MSWOnInitDialog(WXHWND hWndFocus);
-    virtual bool MSWOnShow(bool show, int status);
+    bool HandleSetFocus(WXHWND wnd);
+    bool HandleKillFocus(WXHWND wnd);
 
-    virtual bool MSWOnMouseEvent(WXUINT msg, int x, int y, WXUINT flags);
-    virtual bool MSWOnMouseMove(int x, int y, WXUINT flags);
+    bool HandleDropFiles(WXWPARAM wParam);
 
-    virtual bool MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII = FALSE);
-    virtual bool MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam);
-    virtual bool MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam);
+    bool HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags);
+    bool HandleMouseMove(int x, int y, WXUINT flags);
 
-    virtual bool MSWOnActivate(int flag, bool minimized, WXHWND activate);
-    virtual bool MSWOnMDIActivate(long flag, WXHWND activate, WXHWND deactivate);
+    bool HandleChar(WXWORD wParam, WXLPARAM lParam, bool isASCII = FALSE);
+    bool HandleKeyDown(WXWORD wParam, WXLPARAM lParam);
+    bool HandleKeyUp(WXWORD wParam, WXLPARAM lParam);
 
-    virtual bool MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *item);
-    virtual bool MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *item);
+    bool HandleQueryDragIcon(WXHICON *hIcon);
+
+    bool HandleSetCursor(WXHWND hWnd, short nHitTest, int mouseMsg);
 
     // Window procedure
     virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
index 220d689e8c6281747462a7bcbd991a323266cc53..d064760b5f2e964c135e41ffc58b078888a7caab 100644 (file)
@@ -73,7 +73,9 @@ BEGIN
     POPUP "&Window"
     BEGIN
         MENUITEM "&Cascade",                    4002
-        MENUITEM "&Tile",                       4001
+        MENUITEM "Tile &Horizontally",          4001
+        MENUITEM "Tile &Vertically",            4005
+       MENUITEM "", -1
         MENUITEM "&Arrange Icons",              4003
         MENUITEM "&Next",                       4004
     END
index 78829524a6d1d302e91b32fca4082b76f1226c81..99f192fc7e46b65e62cb19b46e5d8a86a2541f05 100644 (file)
@@ -156,7 +156,8 @@ public:
 
         // label is just the same as the title (but for, e.g., buttons it
         // makes more sense to speak about labels)
-    virtual wxString GetLabel() const { return GetTitle(); }
+    void SetLabel(const wxString& label) { SetTitle(label); }
+    wxString GetLabel() const { return GetTitle(); }
 
         // the window name is used for ressource setting in X, it is not the
         // same as the window title/label
index 34cb92fcf7977579d809c43654dce2c75e27023c..0c2e5f813cc0188c93e3ead20afe52f33fe2374f 100644 (file)
@@ -60,6 +60,8 @@
     IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent, wxCommandEvent)
     IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent, wxEvent)
     IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent, wxEvent)
+    IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent, wxEvent)
+    IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent, wxEvent)
 
     const wxEventTable *wxEvtHandler::GetEventTable() const
         { return &wxEvtHandler::sm_eventTable; }
@@ -91,7 +93,6 @@ wxEvent::wxEvent(int theId)
 {
     m_eventType = wxEVT_NULL;
     m_eventObject = (wxObject *) NULL;
-    m_eventHandle = (char *) NULL;
     m_timeStamp = 0;
     m_id = theId;
     m_skipped = FALSE;
@@ -106,7 +107,6 @@ void wxEvent::CopyObject(wxObject& object_dest) const
 
     obj->m_eventType = m_eventType;
     obj->m_eventObject = m_eventObject;
-    obj->m_eventHandle = m_eventHandle;
     obj->m_timeStamp = m_timeStamp;
     obj->m_id = m_id;
     obj->m_skipped = m_skipped;
@@ -467,6 +467,18 @@ void wxQueryNewPaletteEvent::CopyObject(wxObject& obj_d) const
     obj->m_paletteRealized = m_paletteRealized;
 }
 
+wxWindowCreateEvent::wxWindowCreateEvent(wxWindow *win)
+                   : wxEvent(wxEVT_CREATE)
+{
+    SetEventObject(win);
+}
+
+wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow *win)
+                    : wxEvent(wxEVT_DESTROY)
+{
+    SetEventObject(win);
+}
+
 /*
  * Event handler
  */
index 19d24912824e64e26bb80fe9ee6bc8eac16a3cc7..234252ff00420bab58ade5d61078cab0217725db 100644 (file)
@@ -57,7 +57,7 @@
 // static data
 // ----------------------------------------------------------------------------
 
-int wxWindowBase::ms_lastControlId = -2;
+int wxWindowBase::ms_lastControlId = -200;
 
 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
 
@@ -309,6 +309,14 @@ void wxWindowBase::Fit()
     while ( node )
     {
         wxWindow *win = node->GetData();
+        if ( win->IsKindOf(CLASSINFO(wxFrame)) ||
+             win->IsKindOf(CLASSINFO(wxDialog)) )
+        {
+            // dialogs and frames line in different top level windows - don't
+            // deal with them here
+            continue;
+        }
+
         int wx, wy, ww, wh;
         win->GetPosition(&wx, &wy);
         win->GetSize(&ww, &wh);
index f535bf2b6e9e4772c02d7df62e1671bd5b7afeed..69ddce49e00d97d80ba5fa424509495b2d528db2 100644 (file)
@@ -24,7 +24,6 @@
     #include "wx/wx.h"
 #endif
 
-#include <math.h>
 #include <stdlib.h>
 
 #include "wx/string.h"
 
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxSplitterWindow, wxWindow)
+IMPLEMENT_DYNAMIC_CLASS(wxSplitterEvent, wxCommandEvent)
 
 BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
     EVT_PAINT(wxSplitterWindow::OnPaint)
     EVT_SIZE(wxSplitterWindow::OnSize)
     EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent)
+
+    EVT_SPLITTER_SASH_POS_CHANGED(-1, wxSplitterWindow::OnSashPosChanged)
+    EVT_SPLITTER_DCLICK(-1,           wxSplitterWindow::OnDoubleClick)
+    EVT_SPLITTER_UNSPLIT(-1,          wxSplitterWindow::OnUnsplitEvent)
 END_EVENT_TABLE()
 #endif
 
@@ -195,8 +199,18 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
         int new_sash_position =
             (int) ( m_splitMode == wxSPLIT_VERTICAL ? x : y );
 
-        if ( !OnSashPositionChange(new_sash_position) )
-            return;
+        wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED,
+                                      this);
+        eventSplitter.m_data.pos = new_sash_position;
+        if ( GetEventHandler()->ProcessEvent(eventSplitter) )
+        {
+            new_sash_position = eventSplitter.GetSashPosition();
+            if ( new_sash_position == -1 )
+            {
+                // change not allowed
+                return;
+            }
+        }
 
         if ( new_sash_position == 0 )
         {
@@ -204,7 +218,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
             wxWindow *removedWindow = m_windowOne;
             m_windowOne = m_windowTwo;
             m_windowTwo = (wxWindow *) NULL;
-            OnUnsplit(removedWindow);
+            SendUnsplitEvent(removedWindow);
             m_sashPosition = 0;
         }
         else if ( new_sash_position == window_size )
@@ -212,13 +226,14 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
             // We remove the second window from the view
             wxWindow *removedWindow = m_windowTwo;
             m_windowTwo = (wxWindow *) NULL;
-            OnUnsplit(removedWindow);
+            SendUnsplitEvent(removedWindow);
             m_sashPosition = 0;
         }
         else
         {
             m_sashPosition = new_sash_position;
         }
+
         SizeWindows();
     }  // left up && dragging
     else if (event.Moving() && !event.Dragging())
@@ -237,11 +252,11 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
         }
 #ifdef __WXGTK__
         else
-       {
-           // where else do we unset the cursor?
+        {
+            // where else do we unset the cursor?
             SetCursor(* wxSTANDARD_CURSOR);
-       }
-#endif
+        }
+#endif // __WXGTK__
     }
     else if (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) 
     {
@@ -256,7 +271,12 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
     }
     else if ( event.LeftDClick() )
     {
-        OnDoubleClickSash(x, y);
+        wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_DOUBLECLICKED,
+                                      this);
+        eventSplitter.m_data.pt.x = x;
+        eventSplitter.m_data.pt.y = y;
+
+        (void)GetEventHandler()->ProcessEvent(eventSplitter);
     }
 }
 
@@ -614,7 +634,7 @@ bool wxSplitterWindow::Unsplit(wxWindow *toRemove)
         return FALSE;
     }
 
-    OnUnsplit(win);
+    SendUnsplitEvent(win);
     m_sashPosition = 0;
     SizeWindows();
 
@@ -657,56 +677,6 @@ void wxSplitterWindow::SetSashPosition(int position, bool redraw)
     }
 }
 
-bool wxSplitterWindow::OnSashPositionChange(int& newSashPosition)
-{
-    // If within UNSPLIT_THRESHOLD from edge, set to edge to cause closure.
-    const int UNSPLIT_THRESHOLD = 4;
-
-    if (newSashPosition <= UNSPLIT_THRESHOLD)   // threshold top / left check
-    {
-        newSashPosition = 0;
-        return TRUE;
-    }
-
-    // Obtain relevant window dimension for bottom / right threshold check
-    int w, h;
-    GetClientSize(&w, &h);
-    int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h ;
-
-    if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD )
-    {
-        newSashPosition = window_size;
-        return TRUE;
-    }
-
-    // If resultant pane would be too small, enlarge it.
-
-    // Check upper / left pane
-    if ( newSashPosition < m_minimumPaneSize )
-        newSashPosition = m_minimumPaneSize;   // NB: don't return just yet
-
-    // Check lower / right pane (check even if sash was just adjusted)
-    if ( newSashPosition > window_size - m_minimumPaneSize )
-        newSashPosition = window_size - m_minimumPaneSize;
-
-    // If the result is out of bounds it means minimum size is too big, so
-    // split window in half as best compromise.
-    if (newSashPosition < 0 || newSashPosition > window_size)
-        newSashPosition = window_size / 2;
-    return TRUE;
-}
-
-// Called when the sash is double-clicked.
-// The default behaviour is to remove the sash if the
-// minimum pane size is zero.
-void wxSplitterWindow::OnDoubleClickSash(int WXUNUSED(x), int WXUNUSED(y) )
-{
-    if ( GetMinimumPaneSize() == 0 )
-    {
-        Unsplit();
-    }
-}
-
 // Initialize colours
 void wxSplitterWindow::InitColours()
 {
@@ -744,3 +714,84 @@ void wxSplitterWindow::InitColours()
 #endif // Win32/!Win32
 }
 
+void wxSplitterWindow::SendUnsplitEvent(wxWindow *winRemoved)
+{
+    wxSplitterEvent event(wxEVT_COMMAND_SPLITTER_UNSPLIT, this);
+    event.m_data.win = winRemoved;
+
+    (void)GetEventHandler()->ProcessEvent(event);
+}
+
+// ---------------------------------------------------------------------------
+// splitter event handlers
+// ---------------------------------------------------------------------------
+
+void wxSplitterWindow::OnSashPosChanged(wxSplitterEvent& event)
+{
+    // If within UNSPLIT_THRESHOLD from edge, set to edge to cause closure.
+    const int UNSPLIT_THRESHOLD = 4;
+
+    int newSashPosition = event.GetSashPosition();
+
+    // Obtain relevant window dimension for bottom / right threshold check
+    int w, h;
+    GetClientSize(&w, &h);
+    int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h ;
+
+    if ( newSashPosition <= UNSPLIT_THRESHOLD )
+    {
+        // threshold top / left check
+        newSashPosition = 0;
+    }
+    else if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD )
+    {
+        // threshold bottom/right check
+        newSashPosition = window_size;
+    }
+
+    // If resultant pane would be too small, enlarge it.
+
+    // Check upper / left pane
+    if ( newSashPosition < m_minimumPaneSize )
+        newSashPosition = m_minimumPaneSize;
+
+    // Check lower / right pane (check even if sash was just adjusted)
+    if ( newSashPosition > window_size - m_minimumPaneSize )
+        newSashPosition = window_size - m_minimumPaneSize;
+
+    // If the result is out of bounds it means minimum size is too big,
+    // so split window in half as best compromise.
+    if ( newSashPosition < 0 || newSashPosition > window_size )
+        newSashPosition = window_size / 2;
+
+    // for compatibility, call the virtual function
+    if ( !OnSashPositionChange(newSashPosition) )
+    {
+        newSashPosition = -1;
+    }
+
+    event.SetSashPosition(newSashPosition);
+}
+
+// Called when the sash is double-clicked. The default behaviour is to remove
+// the sash if the minimum pane size is zero.
+void wxSplitterWindow::OnDoubleClick(wxSplitterEvent& event)
+{
+    // for compatibility, call the virtual function
+    OnDoubleClickSash(event.GetX(), event.GetY());
+
+    if ( GetMinimumPaneSize() == 0 )
+    {
+        Unsplit();
+    }
+}
+
+void wxSplitterWindow::OnUnsplitEvent(wxSplitterEvent& event)
+{
+    wxWindow *win = event.GetWindowBeingRemoved();
+
+    // for compatibility, call the virtual function
+    OnUnsplit(win);
+
+    win->Show(FALSE);
+}
index 06aef88b6068485f89ca751c79994ac08b1beed7..ea4c2d1f20f63716e75a5ddaa84577693180a617 100644 (file)
 
 #include "wx/msw/private.h"
 
-#ifdef LoadAccelerators
-#undef LoadAccelerators
-#endif
-
 #if !USE_SHARED_LIBRARIES
 IMPLEMENT_DYNAMIC_CLASS(wxAcceleratorTable, wxObject)
 #endif
index ac660f8e3f1603a5bcc67677ac8eb2360fcaba2b..33f10ba51a1c269146653578c519ed60db20f54b 100644 (file)
@@ -100,7 +100,7 @@ extern void wxSetKeyboardHook(bool doIt);
 extern wxCursor *g_globalCursor;
 
 HINSTANCE wxhInstance = 0;
-static MSG s_currentMsg;
+MSG s_currentMsg;
 wxApp *wxTheApp = NULL;
 
 // FIXME why not const? and not static?
@@ -150,8 +150,6 @@ LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
     END_EVENT_TABLE()
 #endif
 
-long wxApp::sm_lastMessageTime = 0;
-
 //// Initialize
 bool wxApp::Initialize()
 {
@@ -169,7 +167,8 @@ bool wxApp::Initialize()
     wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
 #endif
 
-    // I'm annoyed ... I don't know where to put this and I don't want to create    // a module for that as it's part of the core.
+    // I'm annoyed ... I don't know where to put this and I don't want to
+    // create a module for that as it's part of the core.
 #if wxUSE_THREADS
     wxPendingEvents = new wxList();
     wxPendingEventsLocker = new wxCriticalSection();
@@ -205,18 +204,6 @@ bool wxApp::Initialize()
     int iMsg = 96;
     while (!SetMessageQueue(iMsg) && (iMsg -= 8));
 
-    /*
-       DWORD dwOleVer;
-       dwOleVer = CoBuildVersion();
-
-    // check the OLE library version
-    if (rmm != HIWORD(dwOleVer))
-    {
-    wxMessageBox("Incorrect version of OLE libraries.");
-    return FALSE;
-    }
-     */
-
 #if wxUSE_OLE
     // we need to initialize OLE library
     if ( FAILED(::OleInitialize(NULL)) )
@@ -244,11 +231,11 @@ bool wxApp::Initialize()
 
     // Create the brush for disabling bitmap buttons
 
-    LOGBRUSH lb ;
+    LOGBRUSH lb;
     lb.lbStyle = BS_PATTERN;
-    lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" ) ;
-    wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ;
-    ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ;
+    lb.lbHatch = (int)LoadBitmap( wxhInstance, "wxDISABLE_BUTTON_BITMAP" );
+    wxDisableButtonBrush = ::CreateBrushIndirect( & lb );
+    ::DeleteObject( (HGDIOBJ)lb.lbHatch );
 
 #if wxUSE_PENWINDOWS
     wxRegisterPenWin();
@@ -271,131 +258,88 @@ bool wxApp::Initialize()
     return TRUE;
 }
 
-//// RegisterWindowClasses
+// ---------------------------------------------------------------------------
+// RegisterWindowClasses
+// ---------------------------------------------------------------------------
 
 bool wxApp::RegisterWindowClasses()
 {
-    ///////////////////////////////////////////////////////////////////////
-    // Register the frame window class.
-    WNDCLASS wndclass;   // Structure used to register Windows class.
+    WNDCLASS wndclass;
 
-    wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
+    // the fields which are common to all classes
+    wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     wndclass.lpfnWndProc   = (WNDPROC)wxWndProc;
     wndclass.cbClsExtra    = 0;
-    wndclass.cbWndExtra    = sizeof( DWORD ); // was 4
+    wndclass.cbWndExtra    = sizeof( DWORD ); // what is this DWORD used for?
     wndclass.hInstance     = wxhInstance;
-    wndclass.hIcon         = (HICON) NULL;        // wxSTD_FRAME_ICON;
-    wndclass.hCursor       = LoadCursor( (HINSTANCE) NULL, IDC_ARROW );
-    wndclass.hbrBackground =  (HBRUSH)(COLOR_APPWORKSPACE+1) ;
-    //  wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
+    wndclass.hIcon         = (HICON) NULL;
+    wndclass.hCursor       = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
     wndclass.lpszMenuName  = NULL;
+
+    // Register the frame window class.
+    wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
 #ifdef _MULTIPLE_INSTANCES
     sprintf( wxFrameClassName,"wxFrameClass%d", wxhInstance );
 #endif
     wndclass.lpszClassName = wxFrameClassName;
 
-    if (!RegisterClass( &wndclass ))
+    if ( !RegisterClass(&wndclass) )
     {
-        // wxFatalError("Can't register Frame Window class");
+        wxLogLastError("RegisterClass(frame)");
+
+        return FALSE;
     }
 
-    ///////////////////////////////////////////////////////////////////////
     // Register the MDI frame window class.
-    WNDCLASS wndclass1;   // Structure used to register Windows class.
-
-    wndclass1.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
-    wndclass1.lpfnWndProc   = (WNDPROC)wxWndProc;
-    wndclass1.cbClsExtra    = 0;
-    wndclass1.cbWndExtra    = sizeof( DWORD ); // was 4
-    wndclass1.hInstance     = wxhInstance;
-    wndclass1.hIcon         = (HICON) NULL; // wxSTD_MDIPARENTFRAME_ICON;
-    wndclass1.hCursor       = LoadCursor( (HINSTANCE) NULL, IDC_ARROW );
-    //  wndclass1.hbrBackground =  (HBRUSH)(COLOR_APPWORKSPACE+1) ;
-    wndclass1.hbrBackground = (HBRUSH) NULL;
-    wndclass1.lpszMenuName  = NULL;
-
-    wndclass1.lpszClassName = wxMDIFrameClassName;
-    if (!RegisterClass( &wndclass1 ))
+    wndclass.hbrBackground = (HBRUSH)NULL; // paint MDI frame ourselves
+    wndclass.lpszClassName = wxMDIFrameClassName;
+
+    if ( !RegisterClass(&wndclass) )
     {
-        //    wxFatalError("Can't register MDI Frame window class");
-        //  return FALSE;
+        wxLogLastError("RegisterClass(MDI parent)");
+
+        return FALSE;
     }
 
-    ///////////////////////////////////////////////////////////////////////
     // Register the MDI child frame window class.
-    WNDCLASS wndclass4;   // Structure used to register Windows class.
-
-    wndclass4.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
-    wndclass4.lpfnWndProc   = (WNDPROC)wxWndProc;
-    wndclass4.cbClsExtra    = 0;
-    wndclass4.cbWndExtra    = sizeof( DWORD ); // was 4
-    wndclass4.hInstance     = wxhInstance;
-    wndclass4.hIcon         = (HICON) NULL;       // wxSTD_MDICHILDFRAME_ICON;
-    wndclass4.hCursor       = LoadCursor( (HINSTANCE) NULL, IDC_ARROW );
-    // TODO: perhaps this should be NULL so that Windows doesn't
-    // paint the background itself (would OnEraseBackground duplicate
-    // this?)
-    wndclass4.hbrBackground =  (HBRUSH)(COLOR_WINDOW+1) ;
-    //  wndclass4.hbrBackground = NULL;
-    wndclass4.lpszMenuName  = NULL;
-    wndclass4.lpszClassName = wxMDIChildFrameClassName;
-
-    if (!RegisterClass( &wndclass4 ))
+    wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    wndclass.lpszClassName = wxMDIChildFrameClassName;
+
+    if ( !RegisterClass(&wndclass) )
     {
-        //   wxFatalError("Can't register MDI child frame window class");
-        //   return FALSE;
+        wxLogLastError("RegisterClass(MDI child)");
+
+        return FALSE;
     }
 
-    ///////////////////////////////////////////////////////////////////////
     // Register the panel window class.
-    WNDCLASS wndclass2;   // Structure used to register Windows class.
-    memset(&wndclass2, 0, sizeof(WNDCLASS));   // start with NULL defaults
-    wndclass2.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
-    wndclass2.lpfnWndProc   = (WNDPROC)wxWndProc;
-    wndclass2.cbClsExtra    = 0;
-    wndclass2.cbWndExtra    = sizeof( DWORD ); // was 4
-    wndclass2.hInstance     = wxhInstance;
-    wndclass2.hIcon         = (HICON) NULL;
-    wndclass2.hCursor       = LoadCursor( (HINSTANCE) NULL, IDC_ARROW );
-    //  wndclass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1) ;
-    wndclass2.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH );
-    wndclass2.lpszMenuName  = NULL;
-    wndclass2.lpszClassName = wxPanelClassName;
-    if (!RegisterClass( &wndclass2 ))
+    wndclass.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH );
+    wndclass.lpszClassName = wxPanelClassName;
+
+    if ( !RegisterClass(&wndclass) )
     {
-        //   wxFatalError("Can't register Panel Window class");
-        //   return FALSE;
+        wxLogLastError("RegisterClass(panel)");
+
+        return FALSE;
     }
 
-    ///////////////////////////////////////////////////////////////////////
     // Register the canvas and textsubwindow class name
-    WNDCLASS wndclass3;   // Structure used to register Windows class.
-    memset(&wndclass3, 0, sizeof(WNDCLASS));   // start with NULL defaults
-    // Use CS_OWNDC to avoid messing about restoring the context
-    // for every graphic operation.
-    //  wndclass3.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS ;
-    // wxWin 2.0
-    wndclass3.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
-    wndclass3.lpfnWndProc   = (WNDPROC)wxWndProc;
-    wndclass3.cbClsExtra    = 0;
-    wndclass3.cbWndExtra    = sizeof( DWORD ); // was 4
-    wndclass3.hInstance     = wxhInstance;
-    wndclass3.hIcon         = (HICON) NULL;
-    wndclass3.hCursor       = LoadCursor( (HINSTANCE) NULL, IDC_ARROW );
-    //  wndclass3.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ;
-    wndclass3.hbrBackground = (HBRUSH) NULL;
-    wndclass3.lpszMenuName  = NULL;
-    wndclass3.lpszClassName = wxCanvasClassName;
-    if (!RegisterClass( &wndclass3))
+    wndclass.hbrBackground = (HBRUSH)NULL;
+    wndclass.lpszClassName = wxCanvasClassName;
+
+    if ( !RegisterClass(&wndclass) )
     {
-        //   wxFatalError("Can't register Canvas class");
-        //   return FALSE;
+        wxLogLastError("RegisterClass(canvas)");
+
+        return FALSE;
     }
 
     return TRUE;
 }
 
-//// Convert Windows to argc, argv style
+// ---------------------------------------------------------------------------
+// Convert Windows to argc, argv style
+// ---------------------------------------------------------------------------
 
 void wxApp::ConvertToStandardCommandArgs(char* lpCmdLine)
 {
@@ -499,7 +443,7 @@ void wxApp::CleanUp()
     delete g_globalCursor;
     g_globalCursor = NULL;
 
-    wxDeleteStockObjects() ;
+    wxDeleteStockObjects();
 
     // Destroy all GDI lists, etc.
     wxDeleteStockLists();
@@ -544,7 +488,7 @@ void wxApp::CleanUp()
         DestroyIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
 
     if ( wxDisableButtonBrush )
-        ::DeleteObject( wxDisableButtonBrush ) ;
+        ::DeleteObject( wxDisableButtonBrush );
 
 #if wxUSE_OLE
     ::OleUninitialize();
@@ -555,7 +499,7 @@ void wxApp::CleanUp()
 #endif
 
     if (wxWinHandleList)
-        delete wxWinHandleList ;
+        delete wxWinHandleList;
 
     // GL: I'm annoyed ... I don't know where to put this and I don't want to 
     // create a module for that as it's part of the core.
@@ -646,7 +590,7 @@ int wxEntry(WXHINSTANCE hInstance,
 
         // GUI-specific initialisation. In fact on Windows we don't have any,
         // but this call is provided for compatibility across platforms.
-        wxTheApp->OnInitGui() ;
+        wxTheApp->OnInitGui();
 
         int retValue = 0;
 
@@ -759,16 +703,11 @@ wxApp::wxApp()
 {
     m_topWindow = NULL;
     wxTheApp = this;
-    m_className = "";
-    m_wantDebugOutput = TRUE ;
-    m_appName = "";
+    m_wantDebugOutput = TRUE;
+
     argc = 0;
     argv = NULL;
-#ifdef __WXMSW__
     m_printMode = wxPRINT_WINDOWS;
-#else
-    m_printMode = wxPRINT_POSTSCRIPT;
-#endif
     m_exitOnFrameDelete = TRUE;
     m_auto3D = TRUE;
 }
@@ -875,7 +814,6 @@ bool wxApp::DoMessage()
         if ( !ProcessMessage((WXMSG *)&s_currentMsg) )
         {
             ::TranslateMessage(&s_currentMsg);
-            wxApp::sm_lastMessageTime = s_currentMsg.time; /* MATTHEW: timeStamp impl. */
             ::DispatchMessage(&s_currentMsg);
         }
     }
@@ -955,7 +893,7 @@ void wxApp::ExitMainLoop()
 
 bool wxApp::Pending()
 {
-    return (::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0) ;
+    return (::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0);
 }
 
 void wxApp::Dispatch()
@@ -1064,7 +1002,7 @@ bool wxApp::SendIdleEvents(wxWindow* win)
 
         node = node->Next();
     }
-    return needMore ;
+    return needMore;
 }
 
 void wxApp::DeletePendingObjects()
index 6af2e7c60d888734f573b26d109ce0183b0d6459..9404785a6ffacac316aee628c4e97c729bb1f1b4 100644 (file)
@@ -72,20 +72,25 @@ bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bit
   if ( height == -1 && bitmap.Ok())
     height = bitmap.GetHeight() + 2*m_marginY;
 
-  HWND wx_button =
-    CreateWindowEx(0, "BUTTON", "", BS_OWNERDRAW | WS_TABSTOP | WS_CHILD,
-                    0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId,
-                    wxGetInstance(), NULL);
-
-  m_hWnd = (WXHWND)wx_button;
+  m_hWnd = (WXHWND)CreateWindowEx
+                   (
+                    0,
+                    "BUTTON",
+                    "",
+                    WS_VISIBLE | WS_TABSTOP | WS_CHILD | BS_OWNERDRAW ,
+                    0, 0, 0, 0, 
+                    GetWinHwnd(parent),
+                    (HMENU)m_windowId,
+                    wxGetInstance(),
+                    NULL
+                   );
 
   // Subclass again for purposes of dialog editing mode
-  SubclassWin((WXHWND)wx_button);
+  SubclassWin(m_hWnd);
 
   SetFont(parent->GetFont()) ;
 
   SetSize(x, y, width, height);
-  ShowWindow(wx_button, SW_SHOW);
 
   return TRUE;
 }
@@ -101,9 +106,6 @@ bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item)
     long style = GetWindowLong((HWND) GetHWND(), GWL_STYLE);
     if (style & BS_BITMAP)
     {
-        // Should we call Default() here?
-//      Default();
-
         // Let default procedure draw the bitmap, which is defined
         // in the Windows resource.
         return FALSE;
@@ -114,33 +116,33 @@ bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item)
 
     wxBitmap* bitmap = &m_buttonBitmap;
 
-       UINT state = lpDIS->itemState;
-       if ((state & ODS_SELECTED) && m_buttonBitmapSelected.Ok())
-               bitmap = &m_buttonBitmapSelected;
-       else if ((state & ODS_FOCUS) && m_buttonBitmapFocus.Ok())
-               bitmap = &m_buttonBitmapFocus;
-       else if ((state & ODS_DISABLED) && m_buttonBitmapDisabled.Ok())
-               bitmap = &m_buttonBitmapDisabled;
+    UINT state = lpDIS->itemState;
+    if ((state & ODS_SELECTED) && m_buttonBitmapSelected.Ok())
+        bitmap = &m_buttonBitmapSelected;
+    else if ((state & ODS_FOCUS) && m_buttonBitmapFocus.Ok())
+        bitmap = &m_buttonBitmapFocus;
+    else if ((state & ODS_DISABLED) && m_buttonBitmapDisabled.Ok())
+        bitmap = &m_buttonBitmapDisabled;
 
-       if ( !bitmap->Ok() )
-               return FALSE;
+    if ( !bitmap->Ok() )
+        return FALSE;
 
-       HDC hDC = lpDIS->hDC;
-       HDC memDC = ::CreateCompatibleDC(hDC);
+    HDC hDC = lpDIS->hDC;
+    HDC memDC = ::CreateCompatibleDC(hDC);
 
-       HBITMAP old = (HBITMAP) ::SelectObject(memDC, (HBITMAP) bitmap->GetHBITMAP());
+    HBITMAP old = (HBITMAP) ::SelectObject(memDC, (HBITMAP) bitmap->GetHBITMAP());
 
-       if (!old)
-               return FALSE;
+    if (!old)
+        return FALSE;
 
-       int x = lpDIS->rcItem.left;
-       int y = lpDIS->rcItem.top;
-       int width = lpDIS->rcItem.right - x;
-       int height = lpDIS->rcItem.bottom - y;
+    int x = lpDIS->rcItem.left;
+    int y = lpDIS->rcItem.top;
+    int width = lpDIS->rcItem.right - x;
+    int height = lpDIS->rcItem.bottom - y;
 
-       // Draw the face, if auto-drawing
-       if ( GetWindowStyleFlag() & wxBU_AUTODRAW )
-               DrawFace((WXHDC) hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right, lpDIS->rcItem.bottom,
+    // Draw the face, if auto-drawing
+    if ( GetWindowStyleFlag() & wxBU_AUTODRAW )
+        DrawFace((WXHDC) hDC, lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right, lpDIS->rcItem.bottom,
             ((state & ODS_SELECTED) == ODS_SELECTED));
 
     // Centre the bitmap in the control area
index 764c28db6f071628331ab2cf4bbdf7b88a8553c6..80e8318503d2d20d5de7f5a63a8b85a6b4238495 100644 (file)
@@ -72,21 +72,25 @@ bool wxButton::Create(wxWindow *parent, wxWindowID id, const wxString& label,
   else
     m_windowId = id;
 
-  DWORD exStyle = MakeExtendedStyle(m_windowStyle);
-  HWND wx_button =
-    CreateWindowEx(exStyle, "BUTTON", label, BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD,
-                    0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId,
-                    wxGetInstance(), NULL);
-
-  m_hWnd = (WXHWND)wx_button;
+  m_hWnd = (WXHWND)CreateWindowEx
+                   (
+                    MakeExtendedStyle(m_windowStyle),
+                    "BUTTON",
+                    label,
+                    WS_VISIBLE | WS_TABSTOP | WS_CHILD,
+                    0, 0, 0, 0, 
+                    GetWinHwnd(parent),
+                    (HMENU)m_windowId,
+                    wxGetInstance(),
+                    NULL
+                   );
 
   // Subclass again for purposes of dialog editing mode
-  SubclassWin((WXHWND)wx_button);
+  SubclassWin(m_hWnd);
 
   SetFont(parent->GetFont());
 
   SetSize(x, y, width, height);
-  ShowWindow(wx_button, SW_SHOW);
 
   return TRUE;
 }
index 5074a31255fe935c00f3557b316fcb87586b2598..cf0aec140ebdc5638817d3bee0f0fe7d7d188542 100644 (file)
@@ -313,7 +313,7 @@ long wxChoice::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
        // with x = 65535 and y = 65535.
        // Filter out this nonsense.
        if (x == 65535 && y == 65535)
-         return Default();
+         return 0;
        break;
       }
     }
index 542d3d7b080fd85303118532961d67d48b3a4687..6788e0ceb7385381535f08bc84d97ae8ea5fab22 100644 (file)
 #include <commctrl.h>
 #endif
 
-#ifdef GetCharWidth
-#undef GetCharWidth
-#undef GetWindowProc
-#endif
-
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
 
@@ -48,75 +43,43 @@ END_EVENT_TABLE()
 #endif
 
 // Item members
-wxControl::wxControl(void)
+wxControl::wxControl()
 {
   m_backgroundColour = *wxWHITE;
   m_foregroundColour = *wxBLACK;
+
+#if WXWIN_COMPATIBILITY
   m_callback = 0;
-//  m_windowCursor = wxNullCursor; // To avoid the standard cursor being used
+#endif // WXWIN_COMPATIBILITY
 }
 
-wxControl::~wxControl(void)
+wxControl::~wxControl()
 {
-  m_isBeingDeleted = TRUE;
-
-  // If we delete an item, we should initialize the parent panel,
-  // because it could now be invalid.
-  wxWindow *parent = (wxWindow *)GetParent();
-  if (parent)
-  {
-    if (parent->GetDefaultItem() == (wxButton*) this)
-        parent->SetDefaultItem(NULL);
-  }
-}
+    m_isBeingDeleted = TRUE;
 
-void wxControl::SetLabel(const wxString& label)
-{
-  if (GetHWND())
-    SetWindowText((HWND) GetHWND(), (const char *)label);
-}
-
-wxString wxControl::GetLabel(void) const
-{
-    wxBuffer[0] = 0;
-    if (GetHWND())
+    // If we delete an item, we should initialize the parent panel,
+    // because it could now be invalid.
+    wxWindow *parent = (wxWindow *)GetParent();
+    if (parent)
     {
-        int len = GetWindowText((HWND)GetHWND(), wxBuffer, 256);
-        wxBuffer[len] = 0;
+        if (parent->GetDefaultItem() == (wxButton*) this)
+            parent->SetDefaultItem(NULL);
     }
-
-  return wxString(wxBuffer);
 }
 
-// Call this repeatedly for several wnds to find the overall size
-// of the widget.
-// Call it initially with -1 for all values in rect.
-// Keep calling for other widgets, and rect will be modified
-// to calculate largest bounding rectangle.
-void wxFindMaxSize(WXHWND wnd, RECT *rect)
+bool wxControl::ProcessCommand(wxCommandEvent& event)
 {
-  int left = rect->left;
-  int right = rect->right;
-  int top = rect->top;
-  int bottom = rect->bottom;
-
-  GetWindowRect((HWND) wnd, rect);
-
-  if (left < 0)
-    return;
-
-  if (left < rect->left)
-    rect->left = left;
-
-  if (right > rect->right)
-    rect->right = right;
-
-  if (top < rect->top)
-    rect->top = top;
+#if WXWIN_COMPATIBILITY
+    if ( m_callback )
+    {
+        (void)(*m_callback)(this, event);
 
-  if (bottom > rect->bottom)
-    rect->bottom = bottom;
+        return TRUE;
+    }
+    else
+#endif // WXWIN_COMPATIBILITY
 
+    return GetEventHandler()->ProcessEvent(event);
 }
 
 #ifdef __WIN95__
@@ -168,70 +131,57 @@ bool wxControl::MSWOnNotify(int idCtrl,
 }
 #endif // Win95
 
-void wxControl::ProcessCommand (wxCommandEvent & event)
-{
-  // Tries:
-  // 1) A callback function (to become obsolete)
-  // 2) OnCommand, starting at this window and working up parent hierarchy
-  // 3) OnCommand then calls ProcessEvent to search the event tables.
-  if (m_callback)
-    {
-      (void) (*(m_callback)) (*this, event);
-    }
-    else
-    {
-      GetEventHandler()->OnCommand(*this, event);
-    }
-}
-
 void wxControl::OnEraseBackground(wxEraseEvent& event)
 {
-  // In general, you don't want to erase the background of a control,
-  // or you'll get a flicker.
-  // TODO: move this 'null' function into each control that
-  // might flicker.
-
-  RECT rect;
-  ::GetClientRect((HWND) GetHWND(), &rect);
-
-  HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
-  int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
-
-  ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush);
-  ::DeleteObject(hBrush);
-  ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
+    // In general, you don't want to erase the background of a control,
+    // or you'll get a flicker.
+    // TODO: move this 'null' function into each control that
+    // might flicker.
+
+    RECT rect;
+    ::GetClientRect((HWND) GetHWND(), &rect);
+
+    HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(),
+                                                  GetBackgroundColour().Green(),
+                                                  GetBackgroundColour().Blue()));
+    int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
+
+    ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush);
+    ::DeleteObject(hBrush);
+    ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
 }
 
-void wxControl::SetClientSize (int width, int height)
-{
-  SetSize (-1, -1, width, height);
-}
+// ---------------------------------------------------------------------------
+// global functions
+// ---------------------------------------------------------------------------
 
-void wxControl::Centre (int direction)
+// Call this repeatedly for several wnds to find the overall size
+// of the widget.
+// Call it initially with -1 for all values in rect.
+// Keep calling for other widgets, and rect will be modified
+// to calculate largest bounding rectangle.
+void wxFindMaxSize(WXHWND wnd, RECT *rect)
 {
-  int x, y, width, height, panel_width, panel_height, new_x, new_y;
+    int left = rect->left;
+    int right = rect->right;
+    int top = rect->top;
+    int bottom = rect->bottom;
 
-  wxWindow *parent = (wxWindow *) GetParent ();
-  if (!parent)
-    return;
+    GetWindowRect((HWND) wnd, rect);
 
-  parent->GetClientSize (&panel_width, &panel_height);
-  GetSize (&width, &height);
-  GetPosition (&x, &y);
+    if (left < 0)
+        return;
 
-  new_x = x;
-  new_y = y;
+    if (left < rect->left)
+        rect->left = left;
 
-  if (direction & wxHORIZONTAL)
-    new_x = (int) ((panel_width - width) / 2);
+    if (right > rect->right)
+        rect->right = right;
 
-  if (direction & wxVERTICAL)
-    new_y = (int) ((panel_height - height) / 2);
+    if (top < rect->top)
+        rect->top = top;
 
-  SetSize (new_x, new_y, width, height);
-  int temp_x, temp_y;
-  GetPosition (&temp_x, &temp_y);
-  GetPosition (&temp_x, &temp_y);
+    if (bottom > rect->bottom)
+        rect->bottom = bottom;
 }
 
-
index 450f97e1a3aa0293f83994cf07d3c326adb6bab4..dc3a9aa01807986a3222b3c5262d2c303f019581 100644 (file)
@@ -669,7 +669,6 @@ END_EVENT_TABLE()
 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
     EVT_CHAR(wxTextCtrl::OnChar)
     EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
-    EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground)
 END_EVENT_TABLE()
 
 #ifdef __WXMSW__
index 33423e3172232d21b22a124b9378f9fd78198bcc..ad8039c3263af9f2e82b86b714142ea8eddcb545 100644 (file)
     #include <print.h>
 #endif
 
-#ifdef DrawText
-    #undef DrawText
-#endif
-
-#ifdef GetCharWidth
-    #undef GetCharWidth
-#endif
-
-#ifdef StartDoc
-    #undef StartDoc
-#endif
-
 #if !USE_SHARED_LIBRARY
     IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
 #endif
 // constants
 // ---------------------------------------------------------------------------
 
-#define VIEWPORT_EXTENT 1000
+static const int VIEWPORT_EXTENT = 1000;
+
+static const int MM_POINTS = 9;
+static const int MM_METRIC = 10;
 
 // ---------------------------------------------------------------------------
 // macros
 // ---------------------------------------------------------------------------
 
+// Logical to device
+// Absolute
+#define XLOG2DEV(x) (x)
+#define YLOG2DEV(y) (y)
+
+// Relative
+#define XLOG2DEVREL(x) (x)
+#define YLOG2DEVREL(y) (y)
+
+// Device to logical
+// Absolute
+#define XDEV2LOG(x) (x)
+
+#define YDEV2LOG(y) (y)
+
+// Relative
+#define XDEV2LOGREL(x) (x)
+#define YDEV2LOGREL(y) (y)
+
+/*
+ * Have the same macros as for XView but not for every operation:
+ * just for calculating window/viewport extent (a better way of scaling).
+ */
+
+// Logical to device
+// Absolute
+#define MS_XLOG2DEV(x) LogicalToDevice(x)
+
+#define MS_YLOG2DEV(y) LogicalToDevice(y)
+
+// Relative
+#define MS_XLOG2DEVREL(x) LogicalToDeviceXRel(x)
+#define MS_YLOG2DEVREL(y) LogicalToDeviceYRel(y)
+
+// Device to logical
+// Absolute
+#define MS_XDEV2LOG(x) DeviceToLogicalX(x)
+
+#define MS_YDEV2LOG(y) DeviceToLogicalY(y)
+
+// Relative
+#define MS_XDEV2LOGREL(x) DeviceToLogicalXRel(x)
+#define MS_YDEV2LOGREL(y) DeviceToLogicalYRel(y)
+
 #define YSCALE(y) (yorigin - (y))
 
+#define     wx_round(a)    (int)((a)+.5)
+
 // ===========================================================================
 // implementation
 // ===========================================================================
index 96a461eaaf127b255045b6d5ed9f51fecafc886e..95fe393b286191d592ae3785e9cb4dc85d681d5c 100644 (file)
@@ -27,7 +27,7 @@
 #include "wx/log.h"
 #include "math.h"
 
-#include <windows.h>
+#include "wx/msw/private.h"
 
 #if wxUSE_COMMON_DIALOGS
 #include <commdlg.h>
 #include <print.h>
 #endif
 
-#ifdef DrawText
-#undef DrawText
-#endif
-
-#ifdef GetCharWidth
-#undef GetCharWidth
-#endif
-
-#ifdef StartDoc
-#undef StartDoc
-#endif
-
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_CLASS(wxPrinterDC, wxDC)
 #endif
index f58e8d96935b5662e246b695e57faa1d1abb3247..ec79f72f57f21f3197ea457afbc59a475532c5f6 100644 (file)
@@ -627,3 +627,27 @@ void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event)
   Refresh();
 #endif
 }
+
+// ---------------------------------------------------------------------------
+// dialog window proc
+// ---------------------------------------------------------------------------
+
+long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+{
+    long rc = 0;
+    bool processed = FALSE;
+
+    switch ( message )
+    {
+        case WM_CLOSE:
+            // if we can't close, tell the system that we processed the
+            // message - otherwise it would close us
+            processed = !Close();
+            break;
+    }
+
+    if ( !processed )
+        rc = wxWindow::MSWWindowProc(message, wParam, lParam);
+
+    return rc;
+}
index 459843e361b83331541874c9e6eda4db8f5a89bd..f5558c492d690d8e971f02fa0f4dd84dac37843b 100644 (file)
 #include "wx/menuitem.h"
 #include "wx/log.h"
 
-#ifdef LoadAccelerators
-#undef LoadAccelerators
-#endif
-
 #if wxUSE_NATIVE_STATUSBAR
     #include <wx/msw/statbr95.h>
 #endif
@@ -94,7 +90,6 @@ bool wxFrame::Create(wxWindow *parent,
     wxTopLevelWindows.Append(this);
 
   SetName(name);
-//  m_modalShowing = FALSE;
   m_windowStyle = style;
   m_frameMenuBar = NULL;
   m_frameToolBar = NULL ;
@@ -163,16 +158,11 @@ wxFrame::~wxFrame()
     ::BringWindowToTop((HWND) GetParent()->GetHWND());
 }
 
-WXHMENU wxFrame::GetWinMenu() const
-{
-  return m_hMenu;
-}
-
 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
 void wxFrame::DoGetClientSize(int *x, int *y) const
 {
   RECT rect;
-  ::GetClientRect((HWND) GetHWND(), &rect);
+  ::GetClientRect(GetHwnd(), &rect);
 
   if ( GetStatusBar() )
   {
@@ -193,7 +183,7 @@ void wxFrame::DoGetClientSize(int *x, int *y) const
 // to wxWindows)
 void wxFrame::DoSetClientSize(int width, int height)
 {
-  HWND hWnd = (HWND) GetHWND();
+  HWND hWnd = GetHwnd();
 
   RECT rect;
   ::GetClientRect(hWnd, &rect);
@@ -232,7 +222,7 @@ void wxFrame::DoSetClientSize(int width, int height)
 void wxFrame::DoGetSize(int *width, int *height) const
 {
   RECT rect;
-  GetWindowRect((HWND) GetHWND(), &rect);
+  GetWindowRect(GetHwnd(), &rect);
   *width = rect.right - rect.left;
   *height = rect.bottom - rect.top;
 }
@@ -240,7 +230,7 @@ void wxFrame::DoGetSize(int *width, int *height) const
 void wxFrame::DoGetPosition(int *x, int *y) const
 {
   RECT rect;
-  GetWindowRect((HWND) GetHWND(), &rect);
+  GetWindowRect(GetHwnd(), &rect);
   POINT point;
   point.x = rect.left;
   point.y = rect.top;
@@ -268,7 +258,7 @@ void wxFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags)
   if (width == -1) w1 = ww ;
   if (height==-1) h1 = hh ;
 
-  MoveWindow((HWND) GetHWND(), x1, y1, w1, h1, (BOOL)TRUE);
+  MoveWindow(GetHwnd(), x1, y1, w1, h1, (BOOL)TRUE);
 
   wxSizeEvent event(wxSize(width, height), m_windowId);
   event.SetEventObject( this );
@@ -295,10 +285,10 @@ bool wxFrame::Show(bool show)
     }
   }
 
-  ShowWindow((HWND) GetHWND(), (BOOL)cshow);
+  ShowWindow(GetHwnd(), (BOOL)cshow);
   if (show)
   {
-    BringWindowToTop((HWND) GetHWND());
+    BringWindowToTop(GetHwnd());
 
     wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId);
     event.SetEventObject( this );
@@ -317,7 +307,7 @@ void wxFrame::Iconize(bool iconize)
     cshow = SW_MINIMIZE;
   else
     cshow = SW_RESTORE;
-  ShowWindow((HWND) GetHWND(), (BOOL)cshow);
+  ShowWindow(GetHwnd(), (BOOL)cshow);
   m_iconized = iconize;
 }
 
@@ -330,31 +320,20 @@ void wxFrame::Maximize(bool maximize)
     cshow = SW_MAXIMIZE;
   else
     cshow = SW_RESTORE;
-  ShowWindow((HWND) GetHWND(), cshow);
+  ShowWindow(GetHwnd(), cshow);
   m_iconized = FALSE;
 }
 
 bool wxFrame::IsIconized() const
 {
-  ((wxFrame *)this)->m_iconized = (::IsIconic((HWND) GetHWND()) != 0);
+  ((wxFrame *)this)->m_iconized = (::IsIconic(GetHwnd()) != 0);
   return m_iconized;
 }
 
 // Is it maximized?
 bool wxFrame::IsMaximized() const
 {
-    return (::IsZoomed((HWND) GetHWND()) != 0) ;
-}
-
-void wxFrame::SetTitle(const wxString& title)
-{
-  SetWindowText((HWND) GetHWND(), (const char *)title);
-}
-
-wxString wxFrame::GetTitle() const
-{
-  GetWindowText((HWND) GetHWND(), wxBuffer, 1000);
-  return wxString(wxBuffer);
+    return (::IsZoomed(GetHwnd()) != 0) ;
 }
 
 void wxFrame::SetIcon(const wxIcon& icon)
@@ -362,7 +341,7 @@ void wxFrame::SetIcon(const wxIcon& icon)
   m_icon = icon;
 #if defined(__WIN95__)
   if ( m_icon.Ok() )
-    SendMessage((HWND) GetHWND(), WM_SETICON,
+    SendMessage(GetHwnd(), WM_SETICON,
                 (WPARAM)TRUE, (LPARAM)(HICON) m_icon.GetHICON());
 #endif
 }
@@ -470,64 +449,18 @@ void wxFrame::SetMenuBar(wxMenuBar *menu_bar)
     if ( !m_hMenu )
         return;
 
-    if ( !::SetMenu((HWND)GetHWND(), (HMENU)m_hMenu) )
-    {
-        wxLogLastError("SetMenu");
-    }
+    InternalSetMenuBar();
 
     m_frameMenuBar = menu_bar;
     menu_bar->Attach(this);
 }
 
-#if 0
-bool wxFrame::LoadAccelerators(const wxString& table)
-{
-  m_acceleratorTable = (WXHANDLE)
-#ifdef __WIN32__
-#ifdef UNICODE
-     ::LoadAcceleratorsW(wxGetInstance(), (const char *)table);
-#else
-     ::LoadAcceleratorsA(wxGetInstance(), (const char *)table);
-#endif
-#else
-     ::LoadAccelerators(wxGetInstance(), (const char *)table);
-#endif
-
-  // The above is necessary because LoadAccelerators is a macro
-  // which we have undefed earlier in the file to avoid confusion
-  // with wxFrame::LoadAccelerators. Ugh!
-
-  return (m_acceleratorTable != (WXHANDLE) NULL);
-}
-#endif
-
-void wxFrame::Fit()
+void wxFrame::InternalSetMenuBar()
 {
-  // Work out max. size
-  wxNode *node = GetChildren().First();
-  int max_width = 0;
-  int max_height = 0;
-  while (node)
-  {
-    // Find a child that's a subwindow, but not a dialog box.
-    wxWindow *win = (wxWindow *)node->Data();
-
-    if (!win->IsKindOf(CLASSINFO(wxFrame)) &&
-         !win->IsKindOf(CLASSINFO(wxDialog)))
+    if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) )
     {
-      int width, height;
-      int x, y;
-      win->GetSize(&width, &height);
-      win->GetPosition(&x, &y);
-
-      if ((x + width) > max_width)
-        max_width = x + width;
-      if ((y + height) > max_height)
-        max_height = y + height;
+        wxLogLastError("SetMenu");
     }
-    node = node->Next();
-  }
-  SetClientSize(max_width, max_height);
 }
 
 // Responds to colour changes, and passes event on to children.
@@ -618,162 +551,11 @@ bool wxFrame::MSWCreate(int id, wxWindow *parent, const char *wclass, wxWindow *
   // Seems to be necessary if we use WS_POPUP
   // style instead of WS_OVERLAPPED
   if (width > -1 && height > -1)
-    ::PostMessage((HWND) GetHWND(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
+    ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
 
   return TRUE;
 }
 
-bool wxFrame::MSWOnPaint()
-{
-  RECT rect;
-  if (GetUpdateRect((HWND) GetHWND(), &rect, FALSE))
-  {
-    if (m_iconized)
-    {
-      HICON the_icon;
-      if (m_icon.Ok())
-        the_icon = (HICON) m_icon.GetHICON();
-      else
-        the_icon = (HICON) m_defaultIcon;
-
-      PAINTSTRUCT ps;
-      // Hold a pointer to the dc so long as the OnPaint() message
-      // is being processed
-      HDC cdc = BeginPaint((HWND) GetHWND(), &ps);
-
-      // Erase background before painting or we get white background
-      this->MSWDefWindowProc(WM_ICONERASEBKGND,(WORD)(LONG) ps.hdc,0L);
-
-      if (the_icon)
-      {
-        RECT rect;
-        ::GetClientRect((HWND) GetHWND(), &rect);
-        int icon_width = 32;
-        int icon_height = 32;
-        int icon_x = (int)((rect.right - icon_width)/2);
-        int icon_y = (int)((rect.bottom - icon_height)/2);
-        DrawIcon(cdc, icon_x, icon_y, the_icon);
-      }
-
-      EndPaint((HWND) GetHWND(), &ps);
-    }
-    else
-    {
-        wxPaintEvent event(m_windowId);
-        event.m_eventObject = this;
-        if (!GetEventHandler()->ProcessEvent(event))
-            Default();
-    }
-    return 0;
-  }
-  return 1;
-}
-
-WXHICON wxFrame::MSWOnQueryDragIcon()
-{
-  if (m_icon.Ok() && (m_icon.GetHICON() != 0))
-    return m_icon.GetHICON();
-  else
-    return m_defaultIcon;
-}
-
-bool wxFrame::MSWOnSize(int x, int y, WXUINT id)
-{
-    bool processed = FALSE;
-
-    switch ( id )
-    {
-        case SIZENORMAL:
-            // only do it it if we were iconized before, otherwise resizing the
-            // parent frame has a curious side effect of bringing it under it's
-            // children
-            if ( !m_iconized )
-                break;
-
-            // restore all child frames too
-            IconizeChildFrames(FALSE);
-
-            // fall through
-
-        case SIZEFULLSCREEN:
-            m_iconized = FALSE;
-            break;
-
-        case SIZEICONIC:
-            // iconize all child frames too
-            IconizeChildFrames(TRUE);
-
-            m_iconized = TRUE;
-            break;
-    }
-
-    if ( !m_iconized )
-    {
-        // forward WM_SIZE to status bar control
-#if wxUSE_NATIVE_STATUSBAR
-        if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
-        {
-            wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
-            event.SetEventObject( m_frameStatusBar );
-
-            ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
-        }
-#endif // wxUSE_NATIVE_STATUSBAR
-
-        PositionStatusBar();
-        PositionToolBar();
-
-        wxSizeEvent event(wxSize(x, y), m_windowId);
-        event.SetEventObject( this );
-        processed = GetEventHandler()->ProcessEvent(event);
-    }
-
-    return processed;
-}
-
-bool wxFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
-{
-  if (cmd == 0 || cmd == 1 ) // Can be either a menu command or an accelerator.
-  {
-    // In case it's e.g. a toolbar.
-    wxWindow *win = wxFindWinFromHandle(control);
-    if (win)
-      return win->MSWCommand(cmd, id);
-
-    if (wxCurrentPopupMenu)
-    {
-        wxMenu *popupMenu = wxCurrentPopupMenu;
-        wxCurrentPopupMenu = NULL;
-        if (popupMenu->MSWCommand(cmd, id))
-            return TRUE;
-    }
-
-    if (GetMenuBar() && GetMenuBar()->FindItemForId(id))
-    {
-      ProcessCommand(id);
-      return TRUE;
-    }
-    else
-      return FALSE;
-  }
-  else
-    return wxWindow::MSWOnCommand(id, cmd, control);
-}
-
-bool wxFrame::MSWProcessMessage(WXMSG* pMsg)
-{
-  return FALSE;
-}
-
-bool wxFrame::MSWTranslateMessage(WXMSG* pMsg)
-{
-  if (m_acceleratorTable.Ok() &&
-          ::TranslateAccelerator((HWND) GetHWND(), (HACCEL) m_acceleratorTable.GetHACCEL(), (MSG *)pMsg))
-    return TRUE;
-
-  return FALSE;
-}
-
 // Default resizing behaviour - if only ONE subwindow, resize to client
 // rectangle size
 void wxFrame::OnSize(wxSizeEvent& event)
@@ -835,7 +617,7 @@ void wxFrame::OnActivate(wxActivateEvent& event)
 // The default implementation for the close window event.
 void wxFrame::OnCloseWindow(wxCloseEvent& event)
 {
-    this->Destroy();
+    Destroy();
 }
 
 // Destroy the window (delayed, if a managed window)
@@ -871,53 +653,26 @@ wxMenuBar *wxFrame::GetMenuBar() const
   return m_frameMenuBar;
 }
 
-void wxFrame::Centre(int direction)
-{
-  int display_width, display_height, width, height, x, y;
-  wxDisplaySize(&display_width, &display_height);
-
-  GetSize(&width, &height);
-  GetPosition(&x, &y);
-
-  if (direction & wxHORIZONTAL)
-    x = (int)((display_width - width)/2);
-  if (direction & wxVERTICAL)
-    y = (int)((display_height - height)/2);
-
-  SetSize(x, y, width, height);
-}
-
-// Call this to simulate a menu command
-void wxFrame::Command(int id)
+bool wxFrame::ProcessCommand(int id)
 {
-  ProcessCommand(id);
-}
-
-void wxFrame::ProcessCommand(int id)
-{
-  wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
-  commandEvent.SetInt( id );
-  commandEvent.SetEventObject( this );
-
-  wxMenuBar *bar = GetMenuBar() ;
-  if (!bar)
-    return;
+    wxMenuBar *bar = GetMenuBar() ;
+    if ( !bar )
+        return FALSE;
 
-  wxMenuItem *item = bar->FindItemForId(id) ;
-  if (item && item->IsCheckable())
-  {
-    bar->Check(id,!bar->Checked(id)) ;
-  }
+    wxMenuItem *item = bar->FindItemForId(id);
+    if ( !item )
+        return FALSE;
 
-/*
-  // Process events starting with the window with the focus, if any.
-  wxWindow* focusWin = wxFindFocusDescendant(this);
+    if ( item->IsCheckable() )
+    {
+        bar->Check(id, !bar->IsChecked(id)) ;
+    }
 
-  wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler();
-*/
+    wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
+    commandEvent.SetInt( id );
+    commandEvent.SetEventObject( this );
 
-  wxEvtHandler* evtHandler = GetEventHandler();
-  evtHandler->ProcessEvent(commandEvent);
+    return GetEventHandler()->ProcessEvent(commandEvent);
 }
 
 // Checks if there is a toolbar, and returns the first free client position
@@ -968,7 +723,7 @@ void wxFrame::ClientToScreen(int *x, int *y) const
 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
 {
     wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
-               "recreating toolbar in wxFrame" );
+                 "recreating toolbar in wxFrame" );
 
     wxToolBar* toolBar = OnCreateToolBar(style, id, name);
     if (toolBar)
@@ -991,7 +746,7 @@ wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& n
 void wxFrame::PositionToolBar()
 {
     RECT rect;
-    ::GetClientRect((HWND) GetHWND(), &rect);
+    ::GetClientRect(GetHwnd(), &rect);
 
     if ( GetStatusBar() )
     {
@@ -1037,9 +792,170 @@ void wxFrame::IconizeChildFrames(bool bIconize)
 }
 
 // ===========================================================================
-// our private (non virtual) message handlers
+// message processing
 // ===========================================================================
 
+// ---------------------------------------------------------------------------
+// preprocessing
+// ---------------------------------------------------------------------------
+
+bool wxFrame::MSWTranslateMessage(WXMSG* pMsg)
+{
+    if ( wxWindow::MSWTranslateMessage(pMsg) )
+        return TRUE;
+
+    // try the menu bar accels
+    wxMenuBar *menuBar = GetMenuBar();
+    if ( !menuBar )
+        return FALSE;
+
+    const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
+    return acceleratorTable.Ok() &&
+           ::TranslateAccelerator(GetHwnd(),
+                                  GetTableHaccel(acceleratorTable),
+                                  (MSG *)pMsg);
+}
+
+// ---------------------------------------------------------------------------
+// our private (non virtual) message handlers
+// ---------------------------------------------------------------------------
+
+bool wxFrame::HandlePaint()
+{
+    RECT rect;
+    if ( GetUpdateRect(GetHwnd(), &rect, FALSE) )
+    {
+        if ( m_iconized )
+        {
+            HICON hIcon = m_icon.Ok() ? GetIconHicon(m_icon)
+                                      : (HICON)m_defaultIcon;
+
+            // Hold a pointer to the dc so long as the OnPaint() message
+            // is being processed
+            PAINTSTRUCT ps;
+            HDC hdc = ::BeginPaint(GetHwnd(), &ps);
+
+            // Erase background before painting or we get white background
+            MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L);
+
+            if ( hIcon )
+            {
+                RECT rect;
+                ::GetClientRect(GetHwnd(), &rect);
+
+                // FIXME: why hardcoded?
+                static const int icon_width = 32;
+                static const int icon_height = 32;
+
+                int icon_x = (int)((rect.right - icon_width)/2);
+                int icon_y = (int)((rect.bottom - icon_height)/2);
+
+                ::DrawIcon(hdc, icon_x, icon_y, hIcon);
+            }
+
+            ::EndPaint(GetHwnd(), &ps);
+
+            return TRUE;
+        }
+        else
+        {
+            wxPaintEvent event(m_windowId);
+            event.m_eventObject = this;
+
+            return GetEventHandler()->ProcessEvent(event);
+        }
+    }
+    else
+    {
+        // nothing to paint - processed
+        return TRUE;
+    }
+}
+
+bool wxFrame::HandleSize(int x, int y, WXUINT id)
+{
+    bool processed = FALSE;
+
+    switch ( id )
+    {
+        case SIZENORMAL:
+            // only do it it if we were iconized before, otherwise resizing the
+            // parent frame has a curious side effect of bringing it under it's
+            // children
+            if ( !m_iconized )
+                break;
+
+            // restore all child frames too
+            IconizeChildFrames(FALSE);
+
+            // fall through
+
+        case SIZEFULLSCREEN:
+            m_iconized = FALSE;
+            break;
+
+        case SIZEICONIC:
+            // iconize all child frames too
+            IconizeChildFrames(TRUE);
+
+            m_iconized = TRUE;
+            break;
+    }
+
+    if ( !m_iconized )
+    {
+        // forward WM_SIZE to status bar control
+#if wxUSE_NATIVE_STATUSBAR
+        if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
+        {
+            wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
+            event.SetEventObject( m_frameStatusBar );
+
+            ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
+        }
+#endif // wxUSE_NATIVE_STATUSBAR
+
+        PositionStatusBar();
+        PositionToolBar();
+
+        wxSizeEvent event(wxSize(x, y), m_windowId);
+        event.SetEventObject( this );
+        processed = GetEventHandler()->ProcessEvent(event);
+    }
+
+    return processed;
+}
+
+bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
+{
+    if ( control )
+    {
+        // In case it's e.g. a toolbar.
+        wxWindow *win = wxFindWinFromHandle(control);
+        if ( win )
+            return win->MSWCommand(cmd, id);
+    }
+
+    // handle here commands from menus and accelerators
+    if ( cmd == 0 || cmd == 1 )
+    {
+        if ( wxCurrentPopupMenu )
+        {
+            wxMenu *popupMenu = wxCurrentPopupMenu;
+            wxCurrentPopupMenu = NULL;
+
+            return popupMenu->MSWCommand(cmd, id);
+        }
+
+        if ( ProcessCommand(id) )
+        {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
 bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu)
 {
     int item;
@@ -1074,19 +990,49 @@ long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 
     switch ( message )
     {
+        case WM_CLOSE:
+            // if we can't close, tell the system that we processed the
+            // message - otherwise it would close us
+            processed = !Close();
+            break;
+
+        case WM_COMMAND:
+            {
+                WORD id, cmd;
+                WXHWND hwnd;
+                UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
+                              &id, &hwnd, &cmd);
+
+                processed = HandleCommand(id, cmd, (WXHWND)hwnd);
+            }
+            break;
+
         case WM_MENUSELECT:
             {
-                WORD item = (WORD)wParam;
-#ifdef __WIN32__
-                WORD flags = HIWORD(wParam);
-                HMENU sysmenu = (HMENU)lParam;
-#else
-                WORD flags = LOWORD(lParam);
-                HMENU sysmenu = (HMENU)HIWORD(lParam);
-#endif
-                processed = HandleMenuSelect(item, flags, (WXHMENU)sysmenu);
+                WXWORD item, flags;
+                WXHMENU hmenu;
+                UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
+
+                processed = HandleMenuSelect(item, flags, hmenu);
             }
             break;
+
+        case WM_PAINT:
+            processed = HandlePaint();
+            break;
+
+        case WM_QUERYDRAGICON:
+            {
+                HICON hIcon = m_icon.Ok() ? GetIconHicon(m_icon)
+                                          : (HICON)(m_defaultIcon);
+                rc = (long)hIcon;
+                processed = rc != 0;
+            }
+            break;
+
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
     }
 
     if ( !processed )
index 4ca6a3955b3551b79536795acad979137c6a0a9e..994f8e8f9b500998d6ebc359349b6796a29d8f05 100644 (file)
     #endif
 #endif
 
-#ifdef GetCharWidth
-    #undef GetCharWidth
-#endif
-
 #if wxUSE_OWNER_DRAWN
     #include  "wx/ownerdrw.h"
 #endif
@@ -165,7 +161,8 @@ bool wxListBox::Create(wxWindow *parent,
     int height = size.y;
     m_windowStyle = style;
 
-    DWORD wstyle = WS_VSCROLL | WS_TABSTOP | LBS_NOTIFY | LBS_HASSTRINGS;
+    DWORD wstyle = WS_VISIBLE | WS_VSCROLL | WS_TABSTOP |
+                   LBS_NOTIFY | LBS_HASSTRINGS;
     if (m_windowStyle & wxLB_MULTIPLE)
         wstyle |= LBS_MULTIPLESEL;
     else if (m_windowStyle & wxLB_EXTENDED)
index 7f933c7c84bf96b05cd08b11842d62cb38937eb6..eb34e34f23b705c4d02b32968de1de1f06d1e012 100644 (file)
@@ -61,14 +61,18 @@ extern wxWindow *wxWndHook;                 // from window.cpp
 
 extern wxList *wxWinHandleList;
 
+static HWND invalidHandle = 0;
+
 // ---------------------------------------------------------------------------
 // constants
 // ---------------------------------------------------------------------------
 
 static const int IDM_WINDOWTILE  = 4001;
+static const int IDM_WINDOWTILEHOR  = 4001;
 static const int IDM_WINDOWCASCADE = 4002;
 static const int IDM_WINDOWICONS = 4003;
 static const int IDM_WINDOWNEXT = 4004;
+static const int IDM_WINDOWTILEVERT = 4005;
 
 // This range gives a maximum of 500 MDI children. Should be enough :-)
 static const int wxFIRST_MDI_CHILD = 4100;
@@ -78,6 +82,27 @@ static const int wxLAST_MDI_CHILD = 4600;
 static const int wxTHICK_LINE_BORDER = 3;
 static const int wxTHICK_LINE_WIDTH  = 1;
 
+// ---------------------------------------------------------------------------
+// private functions
+// ---------------------------------------------------------------------------
+
+// set the MDI menus (by sending the WM_MDISETMENU message) and update the menu
+// of the parent of win (which is supposed to be the MDI client window)
+static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow);
+
+// insert the window menu (subMenu) into menu just before "Help" submenu or at
+// the very end if not found
+static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu);
+
+// is this an id of an MDI child?
+inline bool IsMdiCommandId(int id)
+{
+    return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD);
+}
+
+static UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
+                         WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
+
 // ===========================================================================
 // implementation
 // ===========================================================================
@@ -94,7 +119,6 @@ static const int wxTHICK_LINE_WIDTH  = 1;
 
 BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
     EVT_SIZE(wxMDIParentFrame::OnSize)
-    EVT_ACTIVATE(wxMDIParentFrame::OnActivate)
     EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
 END_EVENT_TABLE()
 
@@ -102,9 +126,10 @@ BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
     EVT_SCROLL(wxMDIClientWindow::OnScroll)
 END_EVENT_TABLE()
 
-// ---------------------------------------------------------------------------
-// wxMDIParentFrame
-// ---------------------------------------------------------------------------
+// ===========================================================================
+// wxMDIParentFrame: the frame which contains the client window which manages
+// the children
+// ===========================================================================
 
 wxMDIParentFrame::wxMDIParentFrame()
 {
@@ -149,7 +174,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
 
   m_windowMenu = (WXHMENU) ::LoadMenu(wxGetInstance(), "wxWindowMenu");
 
-  DWORD msflags = WS_OVERLAPPED ;
+  DWORD msflags = WS_OVERLAPPED;
   if (style & wxMINIMIZE_BOX)
     msflags |= WS_MINIMIZEBOX;
   if (style & wxMAXIMIZE_BOX)
@@ -180,96 +205,39 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
 
 wxMDIParentFrame::~wxMDIParentFrame()
 {
-  DestroyChildren();
+    DestroyChildren();
 
-  DestroyMenu((HMENU) m_windowMenu); // Destroy dummy "Window" menu
-  m_windowMenu = 0;
+    ::DestroyMenu((HMENU)m_windowMenu);
+    m_windowMenu = 0;
 
-  if (m_clientWindow->MSWGetOldWndProc())
-      m_clientWindow->UnsubclassWin();
+    if ( m_clientWindow )
+    {
+        if ( m_clientWindow->MSWGetOldWndProc() )
+            m_clientWindow->UnsubclassWin();
 
-  m_clientWindow->SetHWND(0);
-  delete m_clientWindow;
+        m_clientWindow->SetHWND(0);
+        delete m_clientWindow;
+    }
 }
 
-void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar)
+void wxMDIParentFrame::InternalSetMenuBar()
 {
-  if (!menu_bar)
-  {
-    m_frameMenuBar = NULL;
-    return;
-  }
-
-  if ( menu_bar->IsAttached() )
-     return;
+    HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0);
 
-  m_hMenu = menu_bar->Create();
-
-  if (m_frameMenuBar)
-    delete m_frameMenuBar;
-
-  // MDI parent-specific code follows
-
-  HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0);
-
-  // Try to insert Window menu in front of Help, otherwise append it.
-  HMENU menu = (HMENU)m_hMenu;
-  int N = GetMenuItemCount(menu);
-  bool success = FALSE;
-  for (int i = 0; i < N; i++)
-  {
-        char buf[100];
-        int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
-        if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
-                            strcmp(buf, "Help") == 0))
-        {
-           success = TRUE;
-           InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
-                      (UINT)subMenu, "&Window");
-           break;
-        }
-  }
-  if (!success)
-    AppendMenu(menu, MF_POPUP,
-                         (UINT)subMenu,
-                         "&Window");
-  m_parentFrameActive = TRUE;
-#ifdef __WIN32__
-  SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDISETMENU,
-                (WPARAM)menu,
-                  (LPARAM)subMenu);
-#else
-  SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
-              MAKELPARAM(menu, subMenu));
-#endif
-  DrawMenuBar((HWND) GetHWND());
+    m_parentFrameActive = TRUE;
 
-  m_frameMenuBar = menu_bar;
-  menu_bar->Attach(this);
+    InsertWindowMenu(GetClientWindow(), m_hMenu, subMenu);
 }
 
 void wxMDIParentFrame::OnSize(wxSizeEvent& event)
 {
-#if wxUSE_CONSTRAINTS
-    if ( GetAutoLayout() )
-    {
-        Layout();
-        return;
-    }
-#endif // wxUSE_CONSTRAINTS
-
-    int x = 0;
-    int y = 0;
-    int width, height;
-    GetClientSize(&width, &height);
-
     if ( GetClientWindow() )
-        GetClientWindow()->SetSize(x, y, width, height);
-}
+    {
+        int width, height;
+        GetClientSize(&width, &height);
 
-void wxMDIParentFrame::OnActivate(wxActivateEvent& event)
-{
-    // Do nothing
+        GetClientWindow()->SetSize(0, 0, width, height);
+    }
 }
 
 // Returns the active MDI child window
@@ -298,25 +266,20 @@ void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
         m_clientWindow->SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
         m_clientWindow->Refresh();
     }
-/*
-    if ( m_frameToolBar )
-    {
-        wxSysColourChangedEvent event2;
-        event2.eventObject = m_frameToolBar;
-        m_frameToolBar->GetEventHandler()->ProcessEvent(event2);
-    }
-*/
 
-    // Propagate the event to the non-top-level children
-    wxFrame::OnSysColourChanged(event);
+    event.Skip();
 }
 
+// ---------------------------------------------------------------------------
 // MDI operations
+// ---------------------------------------------------------------------------
+
 void wxMDIParentFrame::Cascade()
 {
     ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE, 0, 0);
 }
 
+// TODO: add a direction argument (hor/vert)
 void wxMDIParentFrame::Tile()
 {
     ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, MDITILE_HORIZONTAL, 0);
@@ -337,7 +300,10 @@ void wxMDIParentFrame::ActivatePrevious()
     ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 1);
 }
 
+// ---------------------------------------------------------------------------
 // the MDI parent frame window proc
+// ---------------------------------------------------------------------------
+
 long wxMDIParentFrame::MSWWindowProc(WXUINT message,
                                      WXWPARAM wParam,
                                      WXLPARAM lParam)
@@ -347,6 +313,31 @@ long wxMDIParentFrame::MSWWindowProc(WXUINT message,
 
     switch ( message )
     {
+        case WM_ACTIVATE:
+            {
+                WXWORD state, minimized;
+                WXHWND hwnd;
+                UnpackActivate(wParam, lParam, &state, &minimized, &hwnd);
+
+                processed = HandleActivate(state, minimized != 0, hwnd);
+            }
+            break;
+
+        case WM_COMMAND:
+            {
+                WXWORD id, cmd;
+                WXHWND hwnd;
+                UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
+
+                (void)HandleCommand(id, cmd, hwnd);
+
+                // even if the frame didn't process it, there is no need to try it
+                // once again (i.e. call wxFrame::HandleCommand()) - we just dud it,
+                // so pretend we processed the message anyhow
+                processed = TRUE;
+            }
+            break;
+
         case WM_CREATE:
             m_clientWindow = OnCreateClient();
             // Uses own style for client style
@@ -369,22 +360,18 @@ long wxMDIParentFrame::MSWWindowProc(WXUINT message,
 
         case WM_MENUSELECT:
             {
-                WORD item = (WORD)wParam;
-#ifdef __WIN32__
-                WORD flags = HIWORD(wParam);
-                HMENU menu = (HMENU)lParam;
-#else
-                WORD flags = LOWORD(lParam);
-                HMENU menu = (HMENU)HIWORD(lParam);
-#endif
+                WXWORD item, flags;
+                WXHMENU hmenu;
+                UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
+
                 if ( m_parentFrameActive )
                 {
-                    processed = HandleMenuSelect(item, flags, (WXHMENU)menu);
+                    processed = HandleMenuSelect(item, flags, hmenu);
                 }
                 else if (m_currentChild)
                 {
                     processed = m_currentChild->
-                        HandleMenuSelect(item, flags, (WXHMENU)menu);
+                        HandleMenuSelect(item, flags, hmenu);
                 }
             }
             break;
@@ -396,11 +383,11 @@ long wxMDIParentFrame::MSWWindowProc(WXUINT message,
     return rc;
 }
 
-bool wxMDIParentFrame::MSWOnActivate(int state, bool minimized, WXHWND activate)
+bool wxMDIParentFrame::HandleActivate(int state, bool minimized, WXHWND activate)
 {
     bool processed = FALSE;
 
-    if ( wxWindow::MSWOnActivate(state, minimized, activate) )
+    if ( wxWindow::HandleActivate(state, minimized, activate) )
     {
         // already processed
         processed = TRUE;
@@ -408,7 +395,7 @@ bool wxMDIParentFrame::MSWOnActivate(int state, bool minimized, WXHWND activate)
 
     // If this window is an MDI parent, we must also send an OnActivate message
     // to the current child.
-    if ( (m_currentChild != NULL) && 
+    if ( (m_currentChild != NULL) &&
          ((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)) )
     {
         wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_currentChild->GetId());
@@ -420,92 +407,104 @@ bool wxMDIParentFrame::MSWOnActivate(int state, bool minimized, WXHWND activate)
     return processed;
 }
 
-bool wxMDIParentFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
+bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
 {
-//  if (cmd == 0) // Why did I do this test?
-  {
     // In case it's e.g. a toolbar.
-    wxWindow *win = wxFindWinFromHandle(control);
-    if (win)
-      return win->MSWCommand(cmd, id);
-
-/*
-    if (wxCurrentPopupMenu)
+    if ( hwnd )
     {
-        wxMenu *popupMenu = wxCurrentPopupMenu;
-        wxCurrentPopupMenu = NULL;
-        if (!popupMenu->MSWCommand(cmd, id))
-            return TRUE;
+        wxWindow *win = wxFindWinFromHandle(hwnd);
+        if ( win )
+            return win->MSWCommand(cmd, id);
     }
-*/
 
-    switch (id)
-    {
-      case IDM_WINDOWCASCADE:
-        SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDICASCADE, MDITILE_SKIPDISABLED, 0);
-        return TRUE;
-      case IDM_WINDOWTILE:
-        SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDITILE, MDITILE_HORIZONTAL, 0);
-        return TRUE;
-      case IDM_WINDOWICONS:
-        SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDIICONARRANGE, 0, 0);
-        return TRUE;
-      case IDM_WINDOWNEXT:
-        SendMessage((HWND) GetClientWindow()->GetHWND(), WM_MDINEXT, 0, 0);
-        return TRUE;
-      default:
-        break;
-     }
-    if (id >= 0xF000)
+    // is it one of standard MDI commands?
+    WXWPARAM wParam = 0;
+    int msg;
+    switch ( id )
     {
-      return FALSE; // Get WndProc to call default proc
+        case IDM_WINDOWCASCADE:
+            msg = WM_MDICASCADE;
+            wParam = MDITILE_SKIPDISABLED;
+            break;
+
+        case IDM_WINDOWTILEHOR:
+            wParam |= MDITILE_HORIZONTAL;
+            // fall through
+
+        case IDM_WINDOWTILEVERT:
+            if ( !wParam )
+                wParam = MDITILE_VERTICAL;
+            msg = WM_MDITILE;
+            wParam |= MDITILE_SKIPDISABLED;
+            break;
+
+        case IDM_WINDOWICONS:
+            msg = WM_MDIICONARRANGE;
+            break;
+
+        case IDM_WINDOWNEXT:
+            msg = WM_MDINEXT;
+            break;
+
+        default:
+            msg = 0;
     }
 
-    if (m_parentFrameActive && (id < wxFIRST_MDI_CHILD || id > wxLAST_MDI_CHILD))
+    if ( msg )
     {
-      ProcessCommand(id);
-      return TRUE;
+        ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, 0);
+
+        return TRUE;
     }
-    else if (m_currentChild && (id < wxFIRST_MDI_CHILD || id > wxLAST_MDI_CHILD))
+
+    // FIXME VZ: what does this test do??
+    if (id >= 0xF000)
     {
-      return m_currentChild->MSWOnCommand(id, cmd, control);
+        return FALSE; // Get WndProc to call default proc
     }
-  }
-  if (id >= wxFIRST_MDI_CHILD && id <= wxLAST_MDI_CHILD)
-  {
-    wxNode* node = GetChildren().First();
-    while (node)
+
+    if ( IsMdiCommandId(id) )
     {
-        wxWindow* child = (wxWindow*) node->Data();
-        if (child->GetHWND())
+        wxWindowList::Node* node = GetChildren().GetFirst();
+        while ( node )
         {
-#ifdef __WIN32__
-            long childId = GetWindowLong((HWND) child->GetHWND(), GWL_ID);
-#else
-            long childId = GetWindowWord((HWND) child->GetHWND(), GWW_ID);
-#endif
-            if (childId == id)
+            wxWindow* child = node->GetData();
+            if ( child->GetHWND() )
             {
-                ::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) child->GetHWND(), 0);
-                return TRUE;
+                long childId = wxGetWindowId(child->GetHWND());
+                if (childId == id)
+                {
+                    ::SendMessage( GetWinHwnd(GetClientWindow()),
+                                   WM_MDIACTIVATE,
+                                   (WPARAM)child->GetHWND(), 0);
+                    return TRUE;
+                }
             }
+            node = node->GetNext();
         }
-        node = node->Next();
     }
-/*
-    wxWindow* child = FindItem(id);
-    if (child)
+    else if ( m_parentFrameActive )
     {
-        ::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) child->GetHWND(), 0);
-        return TRUE;
+        return ProcessCommand(id);
+    }
+    else if ( m_currentChild )
+    {
+        return m_currentChild->HandleCommand(id, cmd, hwnd);
+    }
+    else
+    {
+        // this shouldn't happen because it means that our messages are being
+        // lost (they're not sent to the parent frame nor to the children)
+        wxFAIL_MSG(_T("MDI parent frame is not active, "
+                      "yet there is no active MDI child?"));
     }
-*/
-  }
 
-  return wxWindow::MSWOnCommand(id, cmd, control);
+    return FALSE;
 }
 
-long wxMDIParentFrame::MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+long wxMDIParentFrame::MSWDefWindowProc(WXUINT message,
+                                        WXWPARAM wParam,
+                                        WXLPARAM lParam)
 {
     WXHWND clientWnd;
     if ( GetClientWindow() )
@@ -516,12 +515,6 @@ long wxMDIParentFrame::MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARA
     return DefFrameProc(GetHwnd(), (HWND)clientWnd, message, wParam, lParam);
 }
 
-bool wxMDIParentFrame::MSWProcessMessage(WXMSG* msg)
-{
-    return m_currentChild && m_currentChild->GetHWND() &&
-           m_currentChild->MSWProcessMessage(msg);
-}
-
 bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg)
 {
     MSG *pMsg = (MSG *)msg;
@@ -534,7 +527,7 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg)
 
     if ( m_acceleratorTable.Ok() &&
          ::TranslateAccelerator(GetHwnd(),
-                                GetTableHaccel(&m_acceleratorTable),
+                                GetTableHaccel(m_acceleratorTable),
                                 pMsg) )
     {
         return TRUE;
@@ -549,13 +542,12 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg)
     return FALSE;
 }
 
-// ---------------------------------------------------------------------------
+// ===========================================================================
 // wxMDIChildFrame
-// ---------------------------------------------------------------------------
+// ===========================================================================
 
 wxMDIChildFrame::wxMDIChildFrame()
 {
-//    m_active = FALSE;
 }
 
 bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
@@ -566,7 +558,8 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
                              long style,
                              const wxString& name)
 {
-  m_defaultIcon = (WXHICON) (wxSTD_MDICHILDFRAME_ICON ? wxSTD_MDICHILDFRAME_ICON : wxDEFAULT_MDICHILDFRAME_ICON);
+  m_defaultIcon = (WXHICON)(wxSTD_MDICHILDFRAME_ICON ? wxSTD_MDICHILDFRAME_ICON
+                                                     : wxDEFAULT_MDICHILDFRAME_ICON);
 
   SetName(name);
 
@@ -575,7 +568,10 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
   else
     m_windowId = (int)NewControlId();
 
-  if (parent) parent->AddChild(this);
+  if ( parent )
+  {
+      parent->AddChild(this);
+  }
 
   wxWndHook = this;
 
@@ -589,19 +585,27 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
   mcs.szClass = wxMDIChildFrameClassName;
   mcs.szTitle = title;
   mcs.hOwner = wxGetInstance();
-  if (x > -1) mcs.x = x;
-  else mcs.x = CW_USEDEFAULT;
+  if (x > -1)
+      mcs.x = x;
+  else
+      mcs.x = CW_USEDEFAULT;
 
-  if (y > -1) mcs.y = y;
-  else mcs.y = CW_USEDEFAULT;
+  if (y > -1)
+      mcs.y = y;
+  else
+      mcs.y = CW_USEDEFAULT;
 
-  if (width > -1) mcs.cx = width;
-  else mcs.cx = CW_USEDEFAULT;
+  if (width > -1)
+      mcs.cx = width;
+  else
+      mcs.cx = CW_USEDEFAULT;
 
-  if (height > -1) mcs.cy = height;
-  else mcs.cy = CW_USEDEFAULT;
+  if (height > -1)
+      mcs.cy = height;
+  else
+      mcs.cy = CW_USEDEFAULT;
 
-  DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN ;
+  DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN;
   if (style & wxMINIMIZE_BOX)
     msflags |= WS_MINIMIZEBOX;
   if (style & wxMAXIMIZE_BOX)
@@ -643,8 +647,6 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
 wxMDIChildFrame::~wxMDIChildFrame()
 {
     MSWDestroyWindow();
-
-    ResetWindowStyle(NULL);
 }
 
 // Set the client size (i.e. leave the calculation of borders etc.
@@ -705,63 +707,21 @@ void wxMDIChildFrame::DoGetPosition(int *x, int *y) const
   *y = point.y;
 }
 
-void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
+void wxMDIChildFrame::InternalSetMenuBar()
 {
-  if (!menu_bar)
-  {
-    m_frameMenuBar = NULL;
-    return;
-  }
-
-  if ( menu_bar->IsAttached() )
-     return;
-
-  m_hMenu = menu_bar->Create();
-
-  if (m_frameMenuBar)
-    delete m_frameMenuBar;
+    wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
 
-   wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+    HMENU subMenu = GetSubMenu((HMENU)parent->GetWindowMenu(), 0);
 
-   parent->m_parentFrameActive = FALSE;
-   HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
+    InsertWindowMenu(parent->GetClientWindow(), m_hMenu, subMenu);
 
-   // Try to insert Window menu in front of Help, otherwise append it.
-   HMENU menu = (HMENU)m_hMenu;
-   int N = GetMenuItemCount(menu);
-   bool success = FALSE;
-   for (int i = 0; i < N; i++)
-   {
-        char buf[100];
-        int chars = GetMenuString(menu, i, buf, 100, MF_BYPOSITION);
-        if ((chars > 0) && (strcmp(buf, "&Help") == 0 ||
-                            strcmp(buf, "Help") == 0))
-        {
-           success = TRUE;
-           InsertMenu(menu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
-                      (UINT)subMenu, "&Window");
-           break;
-        }
-      }
-  if (!success)
-    AppendMenu(menu, MF_POPUP,
-                         (UINT)subMenu,
-                         "&Window");
-#ifdef __WIN32__
-  SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU,
-                  (WPARAM)menu,
-                  (LPARAM)subMenu);
-#else
-  SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
-                  MAKELPARAM(menu, subMenu));
-#endif
-
-  DrawMenuBar((HWND) parent->GetHWND());
-  m_frameMenuBar = menu_bar;
-  menu_bar->Attach(this);
+    parent->m_parentFrameActive = FALSE;
 }
 
+// ---------------------------------------------------------------------------
 // MDI operations
+// ---------------------------------------------------------------------------
+
 void wxMDIChildFrame::Maximize()
 {
     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
@@ -783,16 +743,70 @@ void wxMDIChildFrame::Activate()
         ::SendMessage( (HWND) parent->GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) GetHWND(), 0);
 }
 
-static HWND invalidHandle = 0;
-bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id)
+// ---------------------------------------------------------------------------
+// MDI window proc and message handlers
+// ---------------------------------------------------------------------------
+
+long wxMDIChildFrame::MSWWindowProc(WXUINT message,
+                                    WXWPARAM wParam,
+                                    WXLPARAM lParam)
+{
+    long rc = 0;
+    bool processed = FALSE;
+
+    switch ( message )
+    {
+        case WM_COMMAND:
+            {
+                WORD id, cmd;
+                WXHWND hwnd;
+                UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
+                              &id, &hwnd, &cmd);
+
+                processed = HandleCommand(id, cmd, (WXHWND)hwnd);
+            }
+            break;
+
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
+
+        case WM_GETMINMAXINFO:
+            // let the default window proc calculate the size of MDI children
+            // frames because it is based on the size of the MDI client window,
+            // not on the values specified in wxWindow m_min/max variables
+            return MSWDefWindowProc(message, wParam, lParam);
+
+        case WM_MDIACTIVATE:
+            {
+                WXWORD act;
+                WXHWND hwndAct, hwndDeact;
+                UnpackMDIActivate(wParam, lParam, &act, &hwndAct, &hwndDeact);
+
+                processed = HandleMDIActivate(act, hwndAct, hwndDeact);
+            }
+            break;
+
+        case WM_WINDOWPOSCHANGING:
+            processed = HandleWindowPosChanging((LPWINDOWPOS)lParam);
+            break;
+    }
+
+    if ( !processed )
+        rc = wxFrame::MSWWindowProc(message, wParam, lParam);
+
+    return rc;
+}
+
+bool wxMDIChildFrame::HandleSize(int x, int y, WXUINT id)
 {
     HWND hwnd = GetHwnd();
-    
+
     if ( !hwnd || hwnd == invalidHandle )
     {
         return FALSE;
     }
-    
+
     switch (id)
     {
         case SIZEFULLSCREEN:
@@ -804,8 +818,8 @@ bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id)
             m_iconized = TRUE;
             break;
     }
-    
-    if (!m_iconized)
+
+    if ( !m_iconized )
     {
         // forward WM_SIZE to status bar control
 #if wxUSE_NATIVE_STATUSBAR
@@ -813,15 +827,15 @@ bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id)
         {
             wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
             event.SetEventObject( m_frameStatusBar );
-            
+
             ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
         }
-#endif
-        
+#endif // wxUSE_NATIVE_STATUSBAR
+
         PositionStatusBar();
         PositionToolBar();
-        
-        return wxWindow::MSWOnSize(x, y, id);
+
+        return wxWindow::HandleSize(x, y, id);
     }
     else
     {
@@ -829,15 +843,15 @@ bool wxMDIChildFrame::MSWOnSize(int x, int y, WXUINT id)
     }
 }
 
-bool wxMDIChildFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
+bool wxMDIChildFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
 {
-//  if ((cmd == 0) && GetHWND())
-  if (GetHWND())
-  {
     // In case it's e.g. a toolbar.
-    wxWindow *win = wxFindWinFromHandle(control);
-    if (win)
-      return win->MSWCommand(cmd, id);
+    if ( hwnd )
+    {
+        wxWindow *win = wxFindWinFromHandle(hwnd);
+        if (win)
+            return win->MSWCommand(cmd, id);
+    }
 
     if (wxCurrentPopupMenu)
     {
@@ -849,135 +863,157 @@ bool wxMDIChildFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
 
     if (GetMenuBar() && GetMenuBar()->FindItemForId(id))
     {
-      ProcessCommand(id);
-      return TRUE;
+        ProcessCommand(id);
+        return TRUE;
     }
     else
-      return FALSE;
+        return FALSE;
+
     return TRUE;
-  }
-  else
-    return wxWindow::MSWOnCommand(id, cmd, control);
 }
 
-long wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXUINT wParam, WXLPARAM lParam)
+bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
+                                        WXHWND hwndAct,
+                                        WXHWND hwndDeact)
 {
-  if (GetHWND())
-    return DefMDIChildProc((HWND) GetHWND(), (UINT) message, (WPARAM) wParam, (LPARAM) lParam);
-  else return 0;
-}
+    wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
 
-bool wxMDIChildFrame::MSWProcessMessage(WXMSG *msg)
-{
-  return FALSE;
-}
+    HMENU menuToSet = 0;
 
-bool wxMDIChildFrame::MSWTranslateMessage(WXMSG* msg)
-{
-  MSG *pMsg = (MSG *)msg;
-  if (m_acceleratorTable.Ok())
-  {
-    wxFrame *parent = (wxFrame *)GetParent();
-    HWND parent_hwnd = (HWND) parent->GetHWND();
-    return (::TranslateAccelerator(parent_hwnd, (HACCEL) m_acceleratorTable.GetHACCEL(), pMsg) != 0);
-  }
+    bool activated;
 
-  return FALSE;
-}
+    if ( m_hWnd == hwndAct )
+    {
+        activated = TRUE;
+        parent->m_currentChild = this;
 
-bool wxMDIChildFrame::MSWOnMDIActivate(long activate, WXHWND WXUNUSED(one), WXHWND WXUNUSED(two))
-{
-  wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
-  HMENU parent_menu = (HMENU) parent->GetWinMenu();
-  HMENU child_menu = (HMENU) GetWinMenu();
+        HMENU child_menu = (HMENU)GetWinMenu();
+        if ( child_menu )
+        {
+            parent->m_parentFrameActive = FALSE;
 
-  if (activate)
-  {
-//    m_active = TRUE;
-    parent->m_currentChild = this;
-    if (child_menu)
+            menuToSet = child_menu;
+        }
+    }
+    else if ( m_hWnd == hwndDeact )
     {
-      parent->m_parentFrameActive = FALSE;
-      HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
-#ifdef __WIN32__
-      ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU,
-                    (WPARAM)child_menu,
-                    (LPARAM)subMenu);
-#else
-      ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
-                  MAKELONG(child_menu, subMenu));
-#endif
+        wxASSERT_MSG( parent->m_currentChild == this,
+                      _T("can't deactivate MDI child which wasn't active!") );
+
+        activated = FALSE;
+        parent->m_currentChild = NULL;
 
-      ::DrawMenuBar((HWND) parent->GetHWND());
+        HMENU parent_menu = (HMENU)parent->GetWinMenu();
+        if ( parent_menu )
+        {
+            parent->m_parentFrameActive = TRUE;
+
+            menuToSet = parent_menu;
+        }
+    }
+    else
+    {
+        // we have nothing to with it
+        return FALSE;
     }
-    wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId);
-    event.SetEventObject( this );
-    return GetEventHandler()->ProcessEvent(event);
-  }
-  else
-  {
-    if (parent->m_currentChild == this)
-      parent->m_currentChild = NULL;
 
-    wxActivateEvent event(wxEVT_ACTIVATE, FALSE, m_windowId);
+    if ( menuToSet )
+    {
+        HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
+
+        MDISetMenu(parent->GetClientWindow(), menuToSet, subMenu);
+    }
+
+    wxActivateEvent event(wxEVT_ACTIVATE, activated, m_windowId);
     event.SetEventObject( this );
-    if ( GetEventHandler()->ProcessEvent(event) )
-        return TRUE;
 
-//    m_active = FALSE;
-    if (parent_menu)
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxMDIChildFrame::HandleWindowPosChanging(void *pos)
+{
+    WINDOWPOS *lpPos = (WINDOWPOS *)pos;
+#if defined(__WIN95__)
+    if (!(lpPos->flags & SWP_NOSIZE))
     {
-      parent->m_parentFrameActive = TRUE;
-      HMENU subMenu = GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
-#ifdef __WIN32__
-      ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU,
-                    (WPARAM)parent_menu,
-                    (LPARAM)subMenu);
-#else
-      ::SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDISETMENU, 0,
-                  MAKELONG(parent_menu, subMenu));
-#endif
+        RECT rectClient;
+        DWORD dwExStyle = ::GetWindowLong((HWND) GetHWND(), GWL_EXSTYLE);
+        DWORD dwStyle = ::GetWindowLong((HWND) GetHWND(), GWL_STYLE);
+        if (ResetWindowStyle((void *) & rectClient) && (dwStyle & WS_MAXIMIZE))
+        {
+            ::AdjustWindowRectEx(&rectClient, dwStyle, FALSE, dwExStyle);
+            lpPos->x = rectClient.left;
+            lpPos->y = rectClient.top;
+            lpPos->cx = rectClient.right - rectClient.left;
+            lpPos->cy = rectClient.bottom - rectClient.top;
+        }
+        wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
+        if (pFrameWnd && pFrameWnd->GetToolBar())
+        {
+            pFrameWnd->GetToolBar()->Refresh();
+        }
+    }
+#endif // Win95
+
+    return FALSE;
+}
+
+// ---------------------------------------------------------------------------
+// MDI specific message translation/preprocessing
+// ---------------------------------------------------------------------------
 
-      ::DrawMenuBar((HWND) parent->GetHWND());
+long wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXUINT wParam, WXLPARAM lParam)
+{
+    return DefMDIChildProc(GetHwnd(),
+                           (UINT)message, (WPARAM)wParam, (LPARAM)lParam);
+}
+
+bool wxMDIChildFrame::MSWTranslateMessage(WXMSG* msg)
+{
+    MSG *pMsg = (MSG *)msg;
+    if ( m_acceleratorTable.Ok() )
+    {
+        return ::TranslateAccelerator(GetWinHwnd(GetParent()),
+                                      GetTableHaccel(m_acceleratorTable),
+                                      pMsg) != 0;
     }
-  }
-  bool flag = (activate != 0);
-  wxActivateEvent event(wxEVT_ACTIVATE, flag, m_windowId);
-  event.SetEventObject( this );
-  return GetEventHandler()->ProcessEvent(event);
+
+    return FALSE;
 }
 
+// ---------------------------------------------------------------------------
+// misc
+// ---------------------------------------------------------------------------
+
 void wxMDIChildFrame::MSWDestroyWindow()
 {
-  MSWDetachWindowMenu();
-  invalidHandle = (HWND) GetHWND();
+    MSWDetachWindowMenu();
+    invalidHandle = (HWND) GetHWND();
 
-  wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+    wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
 
-  // Must make sure this handle is invalidated (set to NULL)
-  // since all sorts of things could happen after the
-  // child client is destroyed, but before the wxFrame is
-  // destroyed.
+    // Must make sure this handle is invalidated (set to NULL) since all sorts
+    // of things could happen after the child client is destroyed, but before
+    // the wxFrame is destroyed.
 
-  HWND oldHandle = (HWND)GetHWND();
+    HWND oldHandle = (HWND)GetHWND();
 #ifdef __WIN32__
-  SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (WPARAM)oldHandle, (LPARAM)0);
+    SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (WPARAM)oldHandle, (LPARAM)0);
 #else
-  SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (HWND)oldHandle, 0);
+    SendMessage((HWND) parent->GetClientWindow()->GetHWND(), WM_MDIDESTROY, (HWND)oldHandle, 0);
 #endif
-  invalidHandle = 0;
+    invalidHandle = 0;
 
-  if (m_hMenu)
-  {
-    ::DestroyMenu((HMENU) m_hMenu);
-    m_hMenu = 0;
-  }
-  m_hWnd = 0;
+    if (m_hMenu)
+    {
+        ::DestroyMenu((HMENU) m_hMenu);
+        m_hMenu = 0;
+    }
+    m_hWnd = 0;
 }
 
-// Change the client window's extended style so we don't
-// get a client edge style when a child is maximised (a double
-// border looks silly.)
+// Change the client window's extended style so we don't get a client edge
+// style when a child is maximised (a double border looks silly.)
 bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
 {
 #if defined(__WIN95__)
@@ -996,106 +1032,75 @@ bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
 
         if (dwStyle != dwNewStyle)
         {
-            ::RedrawWindow((HWND) pFrameWnd->GetClientWindow()->GetHWND(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
-            ::SetWindowLong((HWND) pFrameWnd->GetClientWindow()->GetHWND(), GWL_EXSTYLE, dwNewStyle);
-            ::SetWindowPos((HWND) pFrameWnd->GetClientWindow()->GetHWND(), NULL, 0, 0, 0, 0,
-                SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOCOPYBITS);
+            HWND hwnd = GetWinHwnd(pFrameWnd->GetClientWindow());
+            ::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
+            ::SetWindowLong(hwnd, GWL_EXSTYLE, dwNewStyle);
+            ::SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
+                           SWP_FRAMECHANGED | SWP_NOACTIVATE |
+                           SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+                           SWP_NOCOPYBITS);
             if (rect)
-                ::GetClientRect((HWND) pFrameWnd->GetClientWindow()->GetHWND(), rect);
-            return TRUE;
-        }
-    }
-    return FALSE;
-#else
-    return FALSE;
-#endif
-}
+                ::GetClientRect(hwnd, rect);
 
-bool wxMDIChildFrame::MSWOnWindowPosChanging(void *pos)
-{
-    WINDOWPOS *lpPos = (WINDOWPOS *)pos;
-#if defined(__WIN95__)
-    if (!(lpPos->flags & SWP_NOSIZE))
-    {
-        RECT rectClient;
-        DWORD dwExStyle = ::GetWindowLong((HWND) GetHWND(), GWL_EXSTYLE);
-        DWORD dwStyle = ::GetWindowLong((HWND) GetHWND(), GWL_STYLE);
-        if (ResetWindowStyle((void *) & rectClient) && (dwStyle & WS_MAXIMIZE))
-        {
-            ::AdjustWindowRectEx(&rectClient, dwStyle, FALSE, dwExStyle);
-            lpPos->x = rectClient.left;
-            lpPos->y = rectClient.top;
-            lpPos->cx = rectClient.right - rectClient.left;
-            lpPos->cy = rectClient.bottom - rectClient.top;
-        }
-        wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
-        if (pFrameWnd && pFrameWnd->GetToolBar())
-        {
-            pFrameWnd->GetToolBar()->Refresh();
+            return TRUE;
         }
     }
-#endif
+#endif // Win95
 
     return FALSE;
 }
 
-// Client window
-wxMDIClientWindow::wxMDIClientWindow()
-{
-    m_scrollX = 0;
-    m_scrollY = 0;
-}
-
-wxMDIClientWindow::~wxMDIClientWindow()
-{
-}
+// ===========================================================================
+// wxMDIClientWindow: the window of predefined (by Windows) class which
+// contains the child frames
+// ===========================================================================
 
 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
 {
-  m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
+    m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
 
-  CLIENTCREATESTRUCT ccs;
-  m_windowStyle = style;
-  m_parent = parent;
+    CLIENTCREATESTRUCT ccs;
+    m_windowStyle = style;
+    m_parent = parent;
 
-  ccs.hWindowMenu = (HMENU) parent->GetWindowMenu();
-  ccs.idFirstChild = wxFIRST_MDI_CHILD;
+    ccs.hWindowMenu = (HMENU)parent->GetWindowMenu();
+    ccs.idFirstChild = wxFIRST_MDI_CHILD;
 
-  DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN ;
-  if ( parent->GetWindowStyleFlag() & wxHSCROLL )
-    msStyle |= WS_HSCROLL;
-  if ( parent->GetWindowStyleFlag() & wxVSCROLL )
-    msStyle |= WS_VSCROLL ;
+    DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN;
+    if ( style & wxHSCROLL )
+        msStyle |= WS_HSCROLL;
+    if ( style & wxVSCROLL )
+        msStyle |= WS_VSCROLL;
 
 #if defined(__WIN95__)
-  DWORD exStyle = WS_EX_CLIENTEDGE;
+    DWORD exStyle = WS_EX_CLIENTEDGE;
 #else
-  DWORD exStyle = 0;
+    DWORD exStyle = 0;
 #endif
 
-  wxWndHook = this;
-  m_hWnd = (WXHWND) ::CreateWindowEx(exStyle, "mdiclient", NULL,
-                msStyle, 0, 0, 0, 0, (HWND) parent->GetHWND(), NULL,
-                wxGetInstance(), (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
-  SubclassWin(m_hWnd);
-  wxWndHook = NULL;
+    wxWndHook = this;
+    m_hWnd = (WXHWND)::CreateWindowEx
+                       (
+                        exStyle,
+                        "MDICLIENT",
+                        NULL,
+                        msStyle,
+                        0, 0, 0, 0,
+                        GetWinHwnd(parent),
+                        NULL,
+                        wxGetInstance(),
+                        (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
+    if ( !m_hWnd )
+    {
+        wxLogLastError("CreateWindowEx(MDI client)");
 
-  return (m_hWnd != 0) ;
-}
+        return FALSE;
+    }
 
-// Window procedure: here for debugging purposes
-long wxMDIClientWindow::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
-{
-    return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
-//    return MSWDefWindowProc(nMsg, wParam, lParam);
-}
+    SubclassWin(m_hWnd);
+    wxWndHook = NULL;
 
-long wxMDIClientWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
-{
-    if ( MSWGetOldWndProc() != 0)
-          return ::CallWindowProc(CASTWNDPROC MSWGetOldWndProc(), (HWND) GetHWND(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
-    else
-        return ::DefWindowProc((HWND) m_hWnd, (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
+    return TRUE;
 }
 
 // Explicitly call default scroll behaviour
@@ -1112,5 +1117,73 @@ void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
     else
         m_scrollY = event.GetPosition(); // Always returns zero!
 
-    Default();
+    event.Skip();
+}
+
+// ---------------------------------------------------------------------------
+// non member functions
+// ---------------------------------------------------------------------------
+
+static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow)
+{
+    ::SendMessage(GetWinHwnd(win), WM_MDISETMENU,
+#ifdef __WIN32__
+                  (WPARAM)hmenuFrame, (LPARAM)hmenuWindow);
+#else
+                  0, MAKELPARAM(hmenuFrame, hmenuWindow));
+#endif
+
+    // update menu bar of the parent window
+    wxWindow *parent = win->GetParent();
+    wxCHECK_RET( parent, "MDI client without parent frame? weird..." );
+
+    ::DrawMenuBar(GetWinHwnd(parent));
+}
+
+static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
+{
+    // Try to insert Window menu in front of Help, otherwise append it.
+    HMENU hmenu = (HMENU)menu;
+    int N = GetMenuItemCount(hmenu);
+    bool success = FALSE;
+    for ( int i = 0; i < N; i++ )
+    {
+        char buf[256];
+        int chars = GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION);
+        if ( chars == 0 )
+        {
+            wxLogLastError("GetMenuString");
+
+            continue;
+        }
+
+        if ( wxStripMenuCodes(wxString(buf)).IsSameAs(_("Help")) )
+        {
+            success = TRUE;
+            ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
+                         (UINT)subMenu, "&Window");
+            break;
+        }
+    }
+
+    if ( !success )
+    {
+        ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, _("&Window"));
+    }
+
+    MDISetMenu(win, hmenu, subMenu);
+}
+
+static UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
+                         WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact)
+{
+#ifdef __WIN32__
+    *activate = TRUE;
+    *hwndAct = (WXHWND)lParam;
+    *hwndDeact = (WXHWND)wParam;
+#else // Win16
+    *activate = (WXWORD)wParam;
+    *hwndAct = (WXHWND)LOWORD(lParam);
+    *hwndDeact = (WXHWND)HIWORD(lParam);
+#endif // Win32/Win16
 }
index 2e56379a77e7e1e2048108112852d6dfba93b71a..7d926f6ee2d4556acba92709578d664727948540 100644 (file)
@@ -145,6 +145,67 @@ void wxMenu::Append(wxMenuItem *pItem)
 {
     wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" );
 
+    // check for accelerators: they are given after '\t'
+    wxString label = pItem->GetName();
+    int posTab = label.Find('\t');
+    if ( posTab != wxNOT_FOUND ) {
+        // parse the accelerator string
+        int keyCode = 0;
+        int accelFlags = wxACCEL_NORMAL;
+        wxString current;
+        for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) {
+            if ( (label[n] == '+') || (label[n] == '-') ) {
+                if ( current == _("ctrl") )
+                    accelFlags |= wxACCEL_CTRL;
+                else if ( current == _("alt") )
+                    accelFlags |= wxACCEL_ALT;
+                else if ( current == _("shift") )
+                    accelFlags |= wxACCEL_SHIFT;
+                else {
+                    wxLogDebug(_T("Unknown accel modifier: '%s'"),
+                               current.c_str());
+                }
+
+                current.Empty();
+            }
+            else {
+                current += wxTolower(label[n]);
+            }
+        }
+
+        if ( current.IsEmpty() ) {
+            wxLogDebug(_T("No accel key found, accel string ignored."));
+        }
+        else {
+            if ( current.Len() == 1 ) {
+                // it's a letter
+                keyCode = wxToupper(current[0]);
+            }
+            else {
+                // it should be a function key
+                if ( current[0] == 'f' && isdigit(current[1]) &&
+                     (current.Len() == 2 ||
+                     (current.Len() == 3 && isdigit(current[2]))) ) {
+                    int n;
+                    sscanf(current.c_str() + 1, "%d", &n);
+
+                    keyCode = VK_F1 + n - 1;
+                }
+                else {
+                    wxLogDebug(_T("Unreckognized accel key '%s', accel "
+                                  "string ignored."), current.c_str());
+                }
+            }
+        }
+
+        if ( keyCode ) {
+            // do add an entry
+            m_accelKeyCodes.Add(keyCode);
+            m_accelFlags.Add(accelFlags);
+            m_accelIds.Add(pItem->GetId());
+        }
+    }
+
     UINT flags = 0;
 
     // if "Break" has just been called, insert a menu break before this item
@@ -190,13 +251,7 @@ void wxMenu::Append(wxMenuItem *pItem)
     {
         // menu is just a normal string (passed in data parameter)
         flags |= MF_STRING;
-        pData = pItem->GetName();
-    }
-
-    // visually select the menu title
-    if ( id == idMenuTitle )
-    {
-        // TODO use SetMenuItemInfo(MFS_DEFAULT) to put it in bold face
+        pData = label;
     }
 
     if ( !::AppendMenu(GetHMENU(), flags, id, pData) )
@@ -205,6 +260,22 @@ void wxMenu::Append(wxMenuItem *pItem)
     }
     else
     {
+#ifdef __WIN32__
+        if ( id == idMenuTitle )
+        {
+            // visually select the menu title
+            MENUITEMINFO mii;
+            mii.cbSize = sizeof(mii);
+            mii.fMask = MIIM_STATE;
+            mii.fState = MFS_DEFAULT;
+
+            if ( !SetMenuItemInfo(GetHMENU(), (unsigned)id, FALSE, &mii) )
+            {
+                wxLogLastError("SetMenuItemInfo");
+            }
+        }
+#endif // __WIN32__
+
         m_menuItems.Append(pItem);
         m_noItems++;
     }
@@ -272,6 +343,23 @@ void wxMenu::Delete(int id)
     delete item;
 }
 
+// ---------------------------------------------------------------------------
+// accelerator helpers
+// ---------------------------------------------------------------------------
+
+// create the wxAcceleratorEntries for our accels and put them into provided
+// array - return the number of accels we have
+size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
+{
+    size_t count = GetAccelCount();
+    for ( size_t n = 0; n < count; n++ )
+    {
+        (*accels++).Set(m_accelFlags[n], m_accelKeyCodes[n], m_accelIds[n]);
+    }
+
+    return count;
+}
+
 // ---------------------------------------------------------------------------
 // wxMenu functions implemented in wxMenuItem
 // ---------------------------------------------------------------------------
@@ -395,7 +483,7 @@ void wxMenu::SetTitle(const wxString& label)
         }
     }
 
-#ifndef __WIN16__
+#ifdef __WIN32__
     // put the title string in bold face
     if ( !m_title.IsEmpty() )
     {
@@ -438,7 +526,7 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id)
     return TRUE;
 }
 
-void wxMenu::ProcessCommand(wxCommandEvent & event)
+bool wxMenu::ProcessCommand(wxCommandEvent & event)
 {
     bool processed = FALSE;
 
@@ -462,6 +550,8 @@ void wxMenu::ProcessCommand(wxCommandEvent & event)
     wxWindow *win = GetInvokingWindow();
     if ( !processed && win )
         processed = win->GetEventHandler()->ProcessEvent(event);
+
+    return processed;
 }
 
 // ---------------------------------------------------------------------------
@@ -917,6 +1007,34 @@ void wxMenuBar::Delete(wxMenu * menu, int i)
     }
 }
 
+void wxMenuBar::Attach(wxFrame *frame)
+{
+    wxASSERT_MSG( !m_menuBarFrame, _T("menubar already attached!") );
+
+    m_menuBarFrame = frame;
+
+    // create the accel table - we consider that the toolbar construction is
+    // finished
+    size_t nAccelCount = 0;
+    int i;
+    for ( i = 0; i < m_menuCount; i++ )
+    {
+        nAccelCount += m_menus[i]->GetAccelCount();
+    }
+
+    wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount];
+
+    nAccelCount = 0;
+    for ( i = 0; i < m_menuCount; i++ )
+    {
+        nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]);
+    }
+
+    m_accelTable = wxAcceleratorTable(nAccelCount, accelEntries);
+
+    delete [] accelEntries;
+}
+
 // ---------------------------------------------------------------------------
 // wxMenuBar searching for menu items
 // ---------------------------------------------------------------------------
index 32d2b0859a669c93583a995e68ccbd5614a8a41d..e039ec75d029adf299333bec5870cb8646d77894 100644 (file)
 #include "wx/menuitem.h"
 #include "wx/log.h"
 
-#include <windows.h>
-
-#ifdef GetClassInfo
-    #undef GetClassInfo
-#endif
-
-#ifdef GetClassName
-    #undef GetClassName
-#endif
+#include "wx/msw/private.h"
 
 // ---------------------------------------------------------------------------
 // convenience macro
index 4a7b28900fcd01cb4e7c4d5c5c8efa167e6c3136..635537b662cf03bb1054b9f9bb95d73869e5224e 100644 (file)
@@ -202,10 +202,14 @@ void wxMetafileDC::GetTextExtent(const wxString& string, long *x, long *y,
 
   ReleaseDC(NULL, dc);
 
-  *x = XDEV2LOGREL(sizeRect.cx);
-  *y = YDEV2LOGREL(sizeRect.cy);
-  if (descent) *descent = tm.tmDescent;
-  if (externalLeading) *externalLeading = tm.tmExternalLeading;
+  if ( x )
+      *x = sizeRect.cx;
+  if ( y )
+    *y = sizeRect.cy;
+  if ( descent )
+      *descent = tm.tmDescent;
+  if ( externalLeading )
+      *externalLeading = tm.tmExternalLeading;
 }
 
 wxMetafile *wxMetafileDC::Close(void)
index eed57498e9bc3df494b873884fe2d8254a0f5c1b..90e4450857fb0c6c2323aabd62c543b8014648ab 100644 (file)
   BEGIN_EVENT_TABLE(wxNotebook, wxControl)
     EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
 
-    EVT_SIZE(wxNotebook::OnSize)
-    EVT_ERASE_BACKGROUND(wxNotebook::OnEraseBackground)
+    EVT_WINDOW_CREATE(wxNotebook::OnWindowCreate)
+
     EVT_SET_FOCUS(wxNotebook::OnSetFocus)
+
     EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
   END_EVENT_TABLE()
 
@@ -164,7 +165,6 @@ bool wxNotebook::Create(wxWindow *parent,
   }
 
   // Not all compilers recognise SetWindowFont
-//  SetWindowFont((HWND)m_hwnd, ::GetStockObject(DEFAULT_GUI_FONT), FALSE);
   ::SendMessage((HWND) m_hwnd, WM_SETFONT,
                   (WPARAM)::GetStockObject(DEFAULT_GUI_FONT),TRUE);
 
@@ -272,6 +272,14 @@ void wxNotebook::SetImageList(wxImageList* imageList)
   TabCtrl_SetImageList(m_hwnd, (HIMAGELIST)imageList->GetHIMAGELIST());
 }
 
+
+// Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH
+// style.
+void wxNotebook::SetTabSize(const wxSize& sz)
+{
+    ::SendMessage(GetHwnd(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y));
+}
+
 // ----------------------------------------------------------------------------
 // wxNotebook operations
 // ----------------------------------------------------------------------------
@@ -371,9 +379,12 @@ bool wxNotebook::InsertPage(int nPage,
     m_nSelection = 0;
 
   // don't show pages by default (we'll need to adjust their size first)
-  HWND hwnd = (HWND)pPage->GetHWND();
+  HWND hwnd = GetWinHwnd(pPage);
   SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE);
 
+  // this updates internal flag too - otherwise it will get out of sync
+  pPage->Show(FALSE);
+
   return TRUE;
 }
 
@@ -381,7 +392,7 @@ bool wxNotebook::InsertPage(int nPage,
 // wxNotebook callbacks
 // ----------------------------------------------------------------------------
 
-void wxNotebook::OnSize(wxSizeEvent& event)
+void wxNotebook::OnWindowCreate(wxWindowCreateEvent& event)
 {
   // make sure the current page is shown and has focus (it's useful because all
   // pages are created invisible initially)
@@ -459,11 +470,6 @@ bool wxNotebook::DoPhase(int /* nPhase */)
   return TRUE;
 }
 
-void wxNotebook::Command(wxCommandEvent& event)
-{
-  wxFAIL_MSG("wxNotebook::Command not implemented");
-}
-
 bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
 {
   wxNotebookEvent event(wxEVT_NULL, m_windowId);
@@ -538,16 +544,3 @@ void wxNotebook::ChangePage(int nOldSel, int nSel)
   m_nSelection = nSel;
   s_bInsideChangePage = FALSE;
 }
-
-void wxNotebook::OnEraseBackground(wxEraseEvent& event)
-{
-    Default();
-}
-
-// Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH
-// style.
-void wxNotebook::SetTabSize(const wxSize& sz)
-{
-    ::SendMessage((HWND) GetHWND(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y));
-}
-
index 6dff2255e48711cdc2d749bdb7ce86f75259f15a..8a8babc89a9de065bea0cfafe4e2722438ca7a75 100644 (file)
 #endif
 
 #include "wx/log.h"
-#include "wx/msw/ole/automtn.h"
 
-#include <windows.h>
-#include <ole2ver.h>
-#include <oleauto.h>
 #include <math.h>
 #include <time.h>
 
-#ifdef GetObject
-#undef GetObject
-#endif
+#include "wx/msw/ole/automtn.h"
+
+#include "wx/msw/private.h"
+
+#include <ole2ver.h>
+#include <oleauto.h>
 
 // wrapper around BSTR type (by Vadim Zeitlin)
 
index 232d56c290d074e80e4822b807d7aa720b5371dc..15dcd0d3f172fc9054b489004a0216794018ca8f 100644 (file)
 #include "wx/ownerdrw.h"
 #include "wx/menuitem.h"
 
-#include <windows.h>
-
-#ifdef DrawText
-#undef DrawText
-#endif
+#include "wx/msw/private.h"
 
 // ============================================================================
 // implementation of wxOwnerDrawn class
index 57ae304e130041e794ee601e2a7c5bf301396815..c9e98a3dbfa865e1c53a51b53d460f68f6433ea3 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <windows.h>
+
+#include "wx/msw/private.h"
+
 #include <commdlg.h>
 
 #ifndef __WIN32__
     #include <print.h>
 #endif
 
-// Clash with Windows header files
-#ifdef StartDoc
-#undef StartDoc
-#endif
-
 // ---------------------------------------------------------------------------
 // wxWin macros
 // ---------------------------------------------------------------------------
index f636c68dcf81e081bcae5d65794cf2d1e6f486a0..758d8c74f0afe2166ad97e1313e2eb94d862f7da 100644 (file)
 #include "wx/msw/private.h"
 
 #include <stdlib.h>
-#include <windows.h>
-#include <commdlg.h>
 
-// Clash with Windows header files
-#ifdef StartDoc
-    #undef StartDoc
-#endif
+#include "wx/msw/private.h"
+
+#include <commdlg.h>
 
 #ifndef __WIN32__
     #include <print.h>
index 3840beb138b20febbcf19281dcbaf95d7645f4b4..757b479bebb9cc8f092ac32b2472c1fe66a2a31b 100644 (file)
@@ -52,16 +52,16 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hWnd,
                                            UINT message,
                                            WPARAM wParam,
                                            LPARAM lParam);
-#endif
 
 // ---------------------------------------------------------------------------
 // global vars
 // ---------------------------------------------------------------------------
 
 // the pointer to standard radio button wnd proc
-// static WNDPROC s_wndprocRadioBtn = (WNDPROC)NULL;
 static WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL;
 
+#endif // __WIN32__
+
 // ===========================================================================
 // implementation
 // ===========================================================================
@@ -94,9 +94,9 @@ int wxRadioBox::GetNumHor() const
     }
 }
 
-bool wxRadioBox::MSWCommand(WXUINT param, WXWORD id)
+bool wxRadioBox::MSWCommand(WXUINT cmd, WXWORD id)
 {
-    if ( param == BN_CLICKED )
+    if ( cmd == BN_CLICKED )
     {
         int selectedButton = -1;
 
@@ -192,12 +192,6 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title,
 
     bool want3D;
     WXDWORD exStyle = Determine3DEffects(0, &want3D);
-    // Even with extended styles, need to combine with WS_BORDER
-    // for them to look right.
-    /*
-       if ( want3D || wxStyleHasBorder(m_windowStyle) )
-       msStyle |= WS_BORDER;
-     */
 
     HWND hwndParent = (HWND)parent->GetHWND();
 
@@ -249,6 +243,7 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title,
                                       NULL);
 
         m_radioButtons[i] = (WXHWND)hwndBtn;
+
         SubclassRadioButton((WXHWND)hwndBtn);
 
         wxFont& font = GetFont();
@@ -258,7 +253,7 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title,
                         (WPARAM)font.GetResourceHandle(), 0L);
         }
 
-        m_subControls.Append((wxObject *)newId);
+        m_subControls.Append((wxObject *)(WXWORD)newId);
     }
 
     // Create a dummy radio control to end the group.
@@ -281,29 +276,21 @@ wxRadioBox::~wxRadioBox()
     {
         int i;
         for (i = 0; i < m_noItems; i++)
-            DestroyWindow((HWND) m_radioButtons[i]);
+            ::DestroyWindow((HWND)m_radioButtons[i]);
         delete[] m_radioButtons;
     }
+
     if (m_radioWidth)
         delete[] m_radioWidth;
     if (m_radioHeight)
         delete[] m_radioHeight;
-    if (m_hWnd)
-        ::DestroyWindow((HWND) m_hWnd);
-    m_hWnd = 0;
 
 }
 
-wxString wxRadioBox::GetLabel(int item) const
-{
-    GetWindowText((HWND)m_radioButtons[item], wxBuffer, 300);
-    return wxString(wxBuffer);
-}
-
 void wxRadioBox::SetLabel(int item, const wxString& label)
 {
     m_radioWidth[item] = m_radioHeight[item] = -1;
-    SetWindowText((HWND)m_radioButtons[item], (const char *)label);
+    SetWindowText((HWND)m_radioButtons[item], label.c_str());
 }
 
 void wxRadioBox::SetLabel(int item, wxBitmap *bitmap)
@@ -312,18 +299,18 @@ void wxRadioBox::SetLabel(int item, wxBitmap *bitmap)
        m_radioWidth[item] = bitmap->GetWidth() + FB_MARGIN;
        m_radioHeight[item] = bitmap->GetHeight() + FB_MARGIN;
      */
+    wxFAIL_MSG("not implemented");
 }
 
 int wxRadioBox::FindString(const wxString& s) const
 {
-    int i;
-    for (i = 0; i < m_noItems; i++)
+    for (int i = 0; i < m_noItems; i++)
     {
-        GetWindowText((HWND) m_radioButtons[i], wxBuffer, 1000);
-        if (s == wxBuffer)
+        if ( s == wxGetWindowText(m_radioButtons[i]) )
             return i;
     }
-    return -1;
+
+    return wxNOT_FOUND;
 }
 
 void wxRadioBox::SetSelection(int N)
@@ -536,22 +523,6 @@ void wxRadioBox::GetPosition(int *x, int *y) const
     *y = point.y;
 }
 
-wxString wxRadioBox::GetLabel() const
-{
-    if (m_hWnd)
-    {
-        GetWindowText((HWND) m_hWnd, wxBuffer, 300);
-        return wxString(wxBuffer);
-    }
-    else return wxString("");
-}
-
-void wxRadioBox::SetLabel(const wxString& label)
-{
-    if (m_hWnd)
-        SetWindowText((HWND) m_hWnd, label);
-}
-
 void wxRadioBox::SetFocus()
 {
     if (m_noItems > 0)
@@ -566,27 +537,25 @@ void wxRadioBox::SetFocus()
 
 bool wxRadioBox::Show(bool show)
 {
-    m_isShown = show;
-    int cshow;
-    if (show)
-        cshow = SW_SHOW;
-    else
-        cshow = SW_HIDE;
-    if (m_hWnd)
-        ShowWindow((HWND) m_hWnd, cshow);
-    int i;
-    for (i = 0; i < m_noItems; i++)
-        ShowWindow((HWND) m_radioButtons[i], cshow);
+    if ( !wxControl::Show(show) )
+        return FALSE;
+
+    int nCmdShow = show ? SW_SHOW : SW_HIDE;
+    for ( int i = 0; i < m_noItems; i++ )
+    {
+        ::ShowWindow((HWND)m_radioButtons[i], nCmdShow);
+    }
+
     return TRUE;
 }
 
 // Enable a specific button
 void wxRadioBox::Enable(int item, bool enable)
 {
-    if (item<0)
-        wxWindow::Enable(enable);
-    else if (item < m_noItems)
-        ::EnableWindow((HWND) m_radioButtons[item], enable);
+    wxCHECK_RET( item >= 0 && item < m_noItems,
+                 _T("invalid item in wxRadioBox::Enable()") );
+
+    ::EnableWindow((HWND) m_radioButtons[item], enable);
 }
 
 // Enable all controls
@@ -595,8 +564,7 @@ bool wxRadioBox::Enable(bool enable)
     if ( !wxControl::Enable(enable) )
         return FALSE;
 
-    int i;
-    for (i = 0; i < m_noItems; i++)
+    for (int i = 0; i < m_noItems; i++)
         ::EnableWindow((HWND) m_radioButtons[i], enable);
 
     return TRUE;
@@ -605,17 +573,10 @@ bool wxRadioBox::Enable(bool enable)
 // Show a specific button
 void wxRadioBox::Show(int item, bool show)
 {
-    if (item<0)
-        wxRadioBox::Show(show);
-    else if (item < m_noItems)
-    {
-        int cshow;
-        if (show)
-            cshow = SW_SHOW;
-        else
-            cshow = SW_HIDE;
-        ShowWindow((HWND) m_radioButtons[item], cshow);
-    }
+    wxCHECK_RET( item >= 0 && item < m_noItems,
+                 _T("invalid item in wxRadioBox::Show()") );
+
+    ::ShowWindow((HWND)m_radioButtons[item], show ? SW_SHOW : SW_HIDE);
 }
 
 WXHBRUSH wxRadioBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
@@ -639,9 +600,6 @@ WXHBRUSH wxRadioBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
 
     wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
 
-    // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush
-    // has a zero usage count.
-    //  backgroundBrush->RealizeResource();
     return (WXHBRUSH) backgroundBrush->GetResourceHandle();
 }
 
@@ -672,8 +630,11 @@ bool wxRadioBox::ContainsHWND(WXHWND hWnd) const
 {
     int i;
     for (i = 0; i < Number(); i++)
+    {
         if (GetRadioButtons()[i] == hWnd)
             return TRUE;
+    }
+
     return FALSE;
 }
 
@@ -683,36 +644,49 @@ void wxRadioBox::Command (wxCommandEvent & event)
     ProcessCommand (event);
 }
 
-long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+long wxRadioBox::MSWWindowProc(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam)
 {
-    if (nMsg == WM_NCHITTEST)
+    long rc = 0;
+    bool processed = FALSE;
+
+    switch ( msg )
     {
-        int xPos = LOWORD(lParam);  // horizontal position of cursor
-        int yPos = HIWORD(lParam);  // vertical position of cursor
+        case WM_NCHITTEST:
+            {
+                int xPos = LOWORD(lParam);  // horizontal position of cursor
+                int yPos = HIWORD(lParam);  // vertical position of cursor
 
-        ScreenToClient(&xPos, &yPos);
+                ScreenToClient(&xPos, &yPos);
 
-        // Make sure you can drag by the top of the groupbox, but let
-        // other (enclosed) controls get mouse events also
-        if (yPos < 10)
-            return (long)HTCLIENT;
+                // Make sure you can drag by the top of the groupbox, but let
+                // other (enclosed) controls get mouse events also
+                if ( yPos < 10 )
+                {
+                    rc = HTCLIENT;
+                    processed = TRUE;
+                }
+            }
+            break;
     }
 
-    return wxControl::MSWWindowProc(nMsg, wParam, lParam);
+    if ( !processed )
+        rc = wxControl::MSWWindowProc(msg, wParam, lParam);
+
+    return rc;
 }
 
 void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn)
 {
+#ifdef __WIN32__
     HWND hwndBtn = (HWND)hWndBtn;
 
     if ( !s_wndprocRadioBtn )
         s_wndprocRadioBtn = (WXFARPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC);
 
     // No GWL_USERDATA in Win16, so omit this subclassing.
-#ifdef __WIN32__
     ::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc);
     ::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this);
-#endif
+#endif // __WIN32__
 }
 
 void wxRadioBox::SendNotificationEvent()
@@ -797,5 +771,6 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd,
     else
         return 0;
 }
-#endif
+
+#endif // __WIN32__
 
index 77e8db8f11ace8a37fa1200473003546b86539af..a82450f6b3c0b857b9c50c4d2a6927c70fda68f9 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows license
+// Licence:       wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
@@ -32,7 +32,7 @@
 IMPLEMENT_DYNAMIC_CLASS(wxStaticBox, wxControl)
 
 BEGIN_EVENT_TABLE(wxStaticBox, wxControl)
-       EVT_ERASE_BACKGROUND(wxStaticBox::OnEraseBackground)
+    EVT_ERASE_BACKGROUND(wxStaticBox::OnEraseBackground)
 END_EVENT_TABLE()
 
 #endif
@@ -56,9 +56,9 @@ bool wxStaticBox::Create(wxWindow *parent, wxWindowID id,
   SetForegroundColour(parent->GetForegroundColour()) ;
 
   if ( id == -1 )
-       m_windowId = (int)NewControlId();
+      m_windowId = (int)NewControlId();
   else
-       m_windowId = id;
+    m_windowId = id;
 
   int x = pos.x;
   int y = pos.y;
@@ -80,7 +80,7 @@ bool wxStaticBox::Create(wxWindow *parent, wxWindowID id,
   if (want3D)
   {
     Ctl3dSubclassCtl(wx_button);
-         m_useCtl3D = TRUE;
+      m_useCtl3D = TRUE;
   }
 #endif
 
@@ -144,7 +144,7 @@ void wxStaticBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 }
 
 WXHBRUSH wxStaticBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
-                       WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+            WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 {
 #if wxUSE_CTL3D
   if ( m_useCtl3D )
@@ -206,12 +206,14 @@ void wxStaticBox::OnEraseBackground(wxEraseEvent& event)
         ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
   }
   else
-       Default();
+  {
+    event.Skip();
+  }
 }
 
 long wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 {
-       if (nMsg == WM_NCHITTEST)
+    if (nMsg == WM_NCHITTEST)
     {
         int xPos = LOWORD(lParam);  // horizontal position of cursor
         int yPos = HIWORD(lParam);  // vertical position of cursor
@@ -224,6 +226,6 @@ long wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
             return (long)HTCLIENT;
     }
 
-       return wxControl::MSWWindowProc(nMsg, wParam, lParam);
+    return wxControl::MSWWindowProc(nMsg, wParam, lParam);
 }
 
index 3792cd8e25edffa5e638787822b2e1ec7e78b7e8..4c0f0991fd546ac52b9e7b02c4d5f97c9d397f75 100644 (file)
 #include "wx/generic/statusbr.h"
 #include "wx/msw/statbr95.h"
 
-#include  <windows.h>
-#include  <windowsx.h>
+#include "wx/msw/private.h"
+#include <windowsx.h>
 
 #if !defined(__GNUWIN32__) || defined(__TWIN32__)
-#include  <commctrl.h>
-#endif
-
-#ifdef GetClassInfo
-#undef GetClassInfo
-#endif
-
-#ifdef GetClassName
-#undef GetClassName
+#include <commctrl.h>
 #endif
 
 #if wxUSE_NATIVE_STATUSBAR
index e41562b853b99d31fe6db5350014fc0c8769327c..20f1d669f103dca47e13a0be17f9a70b8fce9974 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
-// Licence:    wxWindows license
+// Licence:       wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
 IMPLEMENT_DYNAMIC_CLASS(wxTabCtrl, wxControl)
 
 BEGIN_EVENT_TABLE(wxTabCtrl, wxControl)
-       EVT_SIZE(wxTabCtrl::OnSize)
-       EVT_PAINT(wxTabCtrl::OnPaint)
-       EVT_KILL_FOCUS(wxTabCtrl::OnKillFocus)
-       EVT_MOUSE_EVENTS(wxTabCtrl::OnMouseEvent)
     EVT_SYS_COLOUR_CHANGED(wxTabCtrl::OnSysColourChanged)
 END_EVENT_TABLE()
 #endif
@@ -71,7 +67,7 @@ bool wxTabCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons
   m_imageList = NULL;
 
   m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
-       GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
+      GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
   m_foregroundColour = *wxBLACK ;
 
   SetName(name);
@@ -139,29 +135,20 @@ wxTabCtrl::~wxTabCtrl()
   UnsubclassWin();
 }
 
-void wxTabCtrl::Command(wxCommandEvent& event)
-{
-}
-
-bool wxTabCtrl::MSWCommand(WXUINT cmd, WXWORD id)
-{
-  return FALSE;
-}
-
 bool wxTabCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
-       wxTabEvent event(wxEVT_NULL, m_windowId);
-       wxEventType eventType = wxEVT_NULL;
-       NMHDR* hdr1 = (NMHDR*) lParam;
-       switch ( hdr1->code )
-       {
-               case TCN_SELCHANGE:
-                       eventType = wxEVT_COMMAND_TAB_SEL_CHANGED;
-                       break;
-
-               case TCN_SELCHANGING:
-                       eventType = wxEVT_COMMAND_TAB_SEL_CHANGING;
-                       break;
+    wxTabEvent event(wxEVT_NULL, m_windowId);
+    wxEventType eventType = wxEVT_NULL;
+    NMHDR* hdr1 = (NMHDR*) lParam;
+    switch ( hdr1->code )
+    {
+        case TCN_SELCHANGE:
+            eventType = wxEVT_COMMAND_TAB_SEL_CHANGED;
+            break;
+
+        case TCN_SELCHANGING:
+            eventType = wxEVT_COMMAND_TAB_SEL_CHANGING;
+            break;
 
         case TTN_NEEDTEXT:
         {
@@ -170,27 +157,23 @@ bool wxTabCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 //                ttText->lpszText = (char *) (const char *)tool->m_shortHelpString;
         }
 
-               default :
-                       return wxControl::MSWOnNotify(idCtrl, lParam, result);
-       }
+        default :
+            return wxControl::MSWOnNotify(idCtrl, lParam, result);
+    }
 
-       event.SetEventObject( this );
-       event.SetEventType(eventType);
-       event.SetInt(idCtrl) ;
+    event.SetEventObject( this );
+    event.SetEventType(eventType);
+    event.SetInt(idCtrl) ;
 
-       return ProcessEvent(event);
+    return ProcessEvent(event);
 }
 
 // Responds to colour changes, and passes event on to children.
 void wxTabCtrl::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
     m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
-           GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
-
-    // Remap the buttons
-//    CreateTools();
-
-    Default();
+                                  GetGValue(GetSysColor(COLOR_BTNFACE)),
+                                  GetBValue(GetSysColor(COLOR_BTNFACE)));
 
     Refresh();
 
index fb02e9d4b8b79248c4754e6145e02f5ab6bc6964..3f4d814f84cb57762b4493ad4e6da9a285716b82 100644 (file)
@@ -77,10 +77,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxToolBar95, wxToolBarBase)
 #endif
 
 BEGIN_EVENT_TABLE(wxToolBar95, wxToolBarBase)
-    EVT_SIZE(wxToolBar95::OnSize)
-    EVT_PAINT(wxToolBar95::OnPaint)
     EVT_MOUSE_EVENTS(wxToolBar95::OnMouseEvent)
-    EVT_KILL_FOCUS(wxToolBar95::OnKillFocus)
     EVT_SYS_COLOUR_CHANGED(wxToolBar95::OnSysColourChanged)
 END_EVENT_TABLE()
 
@@ -527,8 +524,6 @@ void wxToolBar95::OnSysColourChanged(wxSysColourChangedEvent& event)
     // Remap the buttons
     CreateTools();
 
-    Default();
-
     Refresh();
 
     // Propagate the event to the non-top-level children
@@ -545,7 +540,7 @@ void wxToolBar95::OnMouseEvent(wxMouseEvent& event)
     }
     else
     {
-        Default();
+        event.Skip();
     }
 }
 
index 8a4f405bd46ff55914601496cf5639e670b0bdf3..7388f2817edec6e29f8058aa170ee5a37c247f7a 100644 (file)
@@ -74,7 +74,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
   EVT_CHAR(wxTextCtrl::OnChar)
   EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
-  EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground)
 
   EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
   EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
@@ -1070,7 +1069,7 @@ WXHBRUSH wxTextCtrl::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
 
 void wxTextCtrl::OnChar(wxKeyEvent& event)
 {
-    switch( event.KeyCode() )
+    switch ( event.KeyCode() )
     {
         case WXK_RETURN:
             if ( !(m_windowStyle & wxTE_MULTILINE) )
@@ -1111,8 +1110,9 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
     // don't just call event.Skip() because this will cause TABs and ENTERs
     // be passed upwards and we don't always want this - instead process it
     // right here
-    Default();
-//    event.Skip();
+
+    // FIXME
+    event.Skip();
 }
 
 long wxTextCtrl::MSWGetDlgCode()
@@ -1135,27 +1135,6 @@ long wxTextCtrl::MSWGetDlgCode()
     return lRc;
 }
 
-void wxTextCtrl::OnEraseBackground(wxEraseEvent& event)
-{
-    if ( m_windowStyle & wxTE_MULTILINE )
-    {
-        // No flicker - only problem is we probably can't change the background
-        Default();
-/*
-        RECT rect;
-        ::GetClientRect((HWND) GetHWND(), &rect);
-
-        HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
-        int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
-
-        ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush);
-        ::DeleteObject(hBrush);
-        ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
-*/
-    }
-//        wxWindow::OnEraseBackground(event);
-}
-
 bool wxTextCtrl::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 {
 /*
index 58d44efaf72b42d4fe09c3a842d9c086737eabe0..1b26944ae7a0dbf86f2e662f2156896bf4c85dfc 100644 (file)
@@ -441,7 +441,7 @@ bool wxThread::IsMain()
 }
 
 #ifdef Yield
-#undef Yield
+    #undef Yield
 #endif
 
 void wxThread::Yield()
index 10ad765ff2e72b95ea6cc149a2f3345bf5f95474..07ff06e610949d6cf23614697a10400d59dd0f1b 100644 (file)
     #include <commctrl.h>
 #endif
 
-#ifdef GetFirstChild
-#undef GetFirstChild
-#endif
-
-#ifdef GetNextChild
-#undef GetNextChild
-#endif
-
-#ifdef GetNextSibling
-#undef GetNextSibling
-#endif
-
-#ifdef GetClassInfo
-#undef GetClassInfo
-#endif
-
 // Bug in headers, sometimes
 #ifndef TVIS_FOCUSED
     #define TVIS_FOCUSED            0x0001
index 8b69fd728cb52759ad3529a1dbaf790da46b499b..697de7232a1197abbf3f91949781baf5b0065ecb 100644 (file)
@@ -853,12 +853,12 @@ wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd)
     return str;
 }
 
-wxWindowID WXDLLEXPORT wxGetWindowId(WXHWND hWnd)
+WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd)
 {
 #ifndef __WIN32__
-    return (wxWindowID)GetWindowWord((HWND)hWnd, GWW_ID);
+    return GetWindowWord((HWND)hWnd, GWW_ID);
 #else // Win32
-    return (wxWindowID)GetWindowLong((HWND)hWnd, GWL_ID);
+    return GetWindowLong((HWND)hWnd, GWL_ID);
 #endif // Win16/32
 }
 
index d398797f0f0fe84cc60dfa031dfe370a623c26d5..de806ac65f173cb53623f1e9ebe067a0db419040 100644 (file)
@@ -58,7 +58,7 @@
 #include "wx/log.h"
 
 #if wxUSE_TOOLTIPS
-#include "wx/tooltip.h"
+    #include "wx/tooltip.h"
 #endif
 
 #include "wx/intl.h"
@@ -80,7 +80,7 @@
 #endif
 
 #if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ )
-#include <commctrl.h>
+    #include <commctrl.h>
 #endif
 
 #ifndef __TWIN32__
     #endif
 #endif
 
-#ifdef GetCharWidth
-#undef GetCharWidth
-#endif
-
-#ifdef FindWindow
-#undef FindWindow
-#endif
-
-#ifdef GetClassName
-#undef GetClassName
-#endif
-
-#ifdef GetClassInfo
-#undef GetClassInfo
-#endif
+#include "wx/msw/winundef.h"
 
 // ---------------------------------------------------------------------------
 // macros
 #endif // GET_X_LPARAM
 
 // ---------------------------------------------------------------------------
+// global variables
 // ---------------------------------------------------------------------------
-#ifdef  __WXDEBUG__
-    const char *wxGetMessageName(int message);
-#endif  //__WXDEBUG__
 
-#define WINDOW_MARGIN 3 // This defines sensitivity of Leave events
+// the last Windows message we got (MT-UNSAFE)
+extern MSG s_currentMsg;
 
 wxMenu *wxCurrentPopupMenu = NULL;
 extern wxList WXDLLEXPORT wxPendingDelete;
+extern char wxCanvasClassName[];
+
+// ---------------------------------------------------------------------------
+// private functions
+// ---------------------------------------------------------------------------
+
+// the window proc for all our windows
+LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
+                                   WPARAM wParam, LPARAM lParam);
+
+#ifdef  __WXDEBUG__
+    const char *wxGetMessageName(int message);
+#endif  //__WXDEBUG__
 
 void wxRemoveHandleAssociation(wxWindow *win);
 void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
 wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 
-#if !USE_SHARED_LIBRARY
-    IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
-#endif
-
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
 
+#if !USE_SHARED_LIBRARY
+    IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
+#endif
+
 BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
     EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
     EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
@@ -149,19 +147,21 @@ END_EVENT_TABLE()
 // implementation
 // ===========================================================================
 
+// ---------------------------------------------------------------------------
+// wxWindow utility functions
+// ---------------------------------------------------------------------------
+
 // Find an item given the MS Windows id
 wxWindow *wxWindow::FindItem(int id) const
 {
-//    if ( !GetChildren() )
-//        return NULL;
-    wxNode *current = GetChildren().First();
+    wxWindowList::Node *current = GetChildren().GetFirst();
     while (current)
     {
-        wxWindow *childWin = (wxWindow *)current->Data();
+        wxWindow *childWin = current->GetData();
 
-        wxWindow *wnd = childWin->FindItem(id) ;
+        wxWindow *wnd = childWin->FindItem(id);
         if ( wnd )
-            return wnd ;
+            return wnd;
 
         if ( childWin->IsKindOf(CLASSINFO(wxControl)) )
         {
@@ -175,30 +175,30 @@ wxWindow *wxWindow::FindItem(int id) const
                     return item;
             }
         }
-        current = current->Next();
+
+        current = current->GetNext();
     }
+
     return NULL;
 }
 
 // Find an item given the MS Windows handle
 wxWindow *wxWindow::FindItemByHWND(WXHWND hWnd, bool controlOnly) const
 {
-//    if ( !GetChildren() )
-//        return NULL;
-    wxNode *current = GetChildren().First();
+    wxWindowList::Node *current = GetChildren().GetFirst();
     while (current)
     {
-        wxObject *obj = (wxObject *)current->Data() ;
+        wxWindow *parent = current->GetData();
+
         // Do a recursive search.
-        wxWindow *parent = (wxWindow *)obj ;
-        wxWindow *wnd = parent->FindItemByHWND(hWnd) ;
+        wxWindow *wnd = parent->FindItemByHWND(hWnd);
         if ( wnd )
-            return wnd ;
+            return wnd;
 
-        if ( (!controlOnly) || obj->IsKindOf(CLASSINFO(wxControl)) )
+        if ( !controlOnly || parent->IsKindOf(CLASSINFO(wxControl)) )
         {
-            wxWindow *item = (wxWindow *)current->Data();
-            if ( (HWND)(item->GetHWND()) == (HWND) hWnd )
+            wxWindow *item = current->GetData();
+            if ( item->GetHWND() == hWnd )
                 return item;
             else
             {
@@ -206,7 +206,8 @@ wxWindow *wxWindow::FindItemByHWND(WXHWND hWnd, bool controlOnly) const
                     return item;
             }
         }
-        current = current->Next();
+
+        current = current->GetNext();
     }
     return NULL;
 }
@@ -217,63 +218,6 @@ bool wxWindow::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
     return FALSE;
 }
 
-#ifdef __WIN95__
-// FIXME: VZ: I'm not sure at all that the order of processing is correct
-bool wxWindow::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
-{
-    LPNMHDR hdr = (LPNMHDR)lParam;
-    HWND hWnd = hdr->hwndFrom;
-    wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd);
-
-    // is this one of our windows?
-    if ( win )
-    {
-        return win->MSWOnNotify(idCtrl, lParam, result);
-    }
-
-    // try all our children
-    wxWindowList::Node *node = GetChildren().GetFirst();
-    while ( node )
-    {
-        wxWindow *child = node->GetData();
-        if ( child->MSWOnNotify(idCtrl, lParam, result) )
-        {
-            return TRUE;
-
-            break;
-        }
-
-        node = node->GetNext();
-    }
-
-    // finally try this window too (catches toolbar case)
-    return MSWOnNotify(idCtrl, lParam, result);
-}
-
-bool wxWindow::MSWOnNotify(int WXUNUSED(idCtrl),
-                           WXLPARAM lParam,
-                           WXLPARAM* WXUNUSED(result))
-{
-#if wxUSE_TOOLTIPS
-    NMHDR* hdr = (NMHDR *)lParam;
-    if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
-    {
-        TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
-        ttt->lpszText = (char *)m_tooltip->GetTip().c_str();
-
-        // processed
-        return TRUE;
-    }
-#endif // wxUSE_TOOLTIPS
-
-    return FALSE;
-}
-#endif // __WIN95__
-
-void wxWindow::PreDelete(WXHDC WXUNUSED(dc))
-{
-}
-
 // ----------------------------------------------------------------------------
 // constructors and such
 // ----------------------------------------------------------------------------
@@ -284,7 +228,7 @@ void wxWindow::Init()
     InitBase();
 
     // MSW specific
-    m_doubleClickAllowed = 0 ;
+    m_doubleClickAllowed = 0;
     m_winCaptured = FALSE;
 
     // caret stuff: initially there is no caret at all
@@ -328,18 +272,16 @@ wxWindow::~wxWindow()
     DestroyChildren();
 
     if ( m_hWnd )
-        ::DestroyWindow((HWND)m_hWnd);
-
-    wxRemoveHandleAssociation(this);
-    m_hWnd = 0;
+    {
+        if ( !::DestroyWindow(GetHwnd()) )
+            wxLogLastError("DestroyWindow");
+    }
 
     // Restore old Window proc, if required and remove hWnd <-> wxWindow
     // association
     UnsubclassWin();
 }
 
-extern char wxCanvasClassName[];
-
 // real construction (Init() must have been called before!)
 bool wxWindow::Create(wxWindow *parent, wxWindowID id,
                       const wxPoint& pos,
@@ -349,6 +291,8 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
 {
     wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" );
 
+    CreateBase(parent, id, pos, size, style, name);
+
     parent->AddChild(this);
 
     DWORD msflags = 0;
@@ -362,7 +306,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
         msflags |= WS_CLIPCHILDREN;
 
     bool want3D;
-    WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
+    WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
 
     // Even with extended styles, need to combine with WS_BORDER
     // for them to look right.
@@ -380,6 +324,10 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
     return TRUE;
 }
 
+// ---------------------------------------------------------------------------
+// basic operations
+// ---------------------------------------------------------------------------
+
 void wxWindow::SetFocus()
 {
     HWND hWnd = GetHwnd();
@@ -387,6 +335,18 @@ void wxWindow::SetFocus()
         ::SetFocus(hWnd);
 }
 
+// Get the window with the focus
+wxWindow *wxWindowBase::FindFocus()
+{
+    HWND hWnd = ::GetFocus();
+    if ( hWnd )
+    {
+        return wxFindWinFromHandle((WXHWND) hWnd);
+    }
+
+    return NULL;
+}
+
 bool wxWindow::Enable(bool enable)
 {
     if ( !wxWindowBase::Enable(enable) )
@@ -399,6 +359,46 @@ bool wxWindow::Enable(bool enable)
     return TRUE;
 }
 
+bool wxWindow::Show(bool show)
+{
+    if ( !wxWindowBase::Show(show) )
+        return FALSE;
+
+    HWND hWnd = GetHwnd();
+    int cshow = show ? SW_SHOW : SW_HIDE;
+    ::ShowWindow(hWnd, cshow);
+
+    if ( show )
+    {
+        BringWindowToTop(hWnd);
+    }
+
+    return TRUE;
+}
+
+// Raise the window to the top of the Z order
+void wxWindow::Raise()
+{
+    ::BringWindowToTop(GetHwnd());
+}
+
+// Lower the window to the bottom of the Z order
+void wxWindow::Lower()
+{
+    ::SetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0,
+                   SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+}
+
+void wxWindow::SetTitle( const wxString& title)
+{
+    SetWindowText(GetHwnd(), title.c_str());
+}
+
+wxString wxWindow::GetTitle() const
+{
+    return wxGetWindowText(GetHWND());
+}
+
 void wxWindow::CaptureMouse()
 {
     HWND hWnd = GetHwnd();
@@ -418,2216 +418,2198 @@ void wxWindow::ReleaseMouse()
     }
 }
 
-#if    wxUSE_DRAG_AND_DROP
-
-void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
+bool wxWindow::SetFont(const wxFont& font)
 {
-    if ( m_dropTarget != 0 ) {
-        m_dropTarget->Revoke(m_hWnd);
-        delete m_dropTarget;
+    if ( !wxWindowBase::SetFont(font) )
+    {
+        // nothing to do
+        return FALSE;
     }
 
-    m_dropTarget = pDropTarget;
-    if ( m_dropTarget != 0 )
-        m_dropTarget->Register(m_hWnd);
-}
+    HWND hWnd = GetHwnd();
+    if ( hWnd != 0 )
+    {
+        WXHANDLE hFont = m_font.GetResourceHandle();
 
-#endif // wxUSE_DRAG_AND_DROP
+        wxASSERT_MSG( hFont, _T("should have valid font") );
 
+        ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, TRUE);
+    }
 
-//old style file-manager drag&drop support
-// I think we should retain the old-style
-// DragAcceptFiles in parallel with SetDropTarget.
-// JACS
-void wxWindow::DragAcceptFiles(bool accept)
+    return TRUE;
+}
+bool wxWindow::SetCursor(const wxCursor& cursor)
 {
+    if ( !wxWindowBase::SetCursor(cursor) )
+    {
+        // no change
+        return FALSE;
+    }
+
+    wxASSERT_MSG( m_cursor.Ok(),
+                  _T("cursor must be valid after call to the base version"));
+
     HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::DragAcceptFiles(hWnd, (BOOL)accept);
-}
 
-// ----------------------------------------------------------------------------
-// tooltips
-// ----------------------------------------------------------------------------
+    // Change the cursor NOW if we're within the correct window
+    POINT point;
+    ::GetCursorPos(&point);
 
-#if wxUSE_TOOLTIPS
+    RECT rect;
+    ::GetWindowRect(hWnd, &rect);
 
-void wxWindow::DoSetToolTip(wxToolTip *tooltip)
-{
-    wxWindowBase::DoSetToolTip(tooltip);
+    if ( ::PtInRect(&rect, point) && !wxIsBusy() )
+        ::SetCursor((HCURSOR)m_cursor.GetHCURSOR());
 
-    if ( m_tooltip )
-        m_tooltip->SetWindow(this);
+    return TRUE;
 }
 
-#endif // wxUSE_TOOLTIPS
-
-// Get total size
-void wxWindow::DoGetSize(int *x, int *y) const
+void wxWindow::WarpPointer (int x_pos, int y_pos)
 {
-    HWND hWnd = GetHwnd();
+    // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
+    // pixel coordinates, relatives to the canvas -- So, we first need to
+    // substract origin of the window, then convert to screen position
+
+    int x = x_pos; int y = y_pos;
     RECT rect;
-    GetWindowRect(hWnd, &rect);
+    GetWindowRect (GetHwnd(), &rect);
 
-    if ( x )
-        *x = rect.right - rect.left;
-    if ( y )
-        *y = rect.bottom - rect.top;
+    x += rect.left;
+    y += rect.top;
+
+    SetCursorPos (x, y);
 }
 
-void wxWindow::DoGetPosition(int *x, int *y) const
+#if WXWIN_COMPATIBILITY
+void wxWindow::MSWDeviceToLogical (float *x, float *y) const
 {
-    HWND hWnd = GetHwnd();
-    HWND hParentWnd = 0;
-    if ( GetParent() )
-        hParentWnd = (HWND) GetParent()->GetHWND();
+}
+#endif // WXWIN_COMPATIBILITY
 
-    RECT rect;
-    GetWindowRect(hWnd, &rect);
+// ---------------------------------------------------------------------------
+// scrolling stuff
+// ---------------------------------------------------------------------------
 
-    // Since we now have the absolute screen coords, if there's a parent we
-    // must subtract its top left corner
-    POINT point;
-    point.x = rect.left;
-    point.y = rect.top;
-    if ( hParentWnd )
+#if WXWIN_COMPATIBILITY
+void wxWindow::SetScrollRange(int orient, int range, bool refresh)
+{
+#if defined(__WIN95__)
+
+    int range1 = range;
+
+    // Try to adjust the range to cope with page size > 1
+    // - a Windows API quirk
+    int pageSize = GetScrollPage(orient);
+    if ( pageSize > 1 && range > 0)
     {
-        ::ScreenToClient(hParentWnd, &point);
+        range1 += (pageSize - 1);
     }
 
-    // We may be faking the client origin. So a window that's really at (0,
-    // 30) may appear (to wxWin apps) to be at (0, 0).
-    if ( GetParent() )
-    {
-        wxPoint pt(GetParent()->GetClientAreaOrigin());
-        point.x -= pt.x;
-        point.y -= pt.y;
+    SCROLLINFO info;
+    int dir;
+
+    if ( orient == wxHORIZONTAL ) {
+        dir = SB_HORZ;
+    } else {
+        dir = SB_VERT;
     }
 
-    if ( x )
-        *x = point.x;
-    if ( y )
-        *y = point.y;
+    info.cbSize = sizeof(SCROLLINFO);
+    info.nPage = pageSize; // Have to set this, or scrollbar goes awry
+    info.nMin = 0;
+    info.nMax = range1;
+    info.nPos = 0;
+    info.fMask = SIF_RANGE | SIF_PAGE;
+
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+        ::SetScrollInfo(hWnd, dir, &info, refresh);
+#else
+    int wOrient;
+    if ( orient == wxHORIZONTAL )
+        wOrient = SB_HORZ;
+    else
+        wOrient = SB_VERT;
+
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+        ::SetScrollRange(hWnd, wOrient, 0, range, refresh);
+#endif
 }
 
-void wxWindow::ScreenToClient(int *x, int *y) const
+void wxWindow::SetScrollPage(int orient, int page, bool refresh)
 {
-    POINT pt;
-    if ( x )
-        pt.x = *x;
-    if ( y )
-        pt.y = *y;
+#if defined(__WIN95__)
+    SCROLLINFO info;
+    int dir;
 
-    HWND hWnd = GetHwnd();
-    ::ScreenToClient(hWnd, &pt);
+    if ( orient == wxHORIZONTAL ) {
+        dir = SB_HORZ;
+        m_xThumbSize = page;
+    } else {
+        dir = SB_VERT;
+        m_yThumbSize = page;
+    }
 
-    if ( x )
-        *x = pt.x;
-    if ( y )
-        *y = pt.y;
+    info.cbSize = sizeof(SCROLLINFO);
+    info.nPage = page;
+    info.nMin = 0;
+    info.fMask = SIF_PAGE;
+
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+        ::SetScrollInfo(hWnd, dir, &info, refresh);
+#else
+    if ( orient == wxHORIZONTAL )
+        m_xThumbSize = page;
+    else
+        m_yThumbSize = page;
+#endif
 }
 
-void wxWindow::ClientToScreen(int *x, int *y) const
+int wxWindow::OldGetScrollRange(int orient) const
 {
-    POINT pt;
-    if ( x )
-        pt.x = *x;
-    if ( y )
-        pt.y = *y;
+    int wOrient;
+    if ( orient == wxHORIZONTAL )
+        wOrient = SB_HORZ;
+    else
+        wOrient = SB_VERT;
 
+#if __WATCOMC__ && defined(__WINDOWS_386__)
+    short minPos, maxPos;
+#else
+    int minPos, maxPos;
+#endif
     HWND hWnd = GetHwnd();
-    ::ClientToScreen(hWnd, &pt);
+    if ( hWnd )
+    {
+        ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
+#if defined(__WIN95__)
+        // Try to adjust the range to cope with page size > 1
+        // - a Windows API quirk
+        int pageSize = GetScrollPage(orient);
+        if ( pageSize > 1 )
+        {
+            maxPos -= (pageSize - 1);
+        }
+#endif
+        return maxPos;
+    }
+    else
+        return 0;
+}
 
-    if ( x )
-        *x = pt.x;
-    if ( y )
-        *y = pt.y;
+int wxWindow::GetScrollPage(int orient) const
+{
+    if ( orient == wxHORIZONTAL )
+        return m_xThumbSize;
+    else
+        return m_yThumbSize;
 }
 
-bool wxWindow::SetCursor(const wxCursor& cursor)
+#endif // WXWIN_COMPATIBILITY
+
+int wxWindow::GetScrollPos(int orient) const
 {
-    if ( !wxWindowBase::SetCursor(cursor) )
+    int wOrient;
+    if ( orient == wxHORIZONTAL )
+        wOrient = SB_HORZ;
+    else
+        wOrient = SB_VERT;
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
     {
-        // no change
-        return FALSE;
+        return ::GetScrollPos(hWnd, wOrient);
     }
+    else
+        return 0;
+}
 
-    wxASSERT_MSG( m_cursor.Ok(),
-                  _T("cursor must be valid after call to the base version"));
+// This now returns the whole range, not just the number
+// of positions that we can scroll.
+int wxWindow::GetScrollRange(int orient) const
+{
+    int wOrient;
+    if ( orient == wxHORIZONTAL )
+        wOrient = SB_HORZ;
+    else
+        wOrient = SB_VERT;
 
+#if __WATCOMC__ && defined(__WINDOWS_386__)
+    short minPos, maxPos;
+#else
+    int minPos, maxPos;
+#endif
     HWND hWnd = GetHwnd();
+    if ( hWnd )
+    {
+        ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
+#if defined(__WIN95__)
+        // Try to adjust the range to cope with page size > 1
+        // - a Windows API quirk
+        int pageSize = GetScrollThumb(orient);
+        if ( pageSize > 1 )
+        {
+            maxPos -= (pageSize - 1);
+        }
+        // October 10th: new range concept.
+        maxPos += pageSize;
+#endif
 
-    // Change the cursor NOW if we're within the correct window
-    POINT point;
-    ::GetCursorPos(&point);
-
-    RECT rect;
-    ::GetWindowRect(hWnd, &rect);
-
-    if ( ::PtInRect(&rect, point) && !wxIsBusy() )
-        ::SetCursor((HCURSOR)m_cursor.GetHCURSOR());
-
-    return TRUE;
+        return maxPos;
+    }
+    else
+        return 0;
 }
 
-// Get size *available for subwindows* i.e. excluding menu bar etc.
-void wxWindow::DoGetClientSize(int *x, int *y) const
+int wxWindow::GetScrollThumb(int orient) const
 {
-    HWND hWnd = GetHwnd();
-    RECT rect;
-    ::GetClientRect(hWnd, &rect);
-    if ( x )
-        *x = rect.right;
-    if ( y )
-        *y = rect.bottom;
+    if ( orient == wxHORIZONTAL )
+        return m_xThumbSize;
+    else
+        return m_yThumbSize;
 }
 
-void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
 {
-    int currentX, currentY;
-    GetPosition(&currentX, &currentY);
-    int currentW,currentH;
-    GetSize(&currentW, &currentH);
-
-    if ( x == currentX && y == currentY && width == currentW && height == currentH )
-        return;
+#if defined(__WIN95__)
+    SCROLLINFO info;
+    int dir;
 
-    int actualWidth = width;
-    int actualHeight = height;
-    int actualX = x;
-    int actualY = y;
-    if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
-        actualX = currentX;
-    if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
-        actualY = currentY;
+    if ( orient == wxHORIZONTAL ) {
+        dir = SB_HORZ;
+    } else {
+        dir = SB_VERT;
+    }
 
-    AdjustForParentClientOrigin(actualX, actualY, sizeFlags);
+    info.cbSize = sizeof(SCROLLINFO);
+    info.nPage = 0;
+    info.nMin = 0;
+    info.nPos = pos;
+    info.fMask = SIF_POS;
 
-    if ( width == -1 )
-        actualWidth = currentW ;
-    if ( height == -1 )
-        actualHeight = currentH ;
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+        ::SetScrollInfo(hWnd, dir, &info, refresh);
+#else
+    int wOrient;
+    if ( orient == wxHORIZONTAL )
+        wOrient = SB_HORZ;
+    else
+        wOrient = SB_VERT;
 
     HWND hWnd = GetHwnd();
     if ( hWnd )
-        MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE);
+        ::SetScrollPos(hWnd, wOrient, pos, refresh);
+#endif
 }
 
-void wxWindow::DoSetClientSize(int width, int height)
+// New function that will replace some of the above.
+void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
+                            int range, bool refresh)
 {
-    wxWindow *parent = GetParent();
-    HWND hWnd = GetHwnd();
-    HWND hParentWnd = (HWND) 0;
-    if ( parent )
-        hParentWnd = (HWND) parent->GetHWND();
+#if defined(__WIN95__)
+    int oldRange = range - thumbVisible;
 
-    RECT rect;
-    ::GetClientRect(hWnd, &rect);
+    int range1 = oldRange;
 
-    RECT rect2;
-    GetWindowRect(hWnd, &rect2);
+    // Try to adjust the range to cope with page size > 1
+    // - a Windows API quirk
+    int pageSize = thumbVisible;
+    if ( pageSize > 1 && range > 0)
+    {
+        range1 += (pageSize - 1);
+    }
 
-    // Find the difference between the entire window (title bar and all)
-    // and the client area; add this to the new client size to move the
-    // window
-    int actual_width = rect2.right - rect2.left - rect.right + width;
-    int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
-
-    // If there's a parent, must subtract the parent's top left corner
-    // since MoveWindow moves relative to the parent
+    SCROLLINFO info;
+    int dir;
 
-    POINT point;
-    point.x = rect2.left;
-    point.y = rect2.top;
-    if ( parent )
-    {
-        ::ScreenToClient(hParentWnd, &point);
+    if ( orient == wxHORIZONTAL ) {
+        dir = SB_HORZ;
+    } else {
+        dir = SB_VERT;
     }
 
-    MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
-
-    wxSizeEvent event(wxSize(width, height), m_windowId);
-    event.SetEventObject(this);
-    GetEventHandler()->ProcessEvent(event);
-}
+    info.cbSize = sizeof(SCROLLINFO);
+    info.nPage = pageSize; // Have to set this, or scrollbar goes awry
+    info.nMin = 0;
+    info.nMax = range1;
+    info.nPos = pos;
+    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
 
-// For implementation purposes - sometimes decorations make the client area
-// smaller
-wxPoint wxWindow::GetClientAreaOrigin() const
-{
-    return wxPoint(0, 0);
-}
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+        ::SetScrollInfo(hWnd, dir, &info, refresh);
+#else
+    int wOrient;
+    if ( orient == wxHORIZONTAL )
+        wOrient = SB_HORZ;
+    else
+        wOrient = SB_VERT;
 
-// Makes an adjustment to the window position (for example, a frame that has
-// a toolbar that it manages itself).
-void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
-{
-    if ( ((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent() )
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
     {
-        wxPoint pt(GetParent()->GetClientAreaOrigin());
-        x += pt.x; y += pt.y;
+        ::SetScrollRange(hWnd, wOrient, 0, range, FALSE);
+        ::SetScrollPos(hWnd, wOrient, pos, refresh);
+    }
+#endif
+    if ( orient == wxHORIZONTAL ) {
+        m_xThumbSize = thumbVisible;
+    } else {
+        m_yThumbSize = thumbVisible;
     }
 }
 
-bool wxWindow::Show(bool show)
+void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
 {
-    if ( !wxWindowBase::Show(show) )
-        return FALSE;
-
-    HWND hWnd = GetHwnd();
-    int cshow = show ? SW_SHOW : SW_HIDE;
-    ::ShowWindow(hWnd, cshow);
-
-    if ( show )
+    RECT rect2;
+    if ( rect )
     {
-        BringWindowToTop(hWnd);
+        rect2.left = rect->x;
+        rect2.top = rect->y;
+        rect2.right = rect->x + rect->width;
+        rect2.bottom = rect->y + rect->height;
     }
 
-    return TRUE;
+    if ( rect )
+        ::ScrollWindow(GetHwnd(), dx, dy, &rect2, NULL);
+    else
+        ::ScrollWindow(GetHwnd(), dx, dy, NULL, NULL);
 }
 
-int wxWindow::GetCharHeight(void) const
+// ---------------------------------------------------------------------------
+// subclassing
+// ---------------------------------------------------------------------------
+
+void wxWindow::SubclassWin(WXHWND hWnd)
 {
-    TEXTMETRIC lpTextMetric;
-    HWND hWnd = GetHwnd();
-    HDC dc = ::GetDC(hWnd);
+    wxASSERT_MSG( !m_oldWndProc, "subclassing window twice?" );
 
-    GetTextMetrics(dc, &lpTextMetric);
-    ::ReleaseDC(hWnd, dc);
+    wxAssociateWinWithHandle((HWND)hWnd, this);
 
-    return lpTextMetric.tmHeight;
+    m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC);
+    SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc);
 }
 
-int wxWindow::GetCharWidth(void) const
+void wxWindow::UnsubclassWin()
 {
-    TEXTMETRIC lpTextMetric;
-    HWND hWnd = GetHwnd();
-    HDC dc = ::GetDC(hWnd);
+    wxRemoveHandleAssociation(this);
 
-    GetTextMetrics(dc, &lpTextMetric);
-    ::ReleaseDC(hWnd, dc);
+    // Restore old Window proc
+    if ( GetHwnd() )
+    {
+        FARPROC farProc = (FARPROC) GetWindowLong(GetHwnd(), GWL_WNDPROC);
+        if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) )
+        {
+            SetWindowLong(GetHwnd(), GWL_WNDPROC, (LONG) m_oldWndProc);
+            m_oldWndProc = 0;
+        }
 
-    return lpTextMetric.tmAveCharWidth;
+        m_hWnd = 0;
+    }
 }
 
-void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
-                             int *descent, int *externalLeading, const wxFont *theFont) const
+// Make a Windows extended style from the given wxWindows window style
+WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders)
 {
-    wxFont *fontToUse = (wxFont *)theFont;
-    if ( !fontToUse )
-        fontToUse = (wxFont *) & m_font;
-
-    HWND hWnd = GetHwnd();
-    HDC dc = ::GetDC(hWnd);
+    WXDWORD exStyle = 0;
+    if ( style & wxTRANSPARENT_WINDOW )
+        exStyle |= WS_EX_TRANSPARENT;
 
-    HFONT fnt = 0;
-    HFONT was = 0;
-    if ( fontToUse && fontToUse->Ok() )
+    if ( !eliminateBorders )
     {
-        fnt = (HFONT)fontToUse->GetResourceHandle();
-        if ( fnt )
-            was = (HFONT) SelectObject(dc,fnt) ;
+        if ( style & wxSUNKEN_BORDER )
+            exStyle |= WS_EX_CLIENTEDGE;
+        if ( style & wxDOUBLE_BORDER )
+            exStyle |= WS_EX_DLGMODALFRAME;
+#if defined(__WIN95__)
+        if ( style & wxRAISED_BORDER )
+            exStyle |= WS_EX_WINDOWEDGE;
+        if ( style & wxSTATIC_BORDER )
+            exStyle |= WS_EX_STATICEDGE;
+#endif
     }
-
-    SIZE sizeRect;
-    TEXTMETRIC tm;
-    GetTextExtentPoint(dc, (const char *)string, (int)string.Length(), &sizeRect);
-    GetTextMetrics(dc, &tm);
-
-    if ( fontToUse && fnt && was )
-        SelectObject(dc,was) ;
-
-    ReleaseDC(hWnd, dc);
-
-    *x = sizeRect.cx;
-    *y = sizeRect.cy;
-    if ( descent ) *descent = tm.tmDescent;
-    if ( externalLeading ) *externalLeading = tm.tmExternalLeading;
-
-    //  if ( fontToUse )
-    //    fontToUse->ReleaseResource();
+    return exStyle;
 }
 
-void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
+// Determines whether native 3D effects or CTL3D should be used,
+// applying a default border style if required, and returning an extended
+// style to pass to CreateWindowEx.
+WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
 {
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
+    // If matches certain criteria, then assume no 3D effects
+    // unless specifically requested (dealt with in MakeExtendedStyle)
+    if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) )
     {
-        if ( rect )
-        {
-            RECT mswRect;
-            mswRect.left = rect->x;
-            mswRect.top = rect->y;
-            mswRect.right = rect->x + rect->width;
-            mswRect.bottom = rect->y + rect->height;
-
-            ::InvalidateRect(hWnd, &mswRect, eraseBack);
-        }
-        else
-            ::InvalidateRect(hWnd, NULL, eraseBack);
+        *want3D = FALSE;
+        return MakeExtendedStyle(m_windowStyle, FALSE);
     }
-}
 
-// ---------------------------------------------------------------------------
-// Main wxWindows window proc and the window proc for wxWindow
-// ---------------------------------------------------------------------------
+    // Determine whether we should be using 3D effects or not.
+    bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
 
-// Hook for new window just as it's being created, when the window isn't yet
-// associated with the handle
-wxWindow *wxWndHook = NULL;
+    // 1) App can specify global 3D effects
+    *want3D = wxTheApp->GetAuto3D();
 
-// Main window proc
-LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-    // trace all messages - useful for the debugging
-#ifdef __WXDEBUG__
-    wxLogTrace(wxTraceMessages, "Processing %s(wParam=%8lx, lParam=%8lx)",
-               wxGetMessageName(message), wParam, lParam);
-#endif // __WXDEBUG__
+    // 2) If the parent is being drawn with user colours, or simple border specified,
+    // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
+    if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) )
+        *want3D = FALSE;
 
-    wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
+    // 3) Control can override this global setting by defining
+    // a border style, e.g. wxSUNKEN_BORDER
+    if ( m_windowStyle & wxSUNKEN_BORDER  )
+        *want3D = TRUE;
 
-    // when we get the first message for the HWND we just created, we associate
-    // it with wxWindow stored in wxWndHook
-    if ( !wnd && wxWndHook )
+    // 4) If it's a special border, CTL3D can't cope so we want a native border
+    if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
+        (m_windowStyle & wxSTATIC_BORDER) )
     {
-        wxAssociateWinWithHandle(hWnd, wxWndHook);
-        wnd = wxWndHook;
-        wxWndHook = NULL;
-        wnd->SetHWND((WXHWND)hWnd);
+        *want3D = TRUE;
+        nativeBorder = TRUE;
     }
 
-    LRESULT rc;
+    // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
+    // effects from extended style
+#if wxUSE_CTL3D
+    if ( *want3D )
+        nativeBorder = FALSE;
+#endif
 
-    // Stop right here if we don't have a valid handle in our wxWindow object.
-    if ( wnd && !wnd->GetHWND() )
-    {
-        // FIXME: why do we do this?
-        wnd->SetHWND((WXHWND) hWnd);
-        rc = wnd->MSWDefWindowProc(message, wParam, lParam );
-        wnd->SetHWND(0);
-    }
-    else
-    {
-        if ( wnd )
-            rc = wnd->MSWWindowProc(message, wParam, lParam);
-        else
-            rc = DefWindowProc( hWnd, message, wParam, lParam );
-    }
+    DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
 
-    return rc;
+    // If we want 3D, but haven't specified a border here,
+    // apply the default border style specified.
+    // TODO what about non-Win95 WIN32? Does it have borders?
+#if defined(__WIN95__) && !wxUSE_CTL3D
+    if ( defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) ||
+        (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
+        exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE;
+#endif
+
+    return exStyle;
 }
 
-long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+#if WXWIN_COMPATIBILITY_2
+// If nothing defined for this, try the parent.
+// E.g. we may be a button loaded from a resource, with no callback function
+// defined.
+void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
 {
-    // did we process the message?
-    bool processed = FALSE;
-
-    // the return value
-    union
-    {
-        bool        allow;
-        long        result;
-        WXHICON     hIcon;
-        WXHBRUSH    hBrush;
-    } rc;
+    if ( GetEventHandler()->ProcessEvent(event)  )
+        return;
+    if ( m_parent )
+        m_parent->GetEventHandler()->OnCommand(win, event);
+}
+#endif // WXWIN_COMPATIBILITY_2
 
-    // for most messages we should return 0 when we do process the message
-    rc.result = 0;
+#if WXWIN_COMPATIBILITY
+wxObject* wxWindow::GetChild(int number) const
+{
+    // Return a pointer to the Nth object in the Panel
+    wxNode *node = GetChildren().First();
+    int n = number;
+    while (node && n--)
+        node = node->Next();
+    if ( node )
+    {
+        wxObject *obj = (wxObject *)node->Data();
+        return(obj);
+    }
+    else
+        return NULL;
+}
+#endif // WXWIN_COMPATIBILITY
 
-    HWND hWnd = GetHwnd();
+// Setup background and foreground colours correctly
+void wxWindow::SetupColours()
+{
+    if ( GetParent() )
+        SetBackgroundColour(GetParent()->GetBackgroundColour());
+}
 
-    switch ( message )
+void wxWindow::OnIdle(wxIdleEvent& event)
+{
+    // Check if we need to send a LEAVE event
+    if ( m_mouseInWindow )
     {
-        case WM_ACTIVATE:
-            {
-#ifdef __WIN32__
-                WORD state = LOWORD(wParam);
-                WORD minimized = HIWORD(wParam);
-                HWND hwnd = (HWND)lParam;
-#else
-                WORD state = (WORD)wParam;
-                WORD minimized = LOWORD(lParam);
-                HWND hwnd = (HWND)HIWORD(lParam);
-#endif
-                processed = MSWOnActivate(state, minimized != 0, (WXHWND)hwnd);
-            }
-            break;
+        POINT pt;
+        ::GetCursorPos(&pt);
+        if ( ::WindowFromPoint(pt) != GetHwnd() )
+        {
+            // Generate a LEAVE event
+            m_mouseInWindow = FALSE;
 
-        case WM_CLOSE:
-            // process this message for any toplevel window
-            if ( !GetParent() )
-            {
-                // if we can't close, tell the system that we processed the
-                // message - otherwise it would close us
-                processed = !Close();
-            }
-            break;
+            // Unfortunately the mouse button and keyboard state may have changed
+            // by the time the OnIdle function is called, so 'state' may be
+            // meaningless.
+            int state = 0;
+            if ( ::GetKeyState(VK_SHIFT) != 0 )
+                state |= MK_SHIFT;
+            if ( ::GetKeyState(VK_CONTROL) != 0 )
+                state |= MK_CONTROL;
 
-        case WM_SETFOCUS:
-            processed = MSWOnSetFocus((WXHWND)(HWND)wParam);
-            break;
+            wxMouseEvent event(wxEVT_LEAVE_WINDOW);
+            InitMouseEvent(event, pt.x, pt.y, state);
 
-        case WM_KILLFOCUS:
-            processed = MSWOnKillFocus((WXHWND)(HWND)wParam);
-            break;
+            (void)GetEventHandler()->ProcessEvent(event);
+        }
+    }
 
-        case WM_CREATE:
-            {
-                bool allow;
-                processed = MSWOnCreate((WXLPCREATESTRUCT)lParam, &allow);
+    UpdateWindowUI();
+}
 
-                // we should return 0 to allow window creation
-                rc.result = !allow;
-            }
-            break;
+// Set this window to be the child of 'parent'.
+bool wxWindow::Reparent(wxWindow *parent)
+{
+    if ( !wxWindowBase::Reparent(parent) )
+        return FALSE;
 
-        case WM_SHOWWINDOW:
-            processed = MSWOnShow(wParam != 0, (int)lParam);
-            break;
+    HWND hWndChild = GetHwnd();
+    HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
 
-        case WM_PAINT:
-            processed = MSWOnPaint();
-            break;
+    ::SetParent(hWndChild, hWndParent);
 
-        case WM_QUERYDRAGICON:
-            processed = MSWOnQueryDragIcon(&rc.hIcon);
-            break;
+    return TRUE;
+}
 
-        case WM_SIZE:
-            processed = MSWOnSize(LOWORD(lParam), HIWORD(lParam), wParam);
-            break;
+void wxWindow::Clear()
+{
+    wxClientDC dc(this);
+    wxBrush brush(GetBackgroundColour(), wxSOLID);
+    dc.SetBackground(brush);
+    dc.Clear();
+}
 
-        case WM_MOVE:
-            processed = HandleMove(LOWORD(lParam), HIWORD(lParam));
-            break;
+void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
+{
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+    {
+        if ( rect )
+        {
+            RECT mswRect;
+            mswRect.left = rect->x;
+            mswRect.top = rect->y;
+            mswRect.right = rect->x + rect->width;
+            mswRect.bottom = rect->y + rect->height;
 
-        case WM_WINDOWPOSCHANGING:
-            processed = MSWOnWindowPosChanging((void *)lParam);
-            break;
+            ::InvalidateRect(hWnd, &mswRect, eraseBack);
+        }
+        else
+            ::InvalidateRect(hWnd, NULL, eraseBack);
+    }
+}
 
-        case WM_MOUSEMOVE:
-        case WM_LBUTTONDOWN:
-        case WM_LBUTTONUP:
-        case WM_LBUTTONDBLCLK:
-        case WM_RBUTTONDOWN:
-        case WM_RBUTTONUP:
-        case WM_RBUTTONDBLCLK:
-        case WM_MBUTTONDOWN:
-        case WM_MBUTTONUP:
-        case WM_MBUTTONDBLCLK:
-            {
-                int x = LOWORD(lParam);
-                int y = HIWORD(lParam);
+// ---------------------------------------------------------------------------
+// drag and drop
+// ---------------------------------------------------------------------------
 
-                processed = MSWOnMouseEvent(message, x, y, wParam);
-            }
-            break;
+#if    wxUSE_DRAG_AND_DROP
 
-        case MM_JOY1MOVE:
-        case MM_JOY2MOVE:
-        case MM_JOY1ZMOVE:
-        case MM_JOY2ZMOVE:
-        case MM_JOY1BUTTONDOWN:
-        case MM_JOY2BUTTONDOWN:
-        case MM_JOY1BUTTONUP:
-        case MM_JOY2BUTTONUP:
-            {
-                int x = LOWORD(lParam);
-                int y = HIWORD(lParam);
+void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
+{
+    if ( m_dropTarget != 0 ) {
+        m_dropTarget->Revoke(m_hWnd);
+        delete m_dropTarget;
+    }
 
-                processed = HandleJoystickEvent(message, x, y, wParam);
-            }
-            break;
+    m_dropTarget = pDropTarget;
+    if ( m_dropTarget != 0 )
+        m_dropTarget->Register(m_hWnd);
+}
 
-        case WM_DESTROY:
-            processed = MSWOnDestroy();
-            break;
+#endif // wxUSE_DRAG_AND_DROP
 
-        case WM_SYSCOMMAND:
-            processed = MSWOnSysCommand(wParam, lParam);
-            break;
+// old style file-manager drag&drop support: we retain the old-style
+// DragAcceptFiles in parallel with SetDropTarget.
+void wxWindow::DragAcceptFiles(bool accept)
+{
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+        ::DragAcceptFiles(hWnd, (BOOL)accept);
+}
 
-        case WM_COMMAND:
-            {
-#ifdef __WIN32__
-                WORD id = LOWORD(wParam);
-                HWND hwnd = (HWND)lParam;
-                WORD cmd = HIWORD(wParam);
-#else
-                WORD id = (WORD)wParam;
-                HWND hwnd = (HWND)LOWORD(lParam) ;
-                WORD cmd = HIWORD(lParam);
-#endif
-                processed = MSWOnCommand(id, cmd, (WXHWND)hwnd);
-            }
-            break;
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
 
-#ifdef __WIN95__
-        case WM_NOTIFY:
-            processed = HandleNotify((int)wParam, lParam, &rc.result);
-            break;
-#endif  // Win95
+#if wxUSE_TOOLTIPS
 
-            // for these messages we must return TRUE if process the message
-        case WM_DRAWITEM:
-        case WM_MEASUREITEM:
-            {
-                int idCtrl = (UINT)wParam;
-                if ( message == WM_DRAWITEM )
-                {
-                    processed = MSWOnDrawItem(idCtrl,
-                                              (WXDRAWITEMSTRUCT *)lParam);
-                }
-                else
-                {
-                    processed = MSWOnMeasureItem(idCtrl,
-                                                 (WXMEASUREITEMSTRUCT *)lParam);
-                }
+void wxWindow::DoSetToolTip(wxToolTip *tooltip)
+{
+    wxWindowBase::DoSetToolTip(tooltip);
 
-                if ( processed )
-                    rc.result = TRUE;
-            }
-            break;
+    if ( m_tooltip )
+        m_tooltip->SetWindow(this);
+}
 
-        case WM_KEYDOWN:
-            // If this has been processed by an event handler,
-            // return 0 now (we've handled it).
-            if ( MSWOnKeyDown((WORD) wParam, lParam) )
-            {
-                processed = TRUE;
+#endif // wxUSE_TOOLTIPS
 
-                break;
-            }
+// ---------------------------------------------------------------------------
+// moving and resizing
+// ---------------------------------------------------------------------------
 
-            // we consider these message "not interesting" to OnChar
-            if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
-            {
-                break;
-            }
+// Get total size
+void wxWindow::DoGetSize(int *x, int *y) const
+{
+    HWND hWnd = GetHwnd();
+    RECT rect;
+    GetWindowRect(hWnd, &rect);
+
+    if ( x )
+        *x = rect.right - rect.left;
+    if ( y )
+        *y = rect.bottom - rect.top;
+}
+
+void wxWindow::DoGetPosition(int *x, int *y) const
+{
+    HWND hWnd = GetHwnd();
+    HWND hParentWnd = 0;
+    if ( GetParent() )
+        hParentWnd = (HWND) GetParent()->GetHWND();
+
+    RECT rect;
+    GetWindowRect(hWnd, &rect);
+
+    // Since we now have the absolute screen coords, if there's a parent we
+    // must subtract its top left corner
+    POINT point;
+    point.x = rect.left;
+    point.y = rect.top;
+    if ( hParentWnd )
+    {
+        ::ScreenToClient(hParentWnd, &point);
+    }
+
+    // We may be faking the client origin. So a window that's really at (0,
+    // 30) may appear (to wxWin apps) to be at (0, 0).
+    if ( GetParent() )
+    {
+        wxPoint pt(GetParent()->GetClientAreaOrigin());
+        point.x -= pt.x;
+        point.y -= pt.y;
+    }
+
+    if ( x )
+        *x = point.x;
+    if ( y )
+        *y = point.y;
+}
 
-            switch ( wParam )
-            {
-                // avoid duplicate messages to OnChar for these ASCII keys: they
-                // will be translated by TranslateMessage() and received in WM_CHAR
-                case VK_ESCAPE:
-                case VK_SPACE:
-                case VK_RETURN:
-                case VK_BACK:
-                case VK_TAB:
-                    break;
+void wxWindow::ScreenToClient(int *x, int *y) const
+{
+    POINT pt;
+    if ( x )
+        pt.x = *x;
+    if ( y )
+        pt.y = *y;
 
-#ifdef VK_APPS
-                // special case of VK_APPS: treat it the same as right mouse
-                // click because both usually pop up a context menu
-                case VK_APPS:
-                    {
-                        // construct the key mask
-                        WPARAM fwKeys = MK_RBUTTON;
-                        if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
-                            fwKeys |= MK_CONTROL;
-                        if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
-                            fwKeys |= MK_SHIFT;
+    HWND hWnd = GetHwnd();
+    ::ScreenToClient(hWnd, &pt);
 
-                        // simulate right mouse button click
-                        DWORD dwPos = ::GetMessagePos();
-                        int x = GET_X_LPARAM(dwPos),
-                            y = GET_Y_LPARAM(dwPos);
+    if ( x )
+        *x = pt.x;
+    if ( y )
+        *y = pt.y;
+}
 
-                        ScreenToClient(&x, &y);
-                        processed = MSWOnMouseEvent(WM_RBUTTONDOWN, x, y, fwKeys);
-                    }
-                    break;
-#endif // VK_APPS
+void wxWindow::ClientToScreen(int *x, int *y) const
+{
+    POINT pt;
+    if ( x )
+        pt.x = *x;
+    if ( y )
+        pt.y = *y;
 
-                case VK_LEFT:
-                case VK_RIGHT:
-                case VK_DOWN:
-                case VK_UP:
-                default:
-                    processed = MSWOnChar((WORD)wParam, lParam);
-            }
-            break;
+    HWND hWnd = GetHwnd();
+    ::ClientToScreen(hWnd, &pt);
 
-        case WM_KEYUP:
-            processed = MSWOnKeyUp((WORD) wParam, lParam);
-            break;
+    if ( x )
+        *x = pt.x;
+    if ( y )
+        *y = pt.y;
+}
 
-        case WM_CHAR: // Always an ASCII character
-            processed = MSWOnChar((WORD)wParam, lParam, TRUE);
-            break;
+// Get size *available for subwindows* i.e. excluding menu bar etc.
+void wxWindow::DoGetClientSize(int *x, int *y) const
+{
+    HWND hWnd = GetHwnd();
+    RECT rect;
+    ::GetClientRect(hWnd, &rect);
+    if ( x )
+        *x = rect.right;
+    if ( y )
+        *y = rect.bottom;
+}
 
-        case WM_HSCROLL:
-        case WM_VSCROLL:
-            {
-#ifdef __WIN32__
-                WORD code = LOWORD(wParam);
-                WORD pos = HIWORD(wParam);
-                HWND control = (HWND)lParam;
-#else
-                WORD code = (WORD)wParam;
-                WORD pos = LOWORD(lParam);
-                HWND control = (HWND)HIWORD(lParam);
-#endif
-                processed = MSWOnScroll(message == WM_HSCROLL ? wxHORIZONTAL
-                                                              : wxVERTICAL,
-                                        code, pos, (WXHWND)control);
-            }
-            break;
+void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+    int currentX, currentY;
+    GetPosition(&currentX, &currentY);
+    int currentW,currentH;
+    GetSize(&currentW, &currentH);
 
-        // CTLCOLOR messages are sent by children to query the parent for their
-        // colors
-#ifdef __WIN32__
-        case WM_CTLCOLORMSGBOX:
-        case WM_CTLCOLOREDIT:
-        case WM_CTLCOLORLISTBOX:
-        case WM_CTLCOLORBTN:
-        case WM_CTLCOLORDLG:
-        case WM_CTLCOLORSCROLLBAR:
-        case WM_CTLCOLORSTATIC:
-            {
-                int nCtlColor = CTLCOLOR_BTN;
-                HWND control = (HWND)lParam;
-                HDC hdc = (HDC)wParam;
+    if ( x == currentX && y == currentY && width == currentW && height == currentH )
+        return;
 
-                processed = MSWOnCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)control,
-                                          nCtlColor, message, wParam, lParam);
-                break;
-            }
-#else // Win16
-        case WM_CTLCOLOR:
-            {
-                HWND control = (HWND)LOWORD(lParam);
-                int nCtlColor = (int)HIWORD(lParam);
-                HDC hdc = (HDC)wParam;
+    int actualWidth = width;
+    int actualHeight = height;
+    int actualX = x;
+    int actualY = y;
+    if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+        actualX = currentX;
+    if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+        actualY = currentY;
 
-                processed = MSWOnCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)control,
-                                          nCtlColor, message, wParam, lParam);
-            }
-            break;
-#endif // Win32/16
+    AdjustForParentClientOrigin(actualX, actualY, sizeFlags);
 
-            // the return value for this message is ignored
-        case WM_SYSCOLORCHANGE:
-            {
-                wxSysColourChangedEvent event;
-                event.SetEventObject(this);
+    if ( width == -1 )
+        actualWidth = currentW;
+    if ( height == -1 )
+        actualHeight = currentH;
 
-                processed = GetEventHandler()->ProcessEvent(event);
-            }
-            break;
+    HWND hWnd = GetHwnd();
+    if ( hWnd )
+        MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE);
+}
 
-        case WM_PALETTECHANGED:
-            processed = MSWOnPaletteChanged((WXHWND) (HWND) wParam);
-            break;
+void wxWindow::DoSetClientSize(int width, int height)
+{
+    wxWindow *parent = GetParent();
+    HWND hWnd = GetHwnd();
+    HWND hParentWnd = (HWND) 0;
+    if ( parent )
+        hParentWnd = (HWND) parent->GetHWND();
 
-        case WM_QUERYNEWPALETTE:
-            processed = MSWOnQueryNewPalette();
-            break;
+    RECT rect;
+    ::GetClientRect(hWnd, &rect);
 
-            // return TRUE if we erase the background
-        case WM_ERASEBKGND:
-                // Prevents flicker when dragging
-                if ( IsIconic(hWnd) ) return 1;
+    RECT rect2;
+    GetWindowRect(hWnd, &rect2);
 
-                if ( !MSWOnEraseBkgnd((WXHDC) (HDC)wParam) )
-                    return 0;
-                else return 1;
-                break;
+    // Find the difference between the entire window (title bar and all)
+    // and the client area; add this to the new client size to move the
+    // window
+    int actual_width = rect2.right - rect2.left - rect.right + width;
+    int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
 
-        case WM_MDIACTIVATE:
-            {
-#ifdef __WIN32__
-                HWND hWndActivate = GET_WM_MDIACTIVATE_HWNDACTIVATE(wParam,lParam);
-                HWND hWndDeactivate = GET_WM_MDIACTIVATE_HWNDDEACT(wParam,lParam);
-                BOOL activate = GET_WM_MDIACTIVATE_FACTIVATE(hWnd,wParam,lParam);
-                processed = MSWOnMDIActivate((long)activate, 
-                                             (WXHWND)hWndActivate,
-                                             (WXHWND)hWndDeactivate);
-#else
-                processed = MSWOnMDIActivate((BOOL)wParam,
-                                             (HWND)LOWORD(lParam),
-                                             (HWND)HIWORD(lParam));
-#endif
-            }
-            break;
+    // If there's a parent, must subtract the parent's top left corner
+    // since MoveWindow moves relative to the parent
 
-        case WM_DROPFILES:
-            processed = MSWOnDropFiles(wParam);
-            break;
+    POINT point;
+    point.x = rect2.left;
+    point.y = rect2.top;
+    if ( parent )
+    {
+        ::ScreenToClient(hParentWnd, &point);
+    }
 
-        case WM_INITDIALOG:
-            wxFAIL_MSG("to fix");
+    MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
 
-            return 0; // MSWOnInitDialog((WXHWND)(HWND)wParam);
+    wxSizeEvent event(wxSize(width, height), m_windowId);
+    event.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(event);
+}
 
-            // we never set focus from here
-            rc.result = FALSE;
-            break;
+// For implementation purposes - sometimes decorations make the client area
+// smaller
+wxPoint wxWindow::GetClientAreaOrigin() const
+{
+    return wxPoint(0, 0);
+}
 
-        case WM_QUERYENDSESSION:
-            processed = MSWOnQueryEndSession(lParam, &rc.allow);
-            break;
+// Makes an adjustment to the window position (for example, a frame that has
+// a toolbar that it manages itself).
+void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
+{
+    if ( ((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent() )
+    {
+        wxPoint pt(GetParent()->GetClientAreaOrigin());
+        x += pt.x; y += pt.y;
+    }
+}
 
-        case WM_ENDSESSION:
-            processed = MSWOnEndSession(wParam != 0, lParam);
-            break;
+// ---------------------------------------------------------------------------
+// text metrics
+// ---------------------------------------------------------------------------
 
-        case WM_GETMINMAXINFO:
-            {
-                MINMAXINFO *info = (MINMAXINFO *)lParam;
-                if ( m_minWidth != -1 )
-                    info->ptMinTrackSize.x = m_minWidth;
-                if ( m_minHeight != -1 )
-                    info->ptMinTrackSize.y = m_minHeight;
-                if ( m_maxWidth != -1 )
-                    info->ptMaxTrackSize.x = m_maxWidth;
-                if ( m_maxHeight != -1 )
-                    info->ptMaxTrackSize.y = m_maxHeight;
-            }
-            break;
+int wxWindow::GetCharHeight() const
+{
+    TEXTMETRIC lpTextMetric;
+    HWND hWnd = GetHwnd();
+    HDC dc = ::GetDC(hWnd);
 
-        case WM_SETCURSOR:
-            // don't set cursor for other windows, only for this one: this
-            // prevents children of this window from getting the same cursor as
-            // the parent has (don't forget that this message is propagated by
-            // default up the window parent-child hierarchy)
-            if ( (HWND)wParam == hWnd )
-            {
-                // don't set cursor when the mouse is not in the client part
-                short nHitTest = LOWORD(lParam);
-                if ( nHitTest == HTCLIENT || nHitTest == HTERROR )
-                {
-                    HCURSOR hcursor = 0;
-                    if ( wxIsBusy() )
-                    {
-                        // from msw\utils.cpp
-                        extern HCURSOR gs_wxBusyCursor;
+    GetTextMetrics(dc, &lpTextMetric);
+    ::ReleaseDC(hWnd, dc);
 
-                        hcursor = gs_wxBusyCursor;
-                    }
-                    else
-                    {
-                        wxCursor *cursor = NULL;
+    return lpTextMetric.tmHeight;
+}
 
-                        if ( m_cursor.Ok() )
-                        {
-                            cursor = &m_cursor;
-                        }
-                        else
-                        {
-                            // from msw\data.cpp
-                            extern wxCursor *g_globalCursor;
+int wxWindow::GetCharWidth() const
+{
+    TEXTMETRIC lpTextMetric;
+    HWND hWnd = GetHwnd();
+    HDC dc = ::GetDC(hWnd);
 
-                            if ( g_globalCursor && g_globalCursor->Ok() )
-                                cursor = g_globalCursor;
-                        }
+    GetTextMetrics(dc, &lpTextMetric);
+    ::ReleaseDC(hWnd, dc);
 
-                        if ( cursor )
-                            hcursor = (HCURSOR)cursor->GetHCURSOR();
-                    }
+    return lpTextMetric.tmAveCharWidth;
+}
 
-                    if ( hcursor )
-                    {
-                        ::SetCursor(hcursor);
+void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
+                             int *descent, int *externalLeading,
+                             const wxFont *theFont) const
+{
+    const wxFont *fontToUse = theFont;
+    if ( !fontToUse )
+        fontToUse = &m_font;
 
-                        // returning TRUE stops the DefWindowProc() from
-                        // further processing this message - exactly what we
-                        // need because we've just set the cursor.
-                        rc.result = TRUE;
-                        processed = TRUE;
-                    }
-                }
-            }
-    }
+    HWND hWnd = GetHwnd();
+    HDC dc = ::GetDC(hWnd);
 
-    if ( !processed )
-    {
-#ifdef __WXDEBUG__
-        wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.",
-                   wxGetMessageName(message));
-#endif // __WXDEBUG__
-        rc.result = MSWDefWindowProc(message, wParam, lParam);
+    HFONT fnt = 0;
+    HFONT hfontOld = 0;
+    if ( fontToUse && fontToUse->Ok() )
+    {
+        fnt = (HFONT)((wxFont *)fontToUse)->GetResourceHandle(); // const_cast
+        if ( fnt )
+            hfontOld = (HFONT)SelectObject(dc,fnt);
     }
 
-    return rc.result;
+    SIZE sizeRect;
+    TEXTMETRIC tm;
+    GetTextExtentPoint(dc, (const char *)string, (int)string.Length(), &sizeRect);
+    GetTextMetrics(dc, &tm);
+
+    if ( fontToUse && fnt && hfontOld )
+        SelectObject(dc, hfontOld);
+
+    ReleaseDC(hWnd, dc);
+
+    if ( x ) *x = sizeRect.cx;
+    if ( y ) *y = sizeRect.cy;
+    if ( descent ) *descent = tm.tmDescent;
+    if ( externalLeading ) *externalLeading = tm.tmExternalLeading;
 }
 
-// Dialog window proc
-LONG APIENTRY _EXPORT
-wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+// ---------------------------------------------------------------------------
+// Caret manipulation
+// ---------------------------------------------------------------------------
+
+void wxWindow::CreateCaret(int w, int h)
 {
-    return 0;
+    m_caretWidth = w;
+    m_caretHeight = h;
+    m_caretEnabled = TRUE;
 }
 
-wxList *wxWinHandleList = NULL;
-wxWindow *wxFindWinFromHandle(WXHWND hWnd)
+void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
 {
-    wxNode *node = wxWinHandleList->Find((long)hWnd);
-    if ( !node )
-        return NULL;
-    return (wxWindow *)node->Data();
+    // Not implemented
 }
 
-void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
+void wxWindow::ShowCaret(bool show)
 {
-    // adding NULL hWnd is (first) surely a result of an error and
-    // (secondly) breaks menu command processing
-    wxCHECK_RET( hWnd != (HWND) NULL, "attempt to add a NULL hWnd to window list" );
-
-    if ( !wxWinHandleList->Find((long)hWnd) )
-        wxWinHandleList->Append((long)hWnd, win);
+    if ( m_caretEnabled )
+    {
+        if ( show )
+            ::ShowCaret(GetHwnd());
+        else
+            ::HideCaret(GetHwnd());
+        m_caretShown = show;
+    }
 }
 
-void wxRemoveHandleAssociation(wxWindow *win)
+void wxWindow::DestroyCaret()
 {
-    wxWinHandleList->DeleteObject(win);
+    m_caretEnabled = FALSE;
 }
 
-// Default destroyer - override if you destroy it in some other way
-// (e.g. with MDI child windows)
-void wxWindow::MSWDestroyWindow()
+void wxWindow::SetCaretPos(int x, int y)
 {
+    ::SetCaretPos(x, y);
 }
 
-bool wxWindow::MSWCreate(int id,
-                         wxWindow *parent,
-                         const char *wclass,
-                         wxWindow *wx_win,
-                         const char *title,
-                         int x,
-                         int y,
-                         int width,
-                         int height,
-                         WXDWORD style,
-                         const char *dialog_template,
-                         WXDWORD extendedStyle)
+void wxWindow::GetCaretPos(int *x, int *y) const
 {
-    int x1 = CW_USEDEFAULT;
-    int y1 = 0;
-    int width1 = CW_USEDEFAULT;
-    int height1 = 100;
-
-    // Find parent's size, if it exists, to set up a possible default
-    // panel size the size of the parent window
-    RECT parent_rect;
-    if ( parent )
-    {
-        ::GetClientRect((HWND) parent->GetHWND(), &parent_rect);
-
-        width1 = parent_rect.right - parent_rect.left;
-        height1 = parent_rect.bottom - parent_rect.top;
-    }
-
-    if ( x > -1 ) x1 = x;
-    if ( y > -1 ) y1 = y;
-    if ( width > -1 ) width1 = width;
-    if ( height > -1 ) height1 = height;
+    POINT point;
+    ::GetCaretPos(&point);
+    *x = point.x;
+    *y = point.y;
+}
 
-    HWND hParent = NULL;
-    if ( parent )
-        hParent = (HWND) parent->GetHWND();
+// ===========================================================================
+// pre/post message processing
+// ===========================================================================
 
-    wxWndHook = this;
+long wxWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+    if ( m_oldWndProc )
+        return ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
+    else
+        return ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam);
+}
 
-    if ( dialog_template )
+bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
+{
+    if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) )
     {
-        m_hWnd = (WXHWND)::CreateDialog(wxGetInstance(),
-                                        dialog_template,
-                                        hParent,
-                                        (DLGPROC)wxDlgProc);
+        // intercept dialog navigation keys
+        MSG *msg = (MSG *)pMsg;
+        bool bProcess = TRUE;
+        if ( msg->message != WM_KEYDOWN )
+            bProcess = FALSE;
 
-        if ( m_hWnd == 0 )
-        {
-            wxLogError(_("Can't find dummy dialog template!\n"
-                         "Check resource include path for finding wx.rc."));
+        if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+            bProcess = FALSE;
 
-            return FALSE;
-        }
+        if ( bProcess )
+        {
+            bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
 
-        ::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE);
-    }
-    else
-    {
-        int controlId = 0;
-        if ( style & WS_CHILD )
-            controlId = id;
+            // WM_GETDLGCODE: ask the control if it wants the key for itself,
+            // don't process it if it's the case (except for Ctrl-Tab/Enter
+            // combinations which are always processed)
+            LONG lDlgCode = 0;
+            if ( !bCtrlDown )
+            {
+                lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+            }
 
-        m_hWnd = (WXHWND)CreateWindowEx(extendedStyle,
-                                        wclass,
-                                        title ? title : "",
-                                        style,
-                                        x1, y1,
-                                        width1, height1,
-                                        hParent, (HMENU)controlId,
-                                        wxGetInstance(),
-                                        NULL);
+            bool bForward = TRUE,
+                 bWindowChange = FALSE;
 
-        if ( !m_hWnd )
-        {
-            wxLogError(_("Can't create window of class %s!\n"
-                         "Possible Windows 3.x compatibility problem?"),
-                       wclass);
+            switch ( msg->wParam ) 
+            {
+                case VK_TAB:
+                    if ( lDlgCode & DLGC_WANTTAB ) {
+                        bProcess = FALSE;
+                    }
+                    else {
+                        // Ctrl-Tab cycles thru notebook pages
+                        bWindowChange = bCtrlDown;
+                        bForward = !(::GetKeyState(VK_SHIFT) & 0x100);
+                    }
+                    break;
 
-            return FALSE;
-        }
-    }
+                case VK_UP:
+                case VK_LEFT:
+                    if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
+                        bProcess = FALSE;
+                    else
+                        bForward = FALSE;
+                    break;
 
-    wxWndHook = NULL;
-    wxWinHandleList->Append((long)m_hWnd, this);
+                case VK_DOWN:
+                case VK_RIGHT:
+                    if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
+                        bProcess = FALSE;
+                    break;
 
-    return TRUE;
-}
+                case VK_RETURN:
+                    {
+                        if ( lDlgCode & DLGC_WANTMESSAGE )
+                        {
+                            // control wants to process Enter itself, don't
+                            // call IsDialogMessage() which would interpret
+                            // it
+                            return FALSE;
+                        }
+#ifndef __WIN16__
+                        wxButton *btnDefault = GetDefaultItem();
+                        if ( btnDefault && !bCtrlDown )
+                        {
+                            // if there is a default button, Enter should
+                            // press it
+                            (void)::SendMessage((HWND)btnDefault->GetHWND(),
+                                                BM_CLICK, 0, 0);
+                            return TRUE;
+                        }
+                        // else: but if there is not it makes sense to make it
+                        //       work like a TAB - and that's what we do.
+                        //       Note that Ctrl-Enter always works this way.
+#endif
+                    }
+                    break;
 
-bool wxWindow::MSWOnCreate(WXLPCREATESTRUCT WXUNUSED(cs), bool *mayCreate)
-{
-    *mayCreate = TRUE;
+                default:
+                    bProcess = FALSE;
+            }
 
-    return TRUE;
-}
+            if ( bProcess )
+            {
+                wxNavigationKeyEvent event;
+                event.SetDirection(bForward);
+                event.SetWindowChange(bWindowChange);
+                event.SetEventObject(this);
 
-bool wxWindow::MSWOnQueryEndSession(long logOff, bool *mayEnd)
-{
-    wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
-    event.SetEventObject(wxTheApp);
-    event.SetCanVeto(TRUE);
-    event.SetLoggingOff(logOff == ENDSESSION_LOGOFF);
+                if ( GetEventHandler()->ProcessEvent(event) )
+                    return TRUE;
+            }
+        }
 
-    bool rc = wxTheApp->ProcessEvent(event);
+        if ( ::IsDialogMessage(GetHwnd(), msg) )
+            return TRUE;
+    }
 
-    if ( rc )
+#if wxUSE_TOOLTIPS
+    if ( m_tooltip )
     {
-        // we may end only if the app didn't veto session closing (double
-        // negation...)
-        *mayEnd = !event.GetVeto();
+        // relay mouse move events to the tooltip control
+        MSG *msg = (MSG *)pMsg;
+        if ( msg->message == WM_MOUSEMOVE )
+            m_tooltip->RelayEvent(pMsg);
     }
+#endif // wxUSE_TOOLTIPS
 
-    return rc;
+    return FALSE;
 }
 
-bool wxWindow::MSWOnEndSession(bool endSession, long logOff)
+bool wxWindow::MSWTranslateMessage(WXMSG* pMsg)
 {
-    // do nothing if the session isn't ending
-    if ( !endSession )
-        return FALSE;
-
-    wxCloseEvent event(wxEVT_END_SESSION, -1);
-    event.SetEventObject(wxTheApp);
-    event.SetCanVeto(FALSE);
-    event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
-    if ( (this == wxTheApp->GetTopWindow()) && // Only send once
-        wxTheApp->ProcessEvent(event))
-    {
-    }
-    return TRUE;
+    return m_acceleratorTable.Ok() &&
+           ::TranslateAccelerator(GetHwnd(),
+                                  GetTableHaccel(m_acceleratorTable),
+                                  (MSG *)pMsg);
 }
 
-bool wxWindow::MSWOnDestroy()
-{
-    // delete our drop target if we've got one
-#if wxUSE_DRAG_AND_DROP
-    if ( m_dropTarget != NULL ) {
-        m_dropTarget->Revoke(m_hWnd);
+// ---------------------------------------------------------------------------
+// message params unpackers (different for Win16 and Win32)
+// ---------------------------------------------------------------------------
 
-        delete m_dropTarget;
-        m_dropTarget = NULL;
-    }
-#endif
+#ifdef __WIN32__
 
-    return TRUE;
+void wxWindow::UnpackCommand(WXWPARAM wParam, WXLPARAM lParam,
+                             WORD *id, WXHWND *hwnd, WORD *cmd)
+{
+    *id = LOWORD(wParam);
+    *hwnd = (WXHWND)lParam;
+    *cmd = HIWORD(wParam);
 }
 
-bool wxWindow::MSWOnMDIActivate(long WXUNUSED(flag),
-                                WXHWND WXUNUSED(activate),
-                                WXHWND WXUNUSED(deactivate))
+void wxWindow::UnpackActivate(WXWPARAM wParam, WXLPARAM lParam,
+                              WXWORD *state, WXWORD *minimized, WXHWND *hwnd)
 {
-    return FALSE;
+    *state = LOWORD(wParam);
+    *minimized = HIWORD(wParam);
+    *hwnd = (WXHWND)lParam;
 }
 
-bool wxWindow::MSWOnActivate(int state, bool WXUNUSED(minimized), WXHWND WXUNUSED(activate))
+void wxWindow::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
+                            WXWORD *code, WXWORD *pos, WXHWND *hwnd)
 {
-    wxActivateEvent event(wxEVT_ACTIVATE,
-                          (state == WA_ACTIVE) || (state == WA_CLICKACTIVE),
-                          m_windowId);
-    event.SetEventObject(this);
+    *code = LOWORD(wParam);
+    *pos = HIWORD(wParam);
+    *hwnd = (WXHWND)lParam;
+}
 
-    return GetEventHandler()->ProcessEvent(event);
+void wxWindow::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
+                              WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
+{
+    *nCtlColor = CTLCOLOR_BTN;
+    *hwnd = (WXHWND)lParam;
+    *hdc = (WXHDC)wParam;
 }
 
-bool wxWindow::MSWOnSetFocus(WXHWND WXUNUSED(hwnd))
+void wxWindow::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
+                                WXWORD *item, WXWORD *flags, WXHMENU *hmenu)
 {
-    // Deal with caret
-    if ( m_caretEnabled && (m_caretWidth > 0) && (m_caretHeight > 0) )
-    {
-        ::CreateCaret(GetHwnd(), NULL, m_caretWidth, m_caretHeight);
-        if ( m_caretShown )
-            ::ShowCaret(GetHwnd());
-    }
+    *item = (WXWORD)wParam;
+    *flags = HIWORD(wParam);
+    *hmenu = (WXHMENU)lParam;
+}
 
-    // panel wants to track the window which was the last to have focus in it
-    wxWindow *parent = GetParent();
-    if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) )
-    {
-        ((wxPanel *)parent)->SetLastFocus(GetId());
-    }
+#else // Win16
 
-    wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
-    event.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(event);
+void wxWindow::UnpackCommand(WXWPARAM wParam, WXLPARAM lParam,
+                             WXWORD *id, WXHWND *hwnd, WXWORD *cmd)
+{
+    *id = (WXWORD)wParam;
+    *hwnd = (WXHWND)LOWORD(lParam);
+    *cmd = HIWORD(lParam);
 }
 
-bool wxWindow::MSWOnKillFocus(WXHWND WXUNUSED(hwnd))
+void wxWindow::UnpackActivate(WXWPARAM wParam, WXLPARAM lParam,
+                              WXWORD *state, WXWORD *minimized, WXHWND *hwnd)
 {
-    // Deal with caret
-    if ( m_caretEnabled )
-    {
-        ::DestroyCaret();
-    }
-
-    wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
-    event.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(event);
+    *state = (WXWORD)wParam;
+    *minimized = LOWORD(lParam);
+    *hwnd = (WXHWND)HIWORD(lParam);
 }
 
-bool wxWindow::MSWOnDropFiles(WXWPARAM wParam)
+void wxWindow::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
+                            WXWORD *code, WXWORD *pos, WXHWND *hwnd)
 {
+    *code = (WXWORD)wParam;
+    *pos = LOWORD(lParam);
+    *hwnd = (WXHWND)HIWORD(lParam);
+}
 
-    HDROP hFilesInfo = (HDROP) wParam;
-    POINT dropPoint;
-    DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
-
-    // Get the total number of files dropped
-    WORD gwFilesDropped = (WORD)DragQueryFile ((HDROP)hFilesInfo,
-        (UINT)-1,
-        (LPSTR)0,
-        (UINT)0);
-
-    wxString *files = new wxString[gwFilesDropped];
-    int wIndex;
-    for (wIndex=0; wIndex < (int)gwFilesDropped; wIndex++)
-    {
-        DragQueryFile (hFilesInfo, wIndex, (LPSTR) wxBuffer, 1000);
-        files[wIndex] = wxBuffer;
-    }
-    DragFinish (hFilesInfo);
-
-    wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
-    event.m_eventObject = this;
-    event.m_pos.x = dropPoint.x; event.m_pos.x = dropPoint.y;
-
-    bool rc = GetEventHandler()->ProcessEvent(event);
-
-    delete[] files;
-
-    return rc;
+void wxWindow::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
+                              WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
+{
+    *control = (WXHWND)LOWORD(lParam);
+    *nCtlColor = (int)HIWORD(lParam);
+    *hdc = (WXHDC)wParam;
 }
 
-bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
+void wxWindow::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
+                                WXWORD *item, WXWORD *flags, WXHMENU *hmenu)
 {
-#if wxUSE_OWNER_DRAWN
-    if ( id == 0 ) {    // is it a menu item?
-        DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct;
-        wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+    *item = (WXWORD)wParam;
+    *flags = LOWORD(lParam);
+    *hmenu = (WXHMENU)HIWORD(lParam);
+}
 
-        // prepare to call OnDrawItem()
-        wxDC dc;
-        dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE);
-        wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top,
-            pDrawStruct->rcItem.right - pDrawStruct->rcItem.left,
-            pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top);
-        return pMenuItem->OnDrawItem(
-            dc, rect,
-            (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction,
-            (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState
-            );
-    }
-#endif  // owner-drawn menus
+#endif // Win32/16
 
-    wxWindow *item = FindItem(id);
-#if wxUSE_DYNAMIC_CLASSES
-    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
-    {
-        return ((wxControl *)item)->MSWOnDraw(itemStruct);
-    }
-    else
-#endif
-        return FALSE;
-}
+// ---------------------------------------------------------------------------
+// Main wxWindows window proc and the window proc for wxWindow
+// ---------------------------------------------------------------------------
 
-bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
+// Hook for new window just as it's being created, when the window isn't yet
+// associated with the handle
+wxWindow *wxWndHook = NULL;
+
+// Main window proc
+LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-#if wxUSE_OWNER_DRAWN
-    if ( id == 0 ) {    // is it a menu item?
-        MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
-        wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+    // trace all messages - useful for the debugging
+#ifdef __WXDEBUG__
+    wxLogTrace(wxTraceMessages, "Processing %s(wParam=%8lx, lParam=%8lx)",
+               wxGetMessageName(message), wParam, lParam);
+#endif // __WXDEBUG__
 
-        return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth,
-            &pMeasureStruct->itemHeight);
-    }
-#endif  // owner-drawn menus
+    wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
 
-    wxWindow *item = FindItem(id);
-#if wxUSE_DYNAMIC_CLASSES
-    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
+    // when we get the first message for the HWND we just created, we associate
+    // it with wxWindow stored in wxWndHook
+    if ( !wnd && wxWndHook )
     {
-        return ((wxControl *)item)->MSWOnMeasure(itemStruct);
+        wxAssociateWinWithHandle(hWnd, wxWndHook);
+        wnd = wxWndHook;
+        wxWndHook = NULL;
+        wnd->SetHWND((WXHWND)hWnd);
     }
-    else
-#endif
-        return FALSE;
-}
 
-bool wxWindow::MSWOnCtlColor(WXHBRUSH *brush,
-                             WXHDC pDC,
-                             WXHWND pWnd,
-                             WXUINT nCtlColor,
-                             WXUINT message,
-                             WXWPARAM wParam,
-                             WXLPARAM lParam)
-{
-    WXHBRUSH hBrush = 0;
+    LRESULT rc;
 
-    if ( nCtlColor == CTLCOLOR_DLG )
+    // Stop right here if we don't have a valid handle in our wxWindow object.
+    if ( wnd && !wnd->GetHWND() )
     {
-        hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
+        // FIXME: why do we do this?
+        wnd->SetHWND((WXHWND) hWnd);
+        rc = wnd->MSWDefWindowProc(message, wParam, lParam );
+        wnd->SetHWND(0);
     }
     else
     {
-        wxControl *item = (wxControl *)FindItemByHWND(pWnd, TRUE);
-        if ( item )
-            hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
+        if ( wnd )
+            rc = wnd->MSWWindowProc(message, wParam, lParam);
+        else
+            rc = DefWindowProc( hWnd, message, wParam, lParam );
     }
 
-    if ( hBrush )
-        *brush = hBrush;
-
-    return hBrush != 0;
-}
-
-// Define for each class of dialog and control
-WXHBRUSH wxWindow::OnCtlColor(WXHDC hDC,
-                              WXHWND hWnd,
-                              WXUINT nCtlColor,
-                              WXUINT message,
-                              WXWPARAM wParam,
-                              WXLPARAM lParam)
-{
-    return (WXHBRUSH)0;
-}
-
-bool wxWindow::MSWOnPaletteChanged(WXHWND hWndPalChange)
-{
-    wxPaletteChangedEvent event(GetId());
-    event.SetEventObject(this);
-    event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
-
-    return GetEventHandler()->ProcessEvent(event);
+    return rc;
 }
 
-bool wxWindow::MSWOnQueryNewPalette()
+long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 {
-    wxQueryNewPaletteEvent event(GetId());
-    event.SetEventObject(this);
-
-    return GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized();
-}
+    // did we process the message?
+    bool processed = FALSE;
 
-// Responds to colour changes: passes event on to children.
-void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event)
-{
-    wxNode *node = GetChildren().First();
-    while ( node )
+    // the return value
+    union
     {
-        // Only propagate to non-top-level windows
-        wxWindow *win = (wxWindow *)node->Data();
-        if ( win->GetParent() )
-        {
-            wxSysColourChangedEvent event2;
-            event.m_eventObject = win;
-            win->GetEventHandler()->ProcessEvent(event2);
-        }
-
-        node = node->Next();
-    }
-}
+        bool        allow;
+        long        result;
+        WXHICON     hIcon;
+        WXHBRUSH    hBrush;
+    } rc;
 
-long wxWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
-{
-    if ( m_oldWndProc )
-        return ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
-    else
-        return ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam);
-}
+    // for most messages we should return 0 when we do process the message
+    rc.result = 0;
 
-bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
-{
-    if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) )
+    switch ( message )
     {
-        // intercept dialog navigation keys
-        MSG *msg = (MSG *)pMsg;
-        bool bProcess = TRUE;
-        if ( msg->message != WM_KEYDOWN )
-            bProcess = FALSE;
+        case WM_CREATE:
+            {
+                bool mayCreate;
+                processed = HandleCreate((WXLPCREATESTRUCT)lParam, &mayCreate);
+                if ( processed )
+                {
+                    // return 0 to allow window creation
+                    rc.result = mayCreate ? 0 : -1;
+                }
+            }
+            break;
 
-        if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
-            bProcess = FALSE;
+        case WM_DESTROY:
+            processed = HandleDestroy();
+            break;
+
+        case WM_MOVE:
+            processed = HandleMove(LOWORD(lParam), HIWORD(lParam));
+            break;
 
-        if ( bProcess )
-        {
-            bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
 
-            // WM_GETDLGCODE: ask the control if it wants the key for itself,
-            // don't process it if it's the case (except for Ctrl-Tab/Enter
-            // combinations which are always processed)
-            LONG lDlgCode = 0;
-            if ( !bCtrlDown )
+        case WM_ACTIVATE:
             {
-                lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+                WXWORD state, minimized;
+                WXHWND hwnd;
+                UnpackActivate(wParam, lParam, &state, &minimized, &hwnd);
+
+                processed = HandleActivate(state, minimized != 0, (WXHWND)hwnd);
             }
+            break;
 
-            bool bForward = TRUE,
-                 bWindowChange = FALSE;
+        case WM_SETFOCUS:
+            processed = HandleSetFocus((WXHWND)(HWND)wParam);
+            break;
 
-            switch ( msg->wParam ) 
-            {
-                case VK_TAB:
-                    if ( lDlgCode & DLGC_WANTTAB ) {
-                        bProcess = FALSE;
-                    }
-                    else {
-                        // Ctrl-Tab cycles thru notebook pages
-                        bWindowChange = bCtrlDown;
-                        bForward = !(::GetKeyState(VK_SHIFT) & 0x100);
-                    }
-                    break;
+        case WM_KILLFOCUS:
+            processed = HandleKillFocus((WXHWND)(HWND)wParam);
+            break;
 
-                case VK_UP:
-                case VK_LEFT:
-                    if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
-                        bProcess = FALSE;
-                    else
-                        bForward = FALSE;
-                    break;
+        case WM_PAINT:
+            processed = HandlePaint();
+            break;
 
-                case VK_DOWN:
-                case VK_RIGHT:
-                    if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
-                        bProcess = FALSE;
-                    break;
+        case WM_CLOSE:
+            // don't let the DefWindowProc() destroy our window - we'll do it
+            // ourselves in ~wxWindow
+            processed = TRUE;
+            rc.result = TRUE;
+            break;
 
-                case VK_RETURN:
-                    {
-                        if ( lDlgCode & DLGC_WANTMESSAGE )
-                        {
-                            // control wants to process Enter itself, don't
-                            // call IsDialogMessage() which would interpret
-                            // it
-                            return FALSE;
-                        }
-#ifndef __WIN16__
-                        wxButton *btnDefault = GetDefaultItem();
-                        if ( btnDefault && !bCtrlDown )
-                        {
-                            // if there is a default button, Enter should
-                            // press it
-                            (void)::SendMessage((HWND)btnDefault->GetHWND(),
-                                                BM_CLICK, 0, 0);
-                            return TRUE;
-                        }
-                        // else: but if there is not it makes sense to make it
-                        //       work like a TAB - and that's what we do.
-                        //       Note that Ctrl-Enter always works this way.
-#endif
-                    }
-                    break;
+        case WM_SHOWWINDOW:
+            processed = HandleShow(wParam != 0, (int)lParam);
+            break;
 
-                default:
-                    bProcess = FALSE;
+        case WM_MOUSEMOVE:
+        case WM_LBUTTONDOWN:
+        case WM_LBUTTONUP:
+        case WM_LBUTTONDBLCLK:
+        case WM_RBUTTONDOWN:
+        case WM_RBUTTONUP:
+        case WM_RBUTTONDBLCLK:
+        case WM_MBUTTONDOWN:
+        case WM_MBUTTONUP:
+        case WM_MBUTTONDBLCLK:
+            {
+                int x = LOWORD(lParam);
+                int y = HIWORD(lParam);
+
+                processed = HandleMouseEvent(message, x, y, wParam);
             }
+            break;
 
-            if ( bProcess )
+        case MM_JOY1MOVE:
+        case MM_JOY2MOVE:
+        case MM_JOY1ZMOVE:
+        case MM_JOY2ZMOVE:
+        case MM_JOY1BUTTONDOWN:
+        case MM_JOY2BUTTONDOWN:
+        case MM_JOY1BUTTONUP:
+        case MM_JOY2BUTTONUP:
             {
-                wxNavigationKeyEvent event;
-                event.SetDirection(bForward);
-                event.SetWindowChange(bWindowChange);
-                event.SetEventObject(this);
+                int x = LOWORD(lParam);
+                int y = HIWORD(lParam);
 
-                if ( GetEventHandler()->ProcessEvent(event) )
-                    return TRUE;
+                processed = HandleJoystickEvent(message, x, y, wParam);
             }
-        }
+            break;
 
-        if ( ::IsDialogMessage(GetHwnd(), msg) )
-            return TRUE;
-    }
+        case WM_SYSCOMMAND:
+            processed = HandleSysCommand(wParam, lParam);
+            break;
 
-#if wxUSE_TOOLTIPS
-    if ( m_tooltip )
-    {
-        // relay mouse move events to the tooltip control
-        MSG *msg = (MSG *)pMsg;
-        if ( msg->message == WM_MOUSEMOVE )
-            m_tooltip->RelayEvent(pMsg);
-    }
-#endif // wxUSE_TOOLTIPS
+        case WM_COMMAND:
+            {
+                WORD id, cmd;
+                WXHWND hwnd;
+                UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
 
-/* This code manages to disable character input completely. Nice one!
- * Probably because the dialog is requesting all char input. Or,
- * it gets called by non-dialog windows.
+                processed = HandleCommand(id, cmd, hwnd);
+            }
+            break;
 
-    // In case we don't have wxTAB_TRAVERSAL style on.
-    // If we don't call this, we may never process Enter correctly.
-    if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) == 0 )
-    {
-        MSG *msg = (MSG *)pMsg;
-        if ( ::IsDialogMessage(GetHwnd(), msg) )
-            return TRUE;
-    }
-*/
-    return FALSE;
-}
+#ifdef __WIN95__
+        case WM_NOTIFY:
+            processed = HandleNotify((int)wParam, lParam, &rc.result);
+            break;
+#endif  // Win95
 
-bool wxWindow::MSWTranslateMessage(WXMSG* pMsg)
-{
-    if ( m_acceleratorTable.Ok( ) &&
-        ::TranslateAccelerator(GetHwnd(), (HACCEL) m_acceleratorTable.GetHACCEL(), (MSG *)pMsg))
-        return TRUE;
-    else
-        return FALSE;
-}
+            // for these messages we must return TRUE if process the message
+        case WM_DRAWITEM:
+        case WM_MEASUREITEM:
+            {
+                int idCtrl = (UINT)wParam;
+                if ( message == WM_DRAWITEM )
+                {
+                    processed = MSWOnDrawItem(idCtrl,
+                                              (WXDRAWITEMSTRUCT *)lParam);
+                }
+                else
+                {
+                    processed = MSWOnMeasureItem(idCtrl,
+                                                 (WXMEASUREITEMSTRUCT *)lParam);
+                }
 
-void wxWindow::MSWDetachWindowMenu()
-{
-    if ( m_hMenu )
-    {
-        int N = GetMenuItemCount((HMENU) m_hMenu);
-        int i;
-        for (i = 0; i < N; i++)
-        {
-            char buf[100];
-            int chars = GetMenuString((HMENU) m_hMenu, i, buf, 100, MF_BYPOSITION);
-            if ( (chars > 0) && (strcmp(buf, "&Window") == 0) )
+                if ( processed )
+                    rc.result = TRUE;
+            }
+            break;
+
+        case WM_KEYDOWN:
+            // If this has been processed by an event handler,
+            // return 0 now (we've handled it).
+            if ( HandleKeyDown((WORD) wParam, lParam) )
             {
-                RemoveMenu((HMENU) m_hMenu, i, MF_BYPOSITION);
+                processed = TRUE;
+
                 break;
             }
-        }
-    }
-}
-
-bool wxWindow::MSWOnPaint()
-{
-#ifdef __WIN32__
-    HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
-    ::GetUpdateRgn(GetHwnd(), hRegion, FALSE);
 
-    m_updateRegion = wxRegion((WXHRGN) hRegion);
-#else
-    RECT updateRect;
-    ::GetUpdateRect(GetHwnd(), & updateRect, FALSE);
+            // we consider these message "not interesting" to OnChar
+            if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
+            {
+                processed = TRUE;
 
-    m_updateRegion = wxRegion(updateRect.left, updateRect.top,
-        updateRect.right - updateRect.left, updateRect.bottom - updateRect.top);
-#endif
+                break;
+            }
 
-    wxPaintEvent event(m_windowId);
-    event.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(event);
-}
+            switch ( wParam )
+            {
+                // avoid duplicate messages to OnChar for these ASCII keys: they
+                // will be translated by TranslateMessage() and received in WM_CHAR
+                case VK_ESCAPE:
+                case VK_SPACE:
+                case VK_RETURN:
+                case VK_BACK:
+                case VK_TAB:
+                    processed = TRUE;
 
-bool wxWindow::HandleMove(int x, int y)
-{
-    wxMoveEvent event(wxPoint(x, y), m_windowId);
-    event.SetEventObject(this);
+                    break;
 
-    return GetEventHandler()->ProcessEvent(event);
-}
+#ifdef VK_APPS
+                // special case of VK_APPS: treat it the same as right mouse
+                // click because both usually pop up a context menu
+                case VK_APPS:
+                    {
+                        // construct the key mask
+                        WPARAM fwKeys = MK_RBUTTON;
+                        if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
+                            fwKeys |= MK_CONTROL;
+                        if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
+                            fwKeys |= MK_SHIFT;
 
-bool wxWindow::MSWOnSize(int w, int h, WXUINT WXUNUSED(flag))
-{
-    wxSizeEvent event(wxSize(w, h), m_windowId);
-    event.SetEventObject(this);
+                        // simulate right mouse button click
+                        DWORD dwPos = ::GetMessagePos();
+                        int x = GET_X_LPARAM(dwPos),
+                            y = GET_Y_LPARAM(dwPos);
 
-    return GetEventHandler()->ProcessEvent(event);
-}
+                        ScreenToClient(&x, &y);
+                        processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, fwKeys);
+                    }
+                    break;
+#endif // VK_APPS
 
-bool wxWindow::MSWOnWindowPosChanging(void *WXUNUSED(lpPos))
-{
-    return FALSE;
-}
+                case VK_LEFT:
+                case VK_RIGHT:
+                case VK_DOWN:
+                case VK_UP:
+                default:
+                    processed = HandleChar((WORD)wParam, lParam);
+            }
+            break;
 
-// Deal with child commands from buttons etc.
-bool wxWindow::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
-{
-    if ( wxCurrentPopupMenu )
-    {
-        wxMenu *popupMenu = wxCurrentPopupMenu;
-        wxCurrentPopupMenu = NULL;
-        bool succ = popupMenu->MSWCommand(cmd, id);
-        return succ;
-    }
+        case WM_KEYUP:
+            processed = HandleKeyUp((WORD) wParam, lParam);
+            break;
 
-    wxWindow *item = FindItem(id);
-    if ( item )
-    {
-        bool value = item->MSWCommand(cmd, id);
-        return value;
-    }
-    else
-    {
-        wxWindow *win = wxFindWinFromHandle(control);
-        if ( win )
-            return win->MSWCommand(cmd, id);
-    }
-    return FALSE;
-}
+        case WM_CHAR: // Always an ASCII character
+            processed = HandleChar((WORD)wParam, lParam, TRUE);
+            break;
 
-bool wxWindow::MSWOnSysCommand(WXWPARAM wParam, WXLPARAM lParam)
-{
-    // 4 bits are reserved
-    switch (wParam & 0xFFFFFFF0)
-    {
-        case SC_MAXIMIZE:
+        case WM_HSCROLL:
+        case WM_VSCROLL:
             {
-                wxMaximizeEvent event(m_windowId);
-                event.SetEventObject(this);
+                WXWORD code, pos;
+                WXHWND hwnd;
+                UnpackScroll(wParam, lParam, &code, &pos, &hwnd);
 
-                return GetEventHandler()->ProcessEvent(event);
+                processed = MSWOnScroll(message == WM_HSCROLL ? wxHORIZONTAL
+                                                              : wxVERTICAL,
+                                        code, pos, hwnd);
             }
+            break;
 
-        case SC_MINIMIZE:
+        // CTLCOLOR messages are sent by children to query the parent for their
+        // colors
+#ifdef __WIN32__
+        case WM_CTLCOLORMSGBOX:
+        case WM_CTLCOLOREDIT:
+        case WM_CTLCOLORLISTBOX:
+        case WM_CTLCOLORBTN:
+        case WM_CTLCOLORDLG:
+        case WM_CTLCOLORSCROLLBAR:
+        case WM_CTLCOLORSTATIC:
+#else // Win16
+        case WM_CTLCOLOR:
+#endif // Win32/16
             {
-                wxIconizeEvent event(m_windowId);
-                event.SetEventObject(this);
-
-                return GetEventHandler()->ProcessEvent(event);
+                WXWORD nCtlColor;
+                WXHDC hdc;
+                WXHWND hwnd;
+                UnpackCtlColor(wParam, lParam, &nCtlColor, &hdc, &hwnd);
+
+                processed = HandleCtlColor(&rc.hBrush,
+                                           (WXHDC)hdc,
+                                           (WXHWND)hwnd,
+                                           nCtlColor,
+                                           message,
+                                           wParam,
+                                           lParam);
             }
-    }
+            break;
 
-    return FALSE;
-}
+            // the return value for this message is ignored
+        case WM_SYSCOLORCHANGE:
+            processed = HandleSysColorChange();
+            break;
 
-// ---------------------------------------------------------------------------
-// mouse events
-// ---------------------------------------------------------------------------
+        case WM_PALETTECHANGED:
+            processed = HandlePaletteChanged((WXHWND) (HWND) wParam);
+            break;
 
-void wxWindow::InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags)
-{
-    event.m_x = x;
-    event.m_y = y;
-    event.m_shiftDown = ((flags & MK_SHIFT) != 0);
-    event.m_controlDown = ((flags & MK_CONTROL) != 0);
-    event.m_leftDown = ((flags & MK_LBUTTON) != 0);
-    event.m_middleDown = ((flags & MK_MBUTTON) != 0);
-    event.m_rightDown = ((flags & MK_RBUTTON) != 0);
-    event.SetTimestamp(wxApp::sm_lastMessageTime);
-    event.m_eventObject = this;
+        case WM_QUERYNEWPALETTE:
+            processed = HandleQueryNewPalette();
+            break;
 
-#if wxUSE_MOUSEEVENT_HACK
-    m_lastMouseX = x;
-    m_lastMouseY = y;
-    m_lastMouseEvent = event.GetEventType();
-#endif // wxUSE_MOUSEEVENT_HACK
+        case WM_ERASEBKGND:
+            processed = HandleEraseBkgnd((WXHDC)(HDC)wParam);
+            if ( processed )
+            {
+                // we processed the message, i.e. erased the background
+                rc.result = TRUE;
+            }
+            break;
 
-}
+        case WM_DROPFILES:
+            processed = HandleDropFiles(wParam);
+            break;
 
-bool wxWindow::MSWOnMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
-{
-    // the mouse events take consecutive IDs from WM_MOUSEFIRST to
-    // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
-    // from the message id and take the value in the table to get wxWin event
-    // id
-    static const wxEventType eventsMouse[] =
-    {
-        wxEVT_MOTION,
-        wxEVT_LEFT_DOWN,
-        wxEVT_LEFT_UP,
-        wxEVT_LEFT_DCLICK,
-        wxEVT_RIGHT_DOWN,
-        wxEVT_RIGHT_UP,
-        wxEVT_RIGHT_DCLICK,
-        wxEVT_MIDDLE_DOWN,
-        wxEVT_MIDDLE_UP,
-        wxEVT_MIDDLE_DCLICK
-    };
+        case WM_INITDIALOG:
+            processed = HandleInitDialog((WXHWND)(HWND)wParam);
 
-    wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]);
-    InitMouseEvent(event, x, y, flags);
+            if ( processed )
+            {
+                // we never set focus from here
+                rc.result = FALSE;
+            }
+            break;
 
-    return GetEventHandler()->ProcessEvent(event);
-}
+        case WM_QUERYENDSESSION:
+            processed = HandleQueryEndSession(lParam, &rc.allow);
+            break;
 
-bool wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags)
-{
-    if ( !m_mouseInWindow )
-    {
-        // Generate an ENTER event
-        m_mouseInWindow = TRUE;
+        case WM_ENDSESSION:
+            processed = HandleEndSession(wParam != 0, lParam);
+            break;
 
-        wxMouseEvent event(wxEVT_ENTER_WINDOW);
-        InitMouseEvent(event, x, y, flags);
+        case WM_GETMINMAXINFO:
+            processed = HandleGetMinMaxInfo((LPMINMAXINFO)lParam);
+            break;
 
-        (void)GetEventHandler()->ProcessEvent(event);
+        case WM_SETCURSOR:
+            processed = HandleSetCursor((WXHWND)(HWND)wParam,
+                                        LOWORD(lParam),     // hit test
+                                        HIWORD(lParam));    // mouse msg
+
+            if ( processed )
+            {
+                // returning TRUE stops the DefWindowProc() from further
+                // processing this message - exactly what we need because we've
+                // just set the cursor.
+                rc.result = TRUE;
+            }
+            break;
     }
 
-#if wxUSE_MOUSEEVENT_HACK
-    // Window gets a click down message followed by a mouse move message even
-    // if position isn't changed!  We want to discard the trailing move event
-    // if x and y are the same.
-    if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN ||
-          m_lastMouseEvent == wxEVT_LEFT_DOWN ||
-          m_lastMouseEvent == wxEVT_MIDDLE_DOWN) &&
-         (m_lastMouseX == event.m_x && m_lastMouseY == event.m_y) )
+    if ( !processed )
     {
-        m_lastMouseEvent = wxEVT_MOTION;
-
-        return FALSE;
+#ifdef __WXDEBUG__
+        wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.",
+                   wxGetMessageName(message));
+#endif // __WXDEBUG__
+        rc.result = MSWDefWindowProc(message, wParam, lParam);
     }
-#endif // wxUSE_MOUSEEVENT_HACK
 
-    return MSWOnMouseEvent(WM_MOUSEMOVE, x, y, flags);
+    return rc.result;
 }
 
-// ---------------------------------------------------------------------------
-// keyboard handling
-// ---------------------------------------------------------------------------
-
-// isASCII is TRUE only when we're called from WM_CHAR handler and not from
-// WM_KEYDOWN one
-bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+// Dialog window proc
+LONG APIENTRY _EXPORT
+wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    int id;
-    bool tempControlDown = FALSE;
-    if ( isASCII )
+    if ( message == WM_INITDIALOG )
     {
-        // If 1 -> 26, translate to CTRL plus a letter.
-        id = wParam;
-        if ( (id > 0) && (id < 27) )
-        {
-            switch (id)
-            {
-            case 13:
-                {
-                    id = WXK_RETURN;
-                    break;
-                }
-            case 8:
-                {
-                    id = WXK_BACK;
-                    break;
-                }
-            case 9:
-                {
-                    id = WXK_TAB;
-                    break;
-                }
-            default:
-                {
-                    tempControlDown = TRUE;
-                    id = id + 96;
-                }
-            }
-        }
-    }
-    else if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
-        // it's ASCII and will be processed here only when called from
-        // WM_CHAR (i.e. when isASCII = TRUE)
-        id = -1;
+        // for this message, returning TRUE tells system to set focus to the
+        // first control in the dialog box
+        return TRUE;
     }
-
-    if ( id != -1 )
+    else
     {
-        wxKeyEvent event(wxEVT_CHAR);
-        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
-        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
-        if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
-            event.m_altDown = TRUE;
-
-        event.m_eventObject = this;
-        event.m_keyCode = id;
-        event.SetTimestamp(wxApp::sm_lastMessageTime);
-
-        POINT pt ;
-        GetCursorPos(&pt) ;
-        RECT rect ;
-        GetWindowRect(GetHwnd(),&rect) ;
-        pt.x -= rect.left ;
-        pt.y -= rect.top ;
-
-        event.m_x = pt.x; event.m_y = pt.y;
-
-        if ( GetEventHandler()->ProcessEvent(event) )
-            return TRUE;
-        else
-            return FALSE;
+        // for all the other ones, FALSE means that we didn't process the
+        // message
+        return 0;
     }
-    else
-        return FALSE;
 }
 
-bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam)
+wxList *wxWinHandleList = NULL;
+wxWindow *wxFindWinFromHandle(WXHWND hWnd)
 {
-    int id;
-
-    if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
-        id = wParam;
-    }
-
-    if ( id != -1 )
-    {
-        wxKeyEvent event(wxEVT_KEY_DOWN);
-        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
-        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
-        if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
-            event.m_altDown = TRUE;
-
-        event.m_eventObject = this;
-        event.m_keyCode = id;
-        event.SetTimestamp(wxApp::sm_lastMessageTime);
+    wxNode *node = wxWinHandleList->Find((long)hWnd);
+    if ( !node )
+        return NULL;
+    return (wxWindow *)node->Data();
+}
 
-        POINT pt ;
-        GetCursorPos(&pt) ;
-        RECT rect ;
-        GetWindowRect(GetHwnd(),&rect) ;
-        pt.x -= rect.left ;
-        pt.y -= rect.top ;
+void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
+{
+    // adding NULL hWnd is (first) surely a result of an error and
+    // (secondly) breaks menu command processing
+    wxCHECK_RET( hWnd != (HWND)NULL,
+                 "attempt to add a NULL hWnd to window list ignored" );
 
-        event.m_x = pt.x; event.m_y = pt.y;
+    if ( !wxWinHandleList->Find((long)hWnd) )
+        wxWinHandleList->Append((long)hWnd, win);
+}
 
-        if ( GetEventHandler()->ProcessEvent(event) )
-        {
-            return TRUE;
-        }
-        else return FALSE;
-    }
-    else
-    {
-        return FALSE;
-    }
+void wxRemoveHandleAssociation(wxWindow *win)
+{
+    wxWinHandleList->DeleteObject(win);
 }
 
-bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam)
+// Default destroyer - override if you destroy it in some other way
+// (e.g. with MDI child windows)
+void wxWindow::MSWDestroyWindow()
 {
-    int id;
-
-    if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
-        id = wParam;
-    }
+}
 
-    if ( id != -1 )
+void wxWindow::MSWDetachWindowMenu()
+{
+    if ( m_hMenu )
     {
-        wxKeyEvent event(wxEVT_KEY_UP);
-        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
-        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
-        if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
-            event.m_altDown = TRUE;
+        HMENU hMenu = (HMENU)m_hMenu;
 
-        event.m_eventObject = this;
-        event.m_keyCode = id;
-        event.SetTimestamp(wxApp::sm_lastMessageTime);
+        int N = ::GetMenuItemCount(hMenu);
+        int i;
+        for (i = 0; i < N; i++)
+        {
+            char buf[100];
+            int chars = GetMenuString(hMenu, i, buf, 100, MF_BYPOSITION);
+            if ( !chars )
+            {
+                wxLogLastError("GetMenuString");
 
-        POINT pt ;
-        GetCursorPos(&pt) ;
-        RECT rect ;
-        GetWindowRect(GetHwnd(),&rect) ;
-        pt.x -= rect.left ;
-        pt.y -= rect.top ;
+                continue;
+            }
 
-        event.m_x = pt.x; event.m_y = pt.y;
+            if ( strcmp(buf, "&Window") == 0 )
+            {
+                RemoveMenu(hMenu, i, MF_BYPOSITION);
 
-        if ( GetEventHandler()->ProcessEvent(event) )
-            return TRUE;
-        else
-            return FALSE;
+                break;
+            }
+        }
     }
-    else
-        return FALSE;
 }
 
-// ---------------------------------------------------------------------------
-// joystick
-// ---------------------------------------------------------------------------
-
-bool wxWindow::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags)
+bool wxWindow::MSWCreate(int id,
+                         wxWindow *parent,
+                         const char *wclass,
+                         wxWindow *wx_win,
+                         const char *title,
+                         int x,
+                         int y,
+                         int width,
+                         int height,
+                         WXDWORD style,
+                         const char *dialog_template,
+                         WXDWORD extendedStyle)
 {
-    int change = 0;
-    if ( flags & JOY_BUTTON1CHG )
-        change = wxJOY_BUTTON1;
-    if ( flags & JOY_BUTTON2CHG )
-        change = wxJOY_BUTTON2;
-    if ( flags & JOY_BUTTON3CHG )
-        change = wxJOY_BUTTON3;
-    if ( flags & JOY_BUTTON4CHG )
-        change = wxJOY_BUTTON4;
-
-    int buttons = 0;
-    if ( flags & JOY_BUTTON1 )
-        buttons |= wxJOY_BUTTON1;
-    if ( flags & JOY_BUTTON2 )
-        buttons |= wxJOY_BUTTON2;
-    if ( flags & JOY_BUTTON3 )
-        buttons |= wxJOY_BUTTON3;
-    if ( flags & JOY_BUTTON4 )
-        buttons |= wxJOY_BUTTON4;
+    int x1 = CW_USEDEFAULT;
+    int y1 = 0;
+    int width1 = CW_USEDEFAULT;
+    int height1 = 100;
 
-    // the event ids aren't consecutive so we can't use table based lookup
-    int joystick;
-    wxEventType eventType;
-    switch ( msg )
+    // Find parent's size, if it exists, to set up a possible default
+    // panel size the size of the parent window
+    RECT parent_rect;
+    if ( parent )
     {
-        case MM_JOY1MOVE:
-            joystick = 1;
-            eventType = wxEVT_JOY_MOVE;
-            break;
+        ::GetClientRect((HWND) parent->GetHWND(), &parent_rect);
 
-        case MM_JOY2MOVE:
-            joystick = 2;
-            eventType = wxEVT_JOY_MOVE;
-            break;
+        width1 = parent_rect.right - parent_rect.left;
+        height1 = parent_rect.bottom - parent_rect.top;
+    }
 
-        case MM_JOY1ZMOVE:
-            joystick = 1;
-            eventType = wxEVT_JOY_ZMOVE;
-            break;
+    if ( x > -1 ) x1 = x;
+    if ( y > -1 ) y1 = y;
+    if ( width > -1 ) width1 = width;
+    if ( height > -1 ) height1 = height;
 
-        case MM_JOY2ZMOVE:
-            joystick = 2;
-            eventType = wxEVT_JOY_ZMOVE;
-            break;
+    HWND hParent = NULL;
+    if ( parent )
+        hParent = (HWND) parent->GetHWND();
 
-        case MM_JOY1BUTTONDOWN:
-            joystick = 1;
-            eventType = wxEVT_JOY_BUTTON_DOWN;
-            break;
+    wxWndHook = this;
 
-        case MM_JOY2BUTTONDOWN:
-            joystick = 2;
-            eventType = wxEVT_JOY_BUTTON_DOWN;
-            break;
+    if ( dialog_template )
+    {
+        m_hWnd = (WXHWND)::CreateDialog(wxGetInstance(),
+                                        dialog_template,
+                                        hParent,
+                                        (DLGPROC)wxDlgProc);
 
-        case MM_JOY1BUTTONUP:
-            joystick = 1;
-            eventType = wxEVT_JOY_BUTTON_UP;
-            break;
+        if ( m_hWnd == 0 )
+        {
+            wxLogError(_("Can't find dummy dialog template!\n"
+                         "Check resource include path for finding wx.rc."));
 
-        case MM_JOY2BUTTONUP:
-            joystick = 2;
-            eventType = wxEVT_JOY_BUTTON_UP;
-            break;
+            return FALSE;
+        }
 
-        default:
-            wxFAIL_MSG("no such joystick event");
+        ::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE);
+    }
+    else
+    {
+        int controlId = 0;
+        if ( style & WS_CHILD )
+            controlId = id;
+
+        m_hWnd = (WXHWND)CreateWindowEx(extendedStyle,
+                                        wclass,
+                                        title ? title : "",
+                                        style,
+                                        x1, y1,
+                                        width1, height1,
+                                        hParent, (HMENU)controlId,
+                                        wxGetInstance(),
+                                        NULL);
+
+        if ( !m_hWnd )
+        {
+            wxLogError(_("Can't create window of class %s!\n"
+                         "Possible Windows 3.x compatibility problem?"),
+                       wclass);
 
             return FALSE;
+        }
     }
 
-    wxJoystickEvent event(eventType, buttons, joystick, change);
-    event.SetPosition(wxPoint(x, y));
-    event.SetEventObject(this);
+    wxWndHook = NULL;
+    wxWinHandleList->Append((long)m_hWnd, this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return TRUE;
 }
 
-bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam,
-                           WXWORD pos, WXHWND control)
+// ===========================================================================
+// MSW message handlers
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// WM_NOTIFY
+// ---------------------------------------------------------------------------
+
+#ifdef __WIN95__
+// FIXME: VZ: I'm not sure at all that the order of processing is correct
+bool wxWindow::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
-    if ( control )
+    LPNMHDR hdr = (LPNMHDR)lParam;
+    HWND hWnd = hdr->hwndFrom;
+    wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd);
+
+    // is this one of our windows?
+    if ( win )
     {
-        wxWindow *child = wxFindWinFromHandle(control);
-        if ( child )
-            return child->MSWOnScroll(orientation, wParam, pos, control);
+        return win->MSWOnNotify(idCtrl, lParam, result);
     }
 
-    wxScrollEvent event;
-    event.SetPosition(pos);
-    event.SetOrientation(orientation);
-    event.m_eventObject = this;
-
-    switch ( wParam )
+    // try all our children
+    wxWindowList::Node *node = GetChildren().GetFirst();
+    while ( node )
     {
-    case SB_TOP:
-        event.m_eventType = wxEVT_SCROLL_TOP;
-        break;
+        wxWindow *child = node->GetData();
+        if ( child->MSWOnNotify(idCtrl, lParam, result) )
+        {
+            return TRUE;
 
-    case SB_BOTTOM:
-        event.m_eventType = wxEVT_SCROLL_BOTTOM;
-        break;
+            break;
+        }
 
-    case SB_LINEUP:
-        event.m_eventType = wxEVT_SCROLL_LINEUP;
-        break;
+        node = node->GetNext();
+    }
 
-    case SB_LINEDOWN:
-        event.m_eventType = wxEVT_SCROLL_LINEDOWN;
-        break;
+    // finally try this window too (catches toolbar case)
+    return MSWOnNotify(idCtrl, lParam, result);
+}
 
-    case SB_PAGEUP:
-        event.m_eventType = wxEVT_SCROLL_PAGEUP;
-        break;
+bool wxWindow::MSWOnNotify(int WXUNUSED(idCtrl),
+                           WXLPARAM lParam,
+                           WXLPARAM* WXUNUSED(result))
+{
+#if wxUSE_TOOLTIPS
+    NMHDR* hdr = (NMHDR *)lParam;
+    if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
+    {
+        TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
+        ttt->lpszText = (char *)m_tooltip->GetTip().c_str();
 
-    case SB_PAGEDOWN:
-        event.m_eventType = wxEVT_SCROLL_PAGEDOWN;
-        break;
+        // processed
+        return TRUE;
+    }
+#endif // wxUSE_TOOLTIPS
+
+    return FALSE;
+}
+#endif // __WIN95__
+
+// ---------------------------------------------------------------------------
+// end session messages
+// ---------------------------------------------------------------------------
 
-    case SB_THUMBTRACK:
-    case SB_THUMBPOSITION:
-        event.m_eventType = wxEVT_SCROLL_THUMBTRACK;
-        break;
+bool wxWindow::HandleQueryEndSession(long logOff, bool *mayEnd)
+{
+    wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
+    event.SetEventObject(wxTheApp);
+    event.SetCanVeto(TRUE);
+    event.SetLoggingOff(logOff == ENDSESSION_LOGOFF);
 
-    default:
-        return FALSE;
+    bool rc = wxTheApp->ProcessEvent(event);
+
+    if ( rc )
+    {
+        // we may end only if the app didn't veto session closing (double
+        // negation...)
+        *mayEnd = !event.GetVeto();
     }
 
-    return GetEventHandler()->ProcessEvent(event);
+    return rc;
 }
 
-bool wxWindow::MSWOnShow(bool show, int status)
+bool wxWindow::HandleEndSession(bool endSession, long logOff)
 {
-    wxShowEvent event(GetId(), show);
-    event.m_eventObject = this;
+    // do nothing if the session isn't ending
+    if ( !endSession )
+        return FALSE;
 
-    return GetEventHandler()->ProcessEvent(event);
+    wxCloseEvent event(wxEVT_END_SESSION, -1);
+    event.SetEventObject(wxTheApp);
+    event.SetCanVeto(FALSE);
+    event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
+    if ( (this == wxTheApp->GetTopWindow()) && // Only send once
+        wxTheApp->ProcessEvent(event))
+    {
+    }
+    return TRUE;
 }
 
-bool wxWindow::MSWOnInitDialog(WXHWND WXUNUSED(hWndFocus))
+// ---------------------------------------------------------------------------
+// window creation/destruction
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
 {
-    wxInitDialogEvent event(GetId());
-    event.m_eventObject = this;
+    // TODO: should generate this event from WM_NCCREATE
+    wxWindowCreateEvent event(this);
+    (void)GetEventHandler()->ProcessEvent(event);
 
-    return GetEventHandler()->ProcessEvent(event);
+    *mayCreate = TRUE;
+
+    return TRUE;
 }
 
-void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
+bool wxWindow::HandleDestroy()
 {
-    TEXTMETRIC tm;
-    HDC dc = ::GetDC((HWND) wnd);
-    HFONT fnt =0;
-    HFONT was = 0;
-    if ( the_font )
-    {
-        //    the_font->UseResource();
-        //    the_font->RealizeResource();
-        fnt = (HFONT)the_font->GetResourceHandle();
-        if ( fnt )
-            was = (HFONT) SelectObject(dc,fnt) ;
-    }
-    GetTextMetrics(dc, &tm);
-    if ( the_font && fnt && was )
+    wxWindowDestroyEvent event(this);
+    (void)GetEventHandler()->ProcessEvent(event);
+
+    // delete our drop target if we've got one
+#if wxUSE_DRAG_AND_DROP
+    if ( m_dropTarget != NULL )
     {
-        SelectObject(dc,was) ;
+        m_dropTarget->Revoke(m_hWnd);
+
+        delete m_dropTarget;
+        m_dropTarget = NULL;
     }
-    ReleaseDC((HWND)wnd, dc);
-    *x = tm.tmAveCharWidth;
-    *y = tm.tmHeight + tm.tmExternalLeading;
+#endif // wxUSE_DRAG_AND_DROP
 
-    //  if ( the_font )
-    //    the_font->ReleaseResource();
+    // WM_DESTROY handled
+    return TRUE;
 }
 
-// Returns 0 if was a normal ASCII value, not a special key. This indicates that
-// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
-int wxCharCodeMSWToWX(int keySym)
+// ---------------------------------------------------------------------------
+// activation/focus
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleActivate(int state,
+                              bool WXUNUSED(minimized),
+                              WXHWND WXUNUSED(activate))
 {
-    int id = 0;
-    switch (keySym)
+    wxActivateEvent event(wxEVT_ACTIVATE,
+                          (state == WA_ACTIVE) || (state == WA_CLICKACTIVE),
+                          m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd))
+{
+    // Deal with caret
+    if ( m_caretEnabled && (m_caretWidth > 0) && (m_caretHeight > 0) )
     {
-    case VK_CANCEL:     id = WXK_CANCEL; break;
-    case VK_BACK:       id = WXK_BACK; break;
-    case VK_TAB:        id = WXK_TAB; break;
-    case VK_CLEAR:      id = WXK_CLEAR; break;
-    case VK_RETURN:     id = WXK_RETURN; break;
-    case VK_SHIFT:      id = WXK_SHIFT; break;
-    case VK_CONTROL:    id = WXK_CONTROL; break;
-    case VK_MENU :      id = WXK_MENU; break;
-    case VK_PAUSE:      id = WXK_PAUSE; break;
-    case VK_SPACE:      id = WXK_SPACE; break;
-    case VK_ESCAPE:     id = WXK_ESCAPE; break;
-    case VK_PRIOR:      id = WXK_PRIOR; break;
-    case VK_NEXT :      id = WXK_NEXT; break;
-    case VK_END:        id = WXK_END; break;
-    case VK_HOME :      id = WXK_HOME; break;
-    case VK_LEFT :      id = WXK_LEFT; break;
-    case VK_UP:         id = WXK_UP; break;
-    case VK_RIGHT:      id = WXK_RIGHT; break;
-    case VK_DOWN :      id = WXK_DOWN; break;
-    case VK_SELECT:     id = WXK_SELECT; break;
-    case VK_PRINT:      id = WXK_PRINT; break;
-    case VK_EXECUTE:    id = WXK_EXECUTE; break;
-    case VK_INSERT:     id = WXK_INSERT; break;
-    case VK_DELETE:     id = WXK_DELETE; break;
-    case VK_HELP :      id = WXK_HELP; break;
-    case VK_NUMPAD0:    id = WXK_NUMPAD0; break;
-    case VK_NUMPAD1:    id = WXK_NUMPAD1; break;
-    case VK_NUMPAD2:    id = WXK_NUMPAD2; break;
-    case VK_NUMPAD3:    id = WXK_NUMPAD3; break;
-    case VK_NUMPAD4:    id = WXK_NUMPAD4; break;
-    case VK_NUMPAD5:    id = WXK_NUMPAD5; break;
-    case VK_NUMPAD6:    id = WXK_NUMPAD6; break;
-    case VK_NUMPAD7:    id = WXK_NUMPAD7; break;
-    case VK_NUMPAD8:    id = WXK_NUMPAD8; break;
-    case VK_NUMPAD9:    id = WXK_NUMPAD9; break;
-    case VK_MULTIPLY:   id = WXK_MULTIPLY; break;
-    case VK_ADD:        id = WXK_ADD; break;
-    case VK_SUBTRACT:   id = WXK_SUBTRACT; break;
-    case VK_DECIMAL:    id = WXK_DECIMAL; break;
-    case VK_DIVIDE:     id = WXK_DIVIDE; break;
-    case VK_F1:         id = WXK_F1; break;
-    case VK_F2:         id = WXK_F2; break;
-    case VK_F3:         id = WXK_F3; break;
-    case VK_F4:         id = WXK_F4; break;
-    case VK_F5:         id = WXK_F5; break;
-    case VK_F6:         id = WXK_F6; break;
-    case VK_F7:         id = WXK_F7; break;
-    case VK_F8:         id = WXK_F8; break;
-    case VK_F9:         id = WXK_F9; break;
-    case VK_F10:        id = WXK_F10; break;
-    case VK_F11:        id = WXK_F11; break;
-    case VK_F12:        id = WXK_F12; break;
-    case VK_F13:        id = WXK_F13; break;
-    case VK_F14:        id = WXK_F14; break;
-    case VK_F15:        id = WXK_F15; break;
-    case VK_F16:        id = WXK_F16; break;
-    case VK_F17:        id = WXK_F17; break;
-    case VK_F18:        id = WXK_F18; break;
-    case VK_F19:        id = WXK_F19; break;
-    case VK_F20:        id = WXK_F20; break;
-    case VK_F21:        id = WXK_F21; break;
-    case VK_F22:        id = WXK_F22; break;
-    case VK_F23:        id = WXK_F23; break;
-    case VK_F24:        id = WXK_F24; break;
-    case VK_NUMLOCK:    id = WXK_NUMLOCK; break;
-    case VK_SCROLL:     id = WXK_SCROLL; break;
-    default:
+        if ( ::CreateCaret(GetHwnd(), NULL, m_caretWidth, m_caretHeight) )
         {
-            return 0;
+            if ( m_caretShown )
+            {
+                if ( !::ShowCaret(GetHwnd()) )
+                    wxLogLastError("ShowCaret");
+            }
         }
+        else
+            wxLogLastError("CreateCaret");
     }
-    return id;
+
+    // panel wants to track the window which was the last to have focus in it
+    wxWindow *parent = GetParent();
+    if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) )
+    {
+        ((wxPanel *)parent)->SetLastFocus(GetId());
+    }
+
+    wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-int wxCharCodeWXToMSW(int id, bool *isVirtual)
+bool wxWindow::HandleKillFocus(WXHWND WXUNUSED(hwnd))
 {
-    *isVirtual = TRUE;
-    int keySym = 0;
-    switch (id)
+    // Deal with caret
+    if ( m_caretEnabled )
     {
-    case WXK_CANCEL:    keySym = VK_CANCEL; break;
-    case WXK_CLEAR:     keySym = VK_CLEAR; break;
-    case WXK_SHIFT:     keySym = VK_SHIFT; break;
-    case WXK_CONTROL:   keySym = VK_CONTROL; break;
-    case WXK_MENU :     keySym = VK_MENU; break;
-    case WXK_PAUSE:     keySym = VK_PAUSE; break;
-    case WXK_PRIOR:     keySym = VK_PRIOR; break;
-    case WXK_NEXT :     keySym = VK_NEXT; break;
-    case WXK_END:       keySym = VK_END; break;
-    case WXK_HOME :     keySym = VK_HOME; break;
-    case WXK_LEFT :     keySym = VK_LEFT; break;
-    case WXK_UP:        keySym = VK_UP; break;
-    case WXK_RIGHT:     keySym = VK_RIGHT; break;
-    case WXK_DOWN :     keySym = VK_DOWN; break;
-    case WXK_SELECT:    keySym = VK_SELECT; break;
-    case WXK_PRINT:     keySym = VK_PRINT; break;
-    case WXK_EXECUTE:   keySym = VK_EXECUTE; break;
-    case WXK_INSERT:    keySym = VK_INSERT; break;
-    case WXK_DELETE:    keySym = VK_DELETE; break;
-    case WXK_HELP :     keySym = VK_HELP; break;
-    case WXK_NUMPAD0:   keySym = VK_NUMPAD0; break;
-    case WXK_NUMPAD1:   keySym = VK_NUMPAD1; break;
-    case WXK_NUMPAD2:   keySym = VK_NUMPAD2; break;
-    case WXK_NUMPAD3:   keySym = VK_NUMPAD3; break;
-    case WXK_NUMPAD4:   keySym = VK_NUMPAD4; break;
-    case WXK_NUMPAD5:   keySym = VK_NUMPAD5; break;
-    case WXK_NUMPAD6:   keySym = VK_NUMPAD6; break;
-    case WXK_NUMPAD7:   keySym = VK_NUMPAD7; break;
-    case WXK_NUMPAD8:   keySym = VK_NUMPAD8; break;
-    case WXK_NUMPAD9:   keySym = VK_NUMPAD9; break;
-    case WXK_MULTIPLY:  keySym = VK_MULTIPLY; break;
-    case WXK_ADD:       keySym = VK_ADD; break;
-    case WXK_SUBTRACT:  keySym = VK_SUBTRACT; break;
-    case WXK_DECIMAL:   keySym = VK_DECIMAL; break;
-    case WXK_DIVIDE:    keySym = VK_DIVIDE; break;
-    case WXK_F1:        keySym = VK_F1; break;
-    case WXK_F2:        keySym = VK_F2; break;
-    case WXK_F3:        keySym = VK_F3; break;
-    case WXK_F4:        keySym = VK_F4; break;
-    case WXK_F5:        keySym = VK_F5; break;
-    case WXK_F6:        keySym = VK_F6; break;
-    case WXK_F7:        keySym = VK_F7; break;
-    case WXK_F8:        keySym = VK_F8; break;
-    case WXK_F9:        keySym = VK_F9; break;
-    case WXK_F10:       keySym = VK_F10; break;
-    case WXK_F11:       keySym = VK_F11; break;
-    case WXK_F12:       keySym = VK_F12; break;
-    case WXK_F13:       keySym = VK_F13; break;
-    case WXK_F14:       keySym = VK_F14; break;
-    case WXK_F15:       keySym = VK_F15; break;
-    case WXK_F16:       keySym = VK_F16; break;
-    case WXK_F17:       keySym = VK_F17; break;
-    case WXK_F18:       keySym = VK_F18; break;
-    case WXK_F19:       keySym = VK_F19; break;
-    case WXK_F20:       keySym = VK_F20; break;
-    case WXK_F21:       keySym = VK_F21; break;
-    case WXK_F22:       keySym = VK_F22; break;
-    case WXK_F23:       keySym = VK_F23; break;
-    case WXK_F24:       keySym = VK_F24; break;
-    case WXK_NUMLOCK:   keySym = VK_NUMLOCK; break;
-    case WXK_SCROLL:    keySym = VK_SCROLL; break;
-    default:
-        {
-            *isVirtual = FALSE;
-            keySym = id;
-            break;
-        }
+        if ( !::DestroyCaret() )
+            wxLogLastError("DestroyCaret");
     }
-    return keySym;
+
+    wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-// Caret manipulation
-void wxWindow::CreateCaret(int w, int h)
+// ---------------------------------------------------------------------------
+// miscellaneous
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleShow(bool show, int status)
 {
-    m_caretWidth = w;
-    m_caretHeight = h;
-    m_caretEnabled = TRUE;
+    wxShowEvent event(GetId(), show);
+    event.m_eventObject = this;
+
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
+bool wxWindow::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 {
-    // Not implemented
+    wxInitDialogEvent event(GetId());
+    event.m_eventObject = this;
+
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-void wxWindow::ShowCaret(bool show)
+bool wxWindow::HandleDropFiles(WXWPARAM wParam)
 {
-    if ( m_caretEnabled )
+    HDROP hFilesInfo = (HDROP) wParam;
+    POINT dropPoint;
+    DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
+
+    // Get the total number of files dropped
+    WORD gwFilesDropped = (WORD)DragQueryFile ((HDROP)hFilesInfo,
+        (UINT)-1,
+        (LPSTR)0,
+        (UINT)0);
+
+    wxString *files = new wxString[gwFilesDropped];
+    int wIndex;
+    for (wIndex=0; wIndex < (int)gwFilesDropped; wIndex++)
     {
-        if ( show )
-            ::ShowCaret(GetHwnd());
-        else
-            ::HideCaret(GetHwnd());
-        m_caretShown = show;
+        DragQueryFile (hFilesInfo, wIndex, (LPSTR) wxBuffer, 1000);
+        files[wIndex] = wxBuffer;
     }
-}
+    DragFinish (hFilesInfo);
 
-void wxWindow::DestroyCaret()
-{
-    m_caretEnabled = FALSE;
+    wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
+    event.m_eventObject = this;
+    event.m_pos.x = dropPoint.x; event.m_pos.x = dropPoint.y;
+
+    bool rc = GetEventHandler()->ProcessEvent(event);
+
+    delete[] files;
+
+    return rc;
 }
 
-void wxWindow::SetCaretPos(int x, int y)
+bool wxWindow::HandleSetCursor(WXHWND hWnd,
+                               short nHitTest,
+                               int WXUNUSED(mouseMsg))
 {
-    ::SetCaretPos(x, y);
+    // don't set cursor for other windows, only for this one: this prevents
+    // children of this window from getting the same cursor as the parent has
+    // (don't forget that this message is propagated by default up the window
+    // parent-child hierarchy)
+    if ( GetHWND() == hWnd )
+    {
+        // don't set cursor when the mouse is not in the client part
+        if ( nHitTest == HTCLIENT || nHitTest == HTERROR )
+        {
+            HCURSOR hcursor = 0;
+            if ( wxIsBusy() )
+            {
+                // from msw\utils.cpp
+                extern HCURSOR gs_wxBusyCursor;
+
+                hcursor = gs_wxBusyCursor;
+            }
+            else
+            {
+                wxCursor *cursor = NULL;
+
+                if ( m_cursor.Ok() )
+                {
+                    cursor = &m_cursor;
+                }
+                else
+                {
+                    // from msw\data.cpp
+                    extern wxCursor *g_globalCursor;
+
+                    if ( g_globalCursor && g_globalCursor->Ok() )
+                        cursor = g_globalCursor;
+                }
+
+                if ( cursor )
+                    hcursor = (HCURSOR)cursor->GetHCURSOR();
+            }
+
+            if ( hcursor )
+            {
+                ::SetCursor(hcursor);
+
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
 }
 
-void wxWindow::GetCaretPos(int *x, int *y) const
+#if wxUSE_OWNER_DRAWN
+// ---------------------------------------------------------------------------
+// owner drawn stuff
+// ---------------------------------------------------------------------------
+
+bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
 {
-    POINT point;
-    ::GetCaretPos(&point);
-    *x = point.x;
-    *y = point.y;
+    // is it a menu item?
+    if ( id == 0 )
+    {
+        DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct;
+        wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
+
+        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+
+        // prepare to call OnDrawItem()
+        wxDC dc;
+        dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE);
+        wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top,
+                    pDrawStruct->rcItem.right - pDrawStruct->rcItem.left,
+                    pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top);
+
+        return pMenuItem->OnDrawItem
+                          (
+                            dc, rect,
+                            (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction,
+                            (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState
+                          );
+    }
+
+    wxWindow *item = FindItem(id);
+    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
+    {
+        return ((wxControl *)item)->MSWOnDraw(itemStruct);
+    }
+    else
+        return FALSE;
 }
 
-wxWindow *wxGetActiveWindow()
+bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
 {
-    HWND hWnd = GetActiveWindow();
-    if ( hWnd != 0 )
+    // is it a menu item?
+    if ( id == 0 )
     {
-        return wxFindWinFromHandle((WXHWND) hWnd);
+        MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
+        wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
+
+        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+
+        return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth,
+                                        &pMeasureStruct->itemHeight);
     }
-    return NULL;
+
+    wxWindow *item = FindItem(id);
+    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
+    {
+        return ((wxControl *)item)->MSWOnMeasure(itemStruct);
+    }
+
+    return FALSE;
 }
+#endif  // owner-drawn menus
 
-// Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
-// in active frames and dialogs, regardless of where the focus is.
-static HHOOK wxTheKeyboardHook = 0;
-static FARPROC wxTheKeyboardHookProc = 0;
-int APIENTRY _EXPORT
-wxKeyboardHook(int nCode, WORD wParam, DWORD lParam);
+// ---------------------------------------------------------------------------
+// colours and palettes
+// ---------------------------------------------------------------------------
 
-void wxSetKeyboardHook(bool doIt)
+bool wxWindow::HandleSysColorChange()
 {
-    if ( doIt )
+    wxSysColourChangedEvent event;
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleCtlColor(WXHBRUSH *brush,
+                              WXHDC pDC,
+                              WXHWND pWnd,
+                              WXUINT nCtlColor,
+                              WXUINT message,
+                              WXWPARAM wParam,
+                              WXLPARAM lParam)
+{
+    WXHBRUSH hBrush = 0;
+
+    if ( nCtlColor == CTLCOLOR_DLG )
     {
-        wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
-        wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
-#if defined(__WIN32__) && !defined(__TWIN32__)
-            GetCurrentThreadId());
-        //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
-#else
-        GetCurrentTask());
-#endif
+        hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
     }
     else
     {
-        UnhookWindowsHookEx(wxTheKeyboardHook);
-        FreeProcInstance(wxTheKeyboardHookProc);
+        wxControl *item = (wxControl *)FindItemByHWND(pWnd, TRUE);
+        if ( item )
+            hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
     }
+
+    if ( hBrush )
+        *brush = hBrush;
+
+    return hBrush != 0;
 }
 
-int APIENTRY _EXPORT
-wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
+// Define for each class of dialog and control
+WXHBRUSH wxWindow::OnCtlColor(WXHDC hDC,
+                              WXHWND hWnd,
+                              WXUINT nCtlColor,
+                              WXUINT message,
+                              WXWPARAM wParam,
+                              WXLPARAM lParam)
 {
-    DWORD hiWord = HIWORD(lParam);
-    if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) )
-    {
-        int id;
-        if ( (id = wxCharCodeMSWToWX(wParam)) != 0 )
-        {
-            wxKeyEvent event(wxEVT_CHAR_HOOK);
-            if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
-                event.m_altDown = TRUE;
+    return (WXHBRUSH)0;
+}
 
-            event.m_eventObject = NULL;
-            event.m_keyCode = id;
-            /* begin Albert's fix for control and shift key 26.5 */
-            event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
-            event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
-            /* end Albert's fix for control and shift key 26.5 */
-            event.SetTimestamp(wxApp::sm_lastMessageTime);
+bool wxWindow::HandlePaletteChanged(WXHWND hWndPalChange)
+{
+    wxPaletteChangedEvent event(GetId());
+    event.SetEventObject(this);
+    event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
 
-            wxWindow *win = wxGetActiveWindow();
-            if ( win )
-            {
-                if ( win->GetEventHandler()->ProcessEvent(event) )
-                    return 1;
-            }
-            else
-            {
-                if ( wxTheApp && wxTheApp->ProcessEvent(event) )
-                    return 1;
-            }
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleQueryNewPalette()
+{
+    wxQueryNewPaletteEvent event(GetId());
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized();
+}
+
+// Responds to colour changes: passes event on to children.
+void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+    wxNode *node = GetChildren().First();
+    while ( node )
+    {
+        // Only propagate to non-top-level windows
+        wxWindow *win = (wxWindow *)node->Data();
+        if ( win->GetParent() )
+        {
+            wxSysColourChangedEvent event2;
+            event.m_eventObject = win;
+            win->GetEventHandler()->ProcessEvent(event2);
         }
+
+        node = node->Next();
     }
-    return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam);
 }
 
-void wxWindow::WarpPointer (int x_pos, int y_pos)
+// ---------------------------------------------------------------------------
+// painting
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandlePaint()
 {
-    // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
-    // pixel coordinates, relatives to the canvas -- So, we first need to
-    // substract origin of the window, then convert to screen position
+#ifdef __WIN32__
+    HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
+    if ( !hRegion )
+        wxLogLastError("CreateRectRgn");
+    if ( ::GetUpdateRgn(GetHwnd(), hRegion, FALSE) == ERROR )
+        wxLogLastError("GetUpdateRgn");
 
-    int x = x_pos; int y = y_pos;
-    RECT rect;
-    GetWindowRect (GetHwnd(), &rect);
+    m_updateRegion = wxRegion((WXHRGN) hRegion);
+#else
+    RECT updateRect;
+    ::GetUpdateRect(GetHwnd(), & updateRect, FALSE);
 
-    x += rect.left;
-    y += rect.top;
+    m_updateRegion = wxRegion(updateRect.left, updateRect.top,
+                              updateRect.right - updateRect.left,
+                              updateRect.bottom - updateRect.top);
+#endif
 
-    SetCursorPos (x, y);
-}
+    wxPaintEvent event(m_windowId);
+    event.SetEventObject(this);
 
-void wxWindow::MSWDeviceToLogical (float *x, float *y) const
-{
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-bool wxWindow::MSWOnQueryDragIcon(WXHICON * WXUNUSED(hIcon))
+bool wxWindow::HandleEraseBkgnd(WXHDC hdc)
 {
-    return FALSE;
-}
+    // Prevents flicker when dragging
+    if ( ::IsIconic(GetHwnd()) )
+        return TRUE;
 
-bool wxWindow::MSWOnEraseBkgnd(WXHDC hdc)
-{
     wxDC dc;
 
     dc.SetHDC(hdc);
@@ -2635,7 +2617,7 @@ bool wxWindow::MSWOnEraseBkgnd(WXHDC hdc)
     dc.BeginDrawing();
 
     wxEraseEvent event(m_windowId, &dc);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
     bool rc = GetEventHandler()->ProcessEvent(event);
 
     dc.EndDrawing();
@@ -2647,1119 +2629,1191 @@ bool wxWindow::MSWOnEraseBkgnd(WXHDC hdc)
 
 void wxWindow::OnEraseBackground(wxEraseEvent& event)
 {
-    if ( !GetHWND() )
-        return;
-
     RECT rect;
     ::GetClientRect(GetHwnd(), &rect);
 
-    COLORREF ref = PALETTERGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue()) ;
+    COLORREF ref = PALETTERGB(m_backgroundColour.Red(),
+                              m_backgroundColour.Green(),
+                              m_backgroundColour.Blue());
     HBRUSH hBrush = ::CreateSolidBrush(ref);
-    int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
+    if ( !hBrush )
+        wxLogLastError("CreateSolidBrush");
+
+    HDC hdc = (HDC)event.GetDC()->GetHDC();
 
-    //  ::GetClipBox((HDC) event.GetDC()->GetHDC(), &rect);
-    ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush);
+    int mode = ::SetMapMode(hdc, MM_TEXT);
+
+    ::FillRect(hdc, &rect, hBrush);
     ::DeleteObject(hBrush);
-    ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
-    /*
-    // Less efficient version (and doesn't account for scrolling)
-    int w, h;
-    GetClientSize(& w, & h);
-    wxBrush *brush = wxTheBrushList->FindOrCreateBrush(& GetBackgroundColour(), wxSOLID);
-    event.GetDC()->SetBrush(brush);
-    event.GetDC()->SetPen(wxTRANSPARENT_PEN);
+    ::SetMapMode(hdc, mode);
+}
+
+// ---------------------------------------------------------------------------
+// moving and resizing
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleMinimize()
+{
+    wxIconizeEvent event(m_windowId);
+    event.SetEventObject(this);
 
-      event.GetDC()->DrawRectangle(0, 0, w+1, h+1);
-    */
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-#if WXWIN_COMPATIBILITY
-void wxWindow::SetScrollRange(int orient, int range, bool refresh)
+bool wxWindow::HandleMaximize()
 {
-#if defined(__WIN95__)
+    wxMaximizeEvent event(m_windowId);
+    event.SetEventObject(this);
 
-    int range1 = range;
+    return GetEventHandler()->ProcessEvent(event);
+}
 
-    // Try to adjust the range to cope with page size > 1
-    // - a Windows API quirk
-    int pageSize = GetScrollPage(orient);
-    if ( pageSize > 1 && range > 0)
+bool wxWindow::HandleMove(int x, int y)
+{
+    wxMoveEvent event(wxPoint(x, y), m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleSize(int w, int h, WXUINT WXUNUSED(flag))
+{
+    wxSizeEvent event(wxSize(w, h), m_windowId);
+    event.SetEventObject(this);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleGetMinMaxInfo(void *mmInfo)
+{
+    MINMAXINFO *info = (MINMAXINFO *)mmInfo;
+
+    bool rc = FALSE;
+
+    if ( m_minWidth != -1 )
     {
-        range1 += (pageSize - 1);
+        info->ptMinTrackSize.x = m_minWidth;
+        rc = TRUE;
     }
 
-    SCROLLINFO info;
-    int dir;
+    if ( m_minHeight != -1 )
+    {
+        info->ptMinTrackSize.y = m_minHeight;
+        rc = TRUE;
+    }
 
-    if ( orient == wxHORIZONTAL ) {
-        dir = SB_HORZ;
-    } else {
-        dir = SB_VERT;
+    if ( m_maxWidth != -1 )
+    {
+        info->ptMaxTrackSize.x = m_maxWidth;
+        rc = TRUE;
     }
 
-    info.cbSize = sizeof(SCROLLINFO);
-    info.nPage = pageSize; // Have to set this, or scrollbar goes awry
-    info.nMin = 0;
-    info.nMax = range1;
-    info.nPos = 0;
-    info.fMask = SIF_RANGE | SIF_PAGE;
+    if ( m_maxHeight != -1 )
+    {
+        info->ptMaxTrackSize.y = m_maxHeight;
+        rc = TRUE;
+    }
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
-    int wOrient ;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
+    return rc;
+}
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollRange(hWnd, wOrient, 0, range, refresh);
-#endif
+// ---------------------------------------------------------------------------
+// command messages
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
+{
+    if ( wxCurrentPopupMenu )
+    {
+        wxMenu *popupMenu = wxCurrentPopupMenu;
+        wxCurrentPopupMenu = NULL;
+
+        return popupMenu->MSWCommand(cmd, id);
+    }
+
+    wxWindow *win = FindItem(id);
+    if ( !win )
+    {
+        win = wxFindWinFromHandle(control);
+    }
+
+    if ( win )
+        return win->MSWCommand(cmd, id);
+
+    return FALSE;
 }
 
-void wxWindow::SetScrollPage(int orient, int page, bool refresh)
+bool wxWindow::HandleSysCommand(WXWPARAM wParam, WXLPARAM lParam)
 {
-#if defined(__WIN95__)
-    SCROLLINFO info;
-    int dir;
+    // 4 bits are reserved
+    switch ( wParam & 0xFFFFFFF0 )
+    {
+        case SC_MAXIMIZE:
+            return HandleMaximize();
 
-    if ( orient == wxHORIZONTAL ) {
-        dir = SB_HORZ;
-        m_xThumbSize = page;
-    } else {
-        dir = SB_VERT;
-        m_yThumbSize = page;
+        case SC_MINIMIZE:
+            return HandleMinimize();
     }
 
-    info.cbSize = sizeof(SCROLLINFO);
-    info.nPage = page;
-    info.nMin = 0;
-    info.fMask = SIF_PAGE ;
+    return FALSE;
+}
+
+// ---------------------------------------------------------------------------
+// mouse events
+// ---------------------------------------------------------------------------
+
+void wxWindow::InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags)
+{
+    event.m_x = x;
+    event.m_y = y;
+    event.m_shiftDown = ((flags & MK_SHIFT) != 0);
+    event.m_controlDown = ((flags & MK_CONTROL) != 0);
+    event.m_leftDown = ((flags & MK_LBUTTON) != 0);
+    event.m_middleDown = ((flags & MK_MBUTTON) != 0);
+    event.m_rightDown = ((flags & MK_RBUTTON) != 0);
+    event.SetTimestamp(s_currentMsg.time);
+    event.m_eventObject = this;
+
+#if wxUSE_MOUSEEVENT_HACK
+    m_lastMouseX = x;
+    m_lastMouseY = y;
+    m_lastMouseEvent = event.GetEventType();
+#endif // wxUSE_MOUSEEVENT_HACK
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
-    if ( orient == wxHORIZONTAL )
-        m_xThumbSize = page;
-    else
-        m_yThumbSize = page;
-#endif
 }
 
-int wxWindow::OldGetScrollRange(int orient) const
+bool wxWindow::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
-    int wOrient ;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
+    // the mouse events take consecutive IDs from WM_MOUSEFIRST to
+    // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
+    // from the message id and take the value in the table to get wxWin event
+    // id
+    static const wxEventType eventsMouse[] =
+    {
+        wxEVT_MOTION,
+        wxEVT_LEFT_DOWN,
+        wxEVT_LEFT_UP,
+        wxEVT_LEFT_DCLICK,
+        wxEVT_RIGHT_DOWN,
+        wxEVT_RIGHT_UP,
+        wxEVT_RIGHT_DCLICK,
+        wxEVT_MIDDLE_DOWN,
+        wxEVT_MIDDLE_UP,
+        wxEVT_MIDDLE_DCLICK
+    };
 
-#if __WATCOMC__ && defined(__WINDOWS_386__)
-    short minPos, maxPos;
-#else
-    int minPos, maxPos;
-#endif
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
+    wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]);
+    InitMouseEvent(event, x, y, flags);
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxWindow::HandleMouseMove(int x, int y, WXUINT flags)
+{
+    if ( !m_mouseInWindow )
     {
-        ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
-#if defined(__WIN95__)
-        // Try to adjust the range to cope with page size > 1
-        // - a Windows API quirk
-        int pageSize = GetScrollPage(orient);
-        if ( pageSize > 1 )
+        // Generate an ENTER event
+        m_mouseInWindow = TRUE;
+
+        wxMouseEvent event(wxEVT_ENTER_WINDOW);
+        InitMouseEvent(event, x, y, flags);
+
+        (void)GetEventHandler()->ProcessEvent(event);
+    }
+
+#if wxUSE_MOUSEEVENT_HACK
+    // Window gets a click down message followed by a mouse move message even
+    // if position isn't changed!  We want to discard the trailing move event
+    // if x and y are the same.
+    if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN ||
+          m_lastMouseEvent == wxEVT_LEFT_DOWN ||
+          m_lastMouseEvent == wxEVT_MIDDLE_DOWN) &&
+         (m_lastMouseX == event.m_x && m_lastMouseY == event.m_y) )
+    {
+        m_lastMouseEvent = wxEVT_MOTION;
+
+        return FALSE;
+    }
+#endif // wxUSE_MOUSEEVENT_HACK
+
+    return HandleMouseEvent(WM_MOUSEMOVE, x, y, flags);
+}
+
+// ---------------------------------------------------------------------------
+// keyboard handling
+// ---------------------------------------------------------------------------
+
+// isASCII is TRUE only when we're called from WM_CHAR handler and not from
+// WM_KEYDOWN one
+bool wxWindow::HandleChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+{
+    int id;
+    bool tempControlDown = FALSE;
+    if ( isASCII )
+    {
+        // If 1 -> 26, translate to CTRL plus a letter.
+        id = wParam;
+        if ( (id > 0) && (id < 27) )
         {
-            maxPos -= (pageSize - 1);
+            switch (id)
+            {
+            case 13:
+                {
+                    id = WXK_RETURN;
+                    break;
+                }
+            case 8:
+                {
+                    id = WXK_BACK;
+                    break;
+                }
+            case 9:
+                {
+                    id = WXK_TAB;
+                    break;
+                }
+            default:
+                {
+                    tempControlDown = TRUE;
+                    id = id + 96;
+                }
+            }
         }
-#endif
-        return maxPos;
     }
-    else
-        return 0;
-}
-
-int wxWindow::GetScrollPage(int orient) const
-{
-    if ( orient == wxHORIZONTAL )
-        return m_xThumbSize;
-    else
-        return m_yThumbSize;
-}
-#endif
+    else if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
+        // it's ASCII and will be processed here only when called from
+        // WM_CHAR (i.e. when isASCII = TRUE)
+        id = -1;
+    }
 
-int wxWindow::GetScrollPos(int orient) const
-{
-    int wOrient ;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
+    if ( id != -1 )
     {
-        return ::GetScrollPos(hWnd, wOrient);
+        wxKeyEvent event(wxEVT_CHAR);
+        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
+        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
+        if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+            event.m_altDown = TRUE;
+
+        event.m_eventObject = this;
+        event.m_keyCode = id;
+        event.SetTimestamp(s_currentMsg.time);
+
+        POINT pt;
+        GetCursorPos(&pt);
+        RECT rect;
+        GetWindowRect(GetHwnd(),&rect);
+        pt.x -= rect.left;
+        pt.y -= rect.top;
+
+        event.m_x = pt.x; event.m_y = pt.y;
+
+        if ( GetEventHandler()->ProcessEvent(event) )
+            return TRUE;
+        else
+            return FALSE;
     }
     else
-        return 0;
+        return FALSE;
 }
 
-// This now returns the whole range, not just the number
-// of positions that we can scroll.
-int wxWindow::GetScrollRange(int orient) const
+bool wxWindow::HandleKeyDown(WXWORD wParam, WXLPARAM lParam)
 {
-    int wOrient ;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
+    int id;
 
-#if __WATCOMC__ && defined(__WINDOWS_386__)
-    short minPos, maxPos;
-#else
-    int minPos, maxPos;
-#endif
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
+    if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
+        id = wParam;
+    }
+
+    if ( id != -1 )
     {
-        ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
-#if defined(__WIN95__)
-        // Try to adjust the range to cope with page size > 1
-        // - a Windows API quirk
-        int pageSize = GetScrollThumb(orient);
-        if ( pageSize > 1 )
+        wxKeyEvent event(wxEVT_KEY_DOWN);
+        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
+        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
+        if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+            event.m_altDown = TRUE;
+
+        event.m_eventObject = this;
+        event.m_keyCode = id;
+        event.SetTimestamp(s_currentMsg.time);
+
+        POINT pt;
+        GetCursorPos(&pt);
+        RECT rect;
+        GetWindowRect(GetHwnd(),&rect);
+        pt.x -= rect.left;
+        pt.y -= rect.top;
+
+        event.m_x = pt.x; event.m_y = pt.y;
+
+        if ( GetEventHandler()->ProcessEvent(event) )
         {
-            maxPos -= (pageSize - 1);
+            return TRUE;
         }
-        // October 10th: new range concept.
-        maxPos += pageSize;
-#endif
-
-        return maxPos;
+        else return FALSE;
     }
     else
-        return 0;
-}
-
-int wxWindow::GetScrollThumb(int orient) const
-{
-    if ( orient == wxHORIZONTAL )
-        return m_xThumbSize;
-    else
-        return m_yThumbSize;
+    {
+        return FALSE;
+    }
 }
 
-void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
+bool wxWindow::HandleKeyUp(WXWORD wParam, WXLPARAM lParam)
 {
-#if defined(__WIN95__)
-    SCROLLINFO info;
-    int dir;
+    int id;
 
-    if ( orient == wxHORIZONTAL ) {
-        dir = SB_HORZ;
-    } else {
-        dir = SB_VERT;
+    if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
+        id = wParam;
     }
 
-    info.cbSize = sizeof(SCROLLINFO);
-    info.nPage = 0;
-    info.nMin = 0;
-    info.nPos = pos;
-    info.fMask = SIF_POS ;
+    if ( id != -1 )
+    {
+        wxKeyEvent event(wxEVT_KEY_UP);
+        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
+        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
+        if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+            event.m_altDown = TRUE;
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
-    int wOrient ;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
+        event.m_eventObject = this;
+        event.m_keyCode = id;
+        event.SetTimestamp(s_currentMsg.time);
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollPos(hWnd, wOrient, pos, refresh);
-#endif
+        POINT pt;
+        GetCursorPos(&pt);
+        RECT rect;
+        GetWindowRect(GetHwnd(),&rect);
+        pt.x -= rect.left;
+        pt.y -= rect.top;
+
+        event.m_x = pt.x; event.m_y = pt.y;
+
+        if ( GetEventHandler()->ProcessEvent(event) )
+            return TRUE;
+        else
+            return FALSE;
+    }
+    else
+        return FALSE;
 }
 
-// New function that will replace some of the above.
-void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
-                            int range, bool refresh)
+// ---------------------------------------------------------------------------
+// joystick
+// ---------------------------------------------------------------------------
+
+bool wxWindow::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
-/*
-SetScrollPage(orient, thumbVisible, FALSE);
+    int change = 0;
+    if ( flags & JOY_BUTTON1CHG )
+        change = wxJOY_BUTTON1;
+    if ( flags & JOY_BUTTON2CHG )
+        change = wxJOY_BUTTON2;
+    if ( flags & JOY_BUTTON3CHG )
+        change = wxJOY_BUTTON3;
+    if ( flags & JOY_BUTTON4CHG )
+        change = wxJOY_BUTTON4;
 
-  int oldRange = range - thumbVisible ;
-  SetScrollRange(orient, oldRange, FALSE);
+    int buttons = 0;
+    if ( flags & JOY_BUTTON1 )
+        buttons |= wxJOY_BUTTON1;
+    if ( flags & JOY_BUTTON2 )
+        buttons |= wxJOY_BUTTON2;
+    if ( flags & JOY_BUTTON3 )
+        buttons |= wxJOY_BUTTON3;
+    if ( flags & JOY_BUTTON4 )
+        buttons |= wxJOY_BUTTON4;
 
-    SetScrollPos(orient, pos, refresh);
-    */
-#if defined(__WIN95__)
-    int oldRange = range - thumbVisible ;
+    // the event ids aren't consecutive so we can't use table based lookup
+    int joystick;
+    wxEventType eventType;
+    switch ( msg )
+    {
+        case MM_JOY1MOVE:
+            joystick = 1;
+            eventType = wxEVT_JOY_MOVE;
+            break;
 
-    int range1 = oldRange;
+        case MM_JOY2MOVE:
+            joystick = 2;
+            eventType = wxEVT_JOY_MOVE;
+            break;
 
-    // Try to adjust the range to cope with page size > 1
-    // - a Windows API quirk
-    int pageSize = thumbVisible;
-    if ( pageSize > 1 && range > 0)
-    {
-        range1 += (pageSize - 1);
-    }
+        case MM_JOY1ZMOVE:
+            joystick = 1;
+            eventType = wxEVT_JOY_ZMOVE;
+            break;
 
-    SCROLLINFO info;
-    int dir;
+        case MM_JOY2ZMOVE:
+            joystick = 2;
+            eventType = wxEVT_JOY_ZMOVE;
+            break;
 
-    if ( orient == wxHORIZONTAL ) {
-        dir = SB_HORZ;
-    } else {
-        dir = SB_VERT;
-    }
+        case MM_JOY1BUTTONDOWN:
+            joystick = 1;
+            eventType = wxEVT_JOY_BUTTON_DOWN;
+            break;
 
-    info.cbSize = sizeof(SCROLLINFO);
-    info.nPage = pageSize; // Have to set this, or scrollbar goes awry
-    info.nMin = 0;
-    info.nMax = range1;
-    info.nPos = pos;
-    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
+        case MM_JOY2BUTTONDOWN:
+            joystick = 2;
+            eventType = wxEVT_JOY_BUTTON_DOWN;
+            break;
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
-    int wOrient ;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
+        case MM_JOY1BUTTONUP:
+            joystick = 1;
+            eventType = wxEVT_JOY_BUTTON_UP;
+            break;
+
+        case MM_JOY2BUTTONUP:
+            joystick = 2;
+            eventType = wxEVT_JOY_BUTTON_UP;
+            break;
+
+        default:
+            wxFAIL_MSG("no such joystick event");
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-    {
-        ::SetScrollRange(hWnd, wOrient, 0, range, FALSE);
-        ::SetScrollPos(hWnd, wOrient, pos, refresh);
-    }
-#endif
-    if ( orient == wxHORIZONTAL ) {
-        m_xThumbSize = thumbVisible;
-    } else {
-        m_yThumbSize = thumbVisible;
+            return FALSE;
     }
-}
 
-void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
-{
-    RECT rect2;
-    if ( rect )
-    {
-        rect2.left = rect->x;
-        rect2.top = rect->y;
-        rect2.right = rect->x + rect->width;
-        rect2.bottom = rect->y + rect->height;
-    }
+    wxJoystickEvent event(eventType, buttons, joystick, change);
+    event.SetPosition(wxPoint(x, y));
+    event.SetEventObject(this);
 
-    if ( rect )
-        ::ScrollWindow(GetHwnd(), dx, dy, &rect2, NULL);
-    else
-        ::ScrollWindow(GetHwnd(), dx, dy, NULL, NULL);
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-bool wxWindow::SetFont(const wxFont& font)
+// ---------------------------------------------------------------------------
+// scrolling
+// ---------------------------------------------------------------------------
+
+bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam,
+                           WXWORD pos, WXHWND control)
 {
-    if ( !wxWindowBase::SetFont(font) )
+    if ( control )
     {
-        // nothing to do
-        return FALSE;
+        wxWindow *child = wxFindWinFromHandle(control);
+        if ( child )
+            return child->MSWOnScroll(orientation, wParam, pos, control);
     }
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd != 0 )
-    {
-        WXHANDLE hFont = m_font.GetResourceHandle();
+    wxScrollEvent event;
+    event.SetPosition(pos);
+    event.SetOrientation(orientation);
+    event.m_eventObject = this;
 
-        wxASSERT_MSG( hFont, _T("should have valid font") );
+    switch ( wParam )
+    {
+    case SB_TOP:
+        event.m_eventType = wxEVT_SCROLL_TOP;
+        break;
 
-        ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, TRUE);
-    }
+    case SB_BOTTOM:
+        event.m_eventType = wxEVT_SCROLL_BOTTOM;
+        break;
 
-    return TRUE;
-}
+    case SB_LINEUP:
+        event.m_eventType = wxEVT_SCROLL_LINEUP;
+        break;
 
-void wxWindow::SubclassWin(WXHWND hWnd)
-{
-    wxASSERT_MSG( !m_oldWndProc, "subclassing window twice?" );
+    case SB_LINEDOWN:
+        event.m_eventType = wxEVT_SCROLL_LINEDOWN;
+        break;
 
-    wxAssociateWinWithHandle((HWND)hWnd, this);
+    case SB_PAGEUP:
+        event.m_eventType = wxEVT_SCROLL_PAGEUP;
+        break;
 
-    m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC);
-    SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc);
-}
+    case SB_PAGEDOWN:
+        event.m_eventType = wxEVT_SCROLL_PAGEDOWN;
+        break;
 
-void wxWindow::UnsubclassWin()
-{
-    wxRemoveHandleAssociation(this);
+    case SB_THUMBTRACK:
+    case SB_THUMBPOSITION:
+        event.m_eventType = wxEVT_SCROLL_THUMBTRACK;
+        break;
 
-    // Restore old Window proc
-    if ( GetHwnd() )
-    {
-        FARPROC farProc = (FARPROC) GetWindowLong(GetHwnd(), GWL_WNDPROC);
-        if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) )
-        {
-            SetWindowLong(GetHwnd(), GWL_WNDPROC, (LONG) m_oldWndProc);
-            m_oldWndProc = 0;
-        }
+    default:
+        return FALSE;
     }
-}
 
-// Make a Windows extended style from the given wxWindows window style
-WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders)
-{
-    WXDWORD exStyle = 0;
-    if ( style & wxTRANSPARENT_WINDOW )
-        exStyle |= WS_EX_TRANSPARENT ;
-
-    if ( !eliminateBorders )
-    {
-        if ( style & wxSUNKEN_BORDER )
-            exStyle |= WS_EX_CLIENTEDGE ;
-        if ( style & wxDOUBLE_BORDER )
-            exStyle |= WS_EX_DLGMODALFRAME ;
-#if defined(__WIN95__)
-        if ( style & wxRAISED_BORDER )
-            exStyle |= WS_EX_WINDOWEDGE ;
-        if ( style & wxSTATIC_BORDER )
-            exStyle |= WS_EX_STATICEDGE ;
-#endif
-    }
-    return exStyle;
+    return GetEventHandler()->ProcessEvent(event);
 }
 
-// Determines whether native 3D effects or CTL3D should be used,
-// applying a default border style if required, and returning an extended
-// style to pass to CreateWindowEx.
-WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
+// ===========================================================================
+// global functions
+// ===========================================================================
+
+void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
 {
-    // If matches certain criteria, then assume no 3D effects
-    // unless specifically requested (dealt with in MakeExtendedStyle)
-    if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) )
+    TEXTMETRIC tm;
+    HDC dc = ::GetDC((HWND) wnd);
+    HFONT fnt =0;
+    HFONT was = 0;
+    if ( the_font )
     {
-        *want3D = FALSE;
-        return MakeExtendedStyle(m_windowStyle, FALSE);
+        //    the_font->UseResource();
+        //    the_font->RealizeResource();
+        fnt = (HFONT)the_font->GetResourceHandle();
+        if ( fnt )
+            was = (HFONT) SelectObject(dc,fnt);
     }
-
-    // Determine whether we should be using 3D effects or not.
-    bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
-
-    // 1) App can specify global 3D effects
-    *want3D = wxTheApp->GetAuto3D();
-
-    // 2) If the parent is being drawn with user colours, or simple border specified,
-    // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
-    if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) )
-        *want3D = FALSE;
-
-    // 3) Control can override this global setting by defining
-    // a border style, e.g. wxSUNKEN_BORDER
-    if ( m_windowStyle & wxSUNKEN_BORDER  )
-        *want3D = TRUE;
-
-    // 4) If it's a special border, CTL3D can't cope so we want a native border
-    if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
-        (m_windowStyle & wxSTATIC_BORDER) )
+    GetTextMetrics(dc, &tm);
+    if ( the_font && fnt && was )
     {
-        *want3D = TRUE;
-        nativeBorder = TRUE;
+        SelectObject(dc,was);
     }
+    ReleaseDC((HWND)wnd, dc);
+    *x = tm.tmAveCharWidth;
+    *y = tm.tmHeight + tm.tmExternalLeading;
 
-    // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
-    // effects from extended style
-#if wxUSE_CTL3D
-    if ( *want3D )
-        nativeBorder = FALSE;
-#endif
-
-    DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
-
-    // If we want 3D, but haven't specified a border here,
-    // apply the default border style specified.
-    // TODO what about non-Win95 WIN32? Does it have borders?
-#if defined(__WIN95__) && !wxUSE_CTL3D
-    if ( defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) ||
-        (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
-        exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ;
-#endif
+    //  if ( the_font )
+    //    the_font->ReleaseResource();
+}
 
-    return exStyle;
+// Returns 0 if was a normal ASCII value, not a special key. This indicates that
+// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
+int wxCharCodeMSWToWX(int keySym)
+{
+    int id = 0;
+    switch (keySym)
+    {
+    case VK_CANCEL:     id = WXK_CANCEL; break;
+    case VK_BACK:       id = WXK_BACK; break;
+    case VK_TAB:        id = WXK_TAB; break;
+    case VK_CLEAR:      id = WXK_CLEAR; break;
+    case VK_RETURN:     id = WXK_RETURN; break;
+    case VK_SHIFT:      id = WXK_SHIFT; break;
+    case VK_CONTROL:    id = WXK_CONTROL; break;
+    case VK_MENU :      id = WXK_MENU; break;
+    case VK_PAUSE:      id = WXK_PAUSE; break;
+    case VK_SPACE:      id = WXK_SPACE; break;
+    case VK_ESCAPE:     id = WXK_ESCAPE; break;
+    case VK_PRIOR:      id = WXK_PRIOR; break;
+    case VK_NEXT :      id = WXK_NEXT; break;
+    case VK_END:        id = WXK_END; break;
+    case VK_HOME :      id = WXK_HOME; break;
+    case VK_LEFT :      id = WXK_LEFT; break;
+    case VK_UP:         id = WXK_UP; break;
+    case VK_RIGHT:      id = WXK_RIGHT; break;
+    case VK_DOWN :      id = WXK_DOWN; break;
+    case VK_SELECT:     id = WXK_SELECT; break;
+    case VK_PRINT:      id = WXK_PRINT; break;
+    case VK_EXECUTE:    id = WXK_EXECUTE; break;
+    case VK_INSERT:     id = WXK_INSERT; break;
+    case VK_DELETE:     id = WXK_DELETE; break;
+    case VK_HELP :      id = WXK_HELP; break;
+    case VK_NUMPAD0:    id = WXK_NUMPAD0; break;
+    case VK_NUMPAD1:    id = WXK_NUMPAD1; break;
+    case VK_NUMPAD2:    id = WXK_NUMPAD2; break;
+    case VK_NUMPAD3:    id = WXK_NUMPAD3; break;
+    case VK_NUMPAD4:    id = WXK_NUMPAD4; break;
+    case VK_NUMPAD5:    id = WXK_NUMPAD5; break;
+    case VK_NUMPAD6:    id = WXK_NUMPAD6; break;
+    case VK_NUMPAD7:    id = WXK_NUMPAD7; break;
+    case VK_NUMPAD8:    id = WXK_NUMPAD8; break;
+    case VK_NUMPAD9:    id = WXK_NUMPAD9; break;
+    case VK_MULTIPLY:   id = WXK_MULTIPLY; break;
+    case VK_ADD:        id = WXK_ADD; break;
+    case VK_SUBTRACT:   id = WXK_SUBTRACT; break;
+    case VK_DECIMAL:    id = WXK_DECIMAL; break;
+    case VK_DIVIDE:     id = WXK_DIVIDE; break;
+    case VK_F1:         id = WXK_F1; break;
+    case VK_F2:         id = WXK_F2; break;
+    case VK_F3:         id = WXK_F3; break;
+    case VK_F4:         id = WXK_F4; break;
+    case VK_F5:         id = WXK_F5; break;
+    case VK_F6:         id = WXK_F6; break;
+    case VK_F7:         id = WXK_F7; break;
+    case VK_F8:         id = WXK_F8; break;
+    case VK_F9:         id = WXK_F9; break;
+    case VK_F10:        id = WXK_F10; break;
+    case VK_F11:        id = WXK_F11; break;
+    case VK_F12:        id = WXK_F12; break;
+    case VK_F13:        id = WXK_F13; break;
+    case VK_F14:        id = WXK_F14; break;
+    case VK_F15:        id = WXK_F15; break;
+    case VK_F16:        id = WXK_F16; break;
+    case VK_F17:        id = WXK_F17; break;
+    case VK_F18:        id = WXK_F18; break;
+    case VK_F19:        id = WXK_F19; break;
+    case VK_F20:        id = WXK_F20; break;
+    case VK_F21:        id = WXK_F21; break;
+    case VK_F22:        id = WXK_F22; break;
+    case VK_F23:        id = WXK_F23; break;
+    case VK_F24:        id = WXK_F24; break;
+    case VK_NUMLOCK:    id = WXK_NUMLOCK; break;
+    case VK_SCROLL:     id = WXK_SCROLL; break;
+    default:
+        {
+            return 0;
+        }
+    }
+    return id;
 }
 
-// Get the window with the focus
-wxWindow *wxWindowBase::FindFocus()
+int wxCharCodeWXToMSW(int id, bool *isVirtual)
 {
-    HWND hWnd = ::GetFocus();
-    if ( hWnd )
+    *isVirtual = TRUE;
+    int keySym = 0;
+    switch (id)
     {
-        return wxFindWinFromHandle((WXHWND) hWnd);
+    case WXK_CANCEL:    keySym = VK_CANCEL; break;
+    case WXK_CLEAR:     keySym = VK_CLEAR; break;
+    case WXK_SHIFT:     keySym = VK_SHIFT; break;
+    case WXK_CONTROL:   keySym = VK_CONTROL; break;
+    case WXK_MENU :     keySym = VK_MENU; break;
+    case WXK_PAUSE:     keySym = VK_PAUSE; break;
+    case WXK_PRIOR:     keySym = VK_PRIOR; break;
+    case WXK_NEXT :     keySym = VK_NEXT; break;
+    case WXK_END:       keySym = VK_END; break;
+    case WXK_HOME :     keySym = VK_HOME; break;
+    case WXK_LEFT :     keySym = VK_LEFT; break;
+    case WXK_UP:        keySym = VK_UP; break;
+    case WXK_RIGHT:     keySym = VK_RIGHT; break;
+    case WXK_DOWN :     keySym = VK_DOWN; break;
+    case WXK_SELECT:    keySym = VK_SELECT; break;
+    case WXK_PRINT:     keySym = VK_PRINT; break;
+    case WXK_EXECUTE:   keySym = VK_EXECUTE; break;
+    case WXK_INSERT:    keySym = VK_INSERT; break;
+    case WXK_DELETE:    keySym = VK_DELETE; break;
+    case WXK_HELP :     keySym = VK_HELP; break;
+    case WXK_NUMPAD0:   keySym = VK_NUMPAD0; break;
+    case WXK_NUMPAD1:   keySym = VK_NUMPAD1; break;
+    case WXK_NUMPAD2:   keySym = VK_NUMPAD2; break;
+    case WXK_NUMPAD3:   keySym = VK_NUMPAD3; break;
+    case WXK_NUMPAD4:   keySym = VK_NUMPAD4; break;
+    case WXK_NUMPAD5:   keySym = VK_NUMPAD5; break;
+    case WXK_NUMPAD6:   keySym = VK_NUMPAD6; break;
+    case WXK_NUMPAD7:   keySym = VK_NUMPAD7; break;
+    case WXK_NUMPAD8:   keySym = VK_NUMPAD8; break;
+    case WXK_NUMPAD9:   keySym = VK_NUMPAD9; break;
+    case WXK_MULTIPLY:  keySym = VK_MULTIPLY; break;
+    case WXK_ADD:       keySym = VK_ADD; break;
+    case WXK_SUBTRACT:  keySym = VK_SUBTRACT; break;
+    case WXK_DECIMAL:   keySym = VK_DECIMAL; break;
+    case WXK_DIVIDE:    keySym = VK_DIVIDE; break;
+    case WXK_F1:        keySym = VK_F1; break;
+    case WXK_F2:        keySym = VK_F2; break;
+    case WXK_F3:        keySym = VK_F3; break;
+    case WXK_F4:        keySym = VK_F4; break;
+    case WXK_F5:        keySym = VK_F5; break;
+    case WXK_F6:        keySym = VK_F6; break;
+    case WXK_F7:        keySym = VK_F7; break;
+    case WXK_F8:        keySym = VK_F8; break;
+    case WXK_F9:        keySym = VK_F9; break;
+    case WXK_F10:       keySym = VK_F10; break;
+    case WXK_F11:       keySym = VK_F11; break;
+    case WXK_F12:       keySym = VK_F12; break;
+    case WXK_F13:       keySym = VK_F13; break;
+    case WXK_F14:       keySym = VK_F14; break;
+    case WXK_F15:       keySym = VK_F15; break;
+    case WXK_F16:       keySym = VK_F16; break;
+    case WXK_F17:       keySym = VK_F17; break;
+    case WXK_F18:       keySym = VK_F18; break;
+    case WXK_F19:       keySym = VK_F19; break;
+    case WXK_F20:       keySym = VK_F20; break;
+    case WXK_F21:       keySym = VK_F21; break;
+    case WXK_F22:       keySym = VK_F22; break;
+    case WXK_F23:       keySym = VK_F23; break;
+    case WXK_F24:       keySym = VK_F24; break;
+    case WXK_NUMLOCK:   keySym = VK_NUMLOCK; break;
+    case WXK_SCROLL:    keySym = VK_SCROLL; break;
+    default:
+        {
+            *isVirtual = FALSE;
+            keySym = id;
+            break;
+        }
     }
-    return NULL;
-}
-
-// If nothing defined for this, try the parent.
-// E.g. we may be a button loaded from a resource, with no callback function
-// defined.
-void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
-{
-    if ( GetEventHandler()->ProcessEvent(event)  )
-        return;
-    if ( m_parent )
-        m_parent->GetEventHandler()->OnCommand(win, event);
+    return keySym;
 }
 
-wxObject* wxWindow::GetChild(int number) const
+wxWindow *wxGetActiveWindow()
 {
-    // Return a pointer to the Nth object in the Panel
-//    if ( !GetChildren() )
-//        return(NULL) ;
-    wxNode *node = GetChildren().First();
-    int n = number;
-    while (node && n--)
-        node = node->Next() ;
-    if ( node )
+    HWND hWnd = GetActiveWindow();
+    if ( hWnd != 0 )
     {
-        wxObject *obj = (wxObject *)node->Data();
-        return(obj) ;
+        return wxFindWinFromHandle((WXHWND) hWnd);
     }
-    else
-        return NULL ;
+    return NULL;
 }
 
-void wxWindow::OnDefaultAction(wxControl *initiatingItem)
-{
-/* This is obsolete now; if we wish to intercept listbox double-clicks,
-* we explicitly intercept the wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
-* event.
-
-  if ( initiatingItem->IsKindOf(CLASSINFO(wxListBox)) )
-  {
-  wxListBox *lbox = (wxListBox *)initiatingItem;
-  wxCommandEvent event(wxEVT_COMMAND_LEFT_DCLICK);
-  event.m_commandInt = -1;
-  if ( (lbox->GetWindowStyleFlag() & wxLB_MULTIPLE) == 0 )
-  {
-  event.m_commandString = copystring(lbox->GetStringSelection());
-  event.m_commandInt = lbox->GetSelection();
-  event.m_clientData = lbox->wxListBox::GetClientData(event.m_commandInt);
-  }
-  event.m_eventObject = lbox;
-
-    lbox->ProcessCommand(event);
-
-      if ( event.m_commandString )
-      delete[] event.m_commandString;
-      return;
-      }
-
-        wxButton *but = GetDefaultItem();
-        if ( but )
-        {
-        wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
-        event.SetEventObject(but);
-        but->Command(event);
-        }
-    */
-}
+// Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
+// in active frames and dialogs, regardless of where the focus is.
+static HHOOK wxTheKeyboardHook = 0;
+static FARPROC wxTheKeyboardHookProc = 0;
+int APIENTRY _EXPORT
+wxKeyboardHook(int nCode, WORD wParam, DWORD lParam);
 
-void wxWindow::Clear()
+void wxSetKeyboardHook(bool doIt)
 {
-    wxClientDC dc(this);
-    wxBrush brush(GetBackgroundColour(), wxSOLID);
-    dc.SetBackground(brush);
-    dc.Clear();
-}
-
-/* TODO
-// Default input behaviour for a scrolling canvas should be to scroll
-// according to the cursor keys pressed
-void wxWindow::OnChar(wxKeyEvent& event)
-{
-int x_page = 0;
-int y_page = 0;
-int start_x = 0;
-int start_y = 0;
-// Bugfix Begin
-int v_width = 0;
-int v_height = 0;
-int y_pages = 0;
-// Bugfix End
-
-  GetScrollUnitsPerPage(&x_page, &y_page);
-  // Bugfix Begin
-  GetVirtualSize(&v_width,&v_height);
-  // Bugfix End
-  ViewStart(&start_x, &start_y);
-  // Bugfix begin
-  if ( vert_units )
-  y_pages = (int)(v_height/vert_units) - y_page;
-
-    #ifdef __WXMSW__
-    int y = 0;
-    #else
-    int y = y_page-1;
-    #endif
-    // Bugfix End
-    switch (event.keyCode)
-    {
-    case WXK_PRIOR:
-    {
-    // BugFix Begin
-    if ( y_page > 0 )
+    if ( doIt )
     {
-    if ( start_y - y_page > 0 )
-    Scroll(start_x, start_y - y_page);
-    else
-    Scroll(start_x, 0);
-    }
-    // Bugfix End
-    break;
+        wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
+        wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
+#if defined(__WIN32__) && !defined(__TWIN32__)
+            GetCurrentThreadId());
+        //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
+#else
+        GetCurrentTask());
+#endif
     }
-    case WXK_NEXT:
-    {
-    // Bugfix Begin
-    if ( (y_page > 0)  && (start_y <= y_pages-y-1) )
-    {
-    if ( y_pages + y < start_y + y_page )
-    Scroll(start_x, y_pages + y);
     else
-    Scroll(start_x, start_y + y_page);
-    }
-    // Bugfix End
-    break;
-    }
-    case WXK_UP:
-    {
-    if ( (y_page > 0) && (start_y >= 1) )
-    Scroll(start_x, start_y - 1);
-    break;
-    }
-    case WXK_DOWN:
-    {
-    // Bugfix Begin
-    if ( (y_page > 0) && (start_y <= y_pages-y-1) )
-    // Bugfix End
-    {
-    Scroll(start_x, start_y + 1);
-    }
-    break;
-    }
-    case WXK_LEFT:
-    {
-    if ( (x_page > 0) && (start_x >= 1) )
-    Scroll(start_x - 1, start_y);
-    break;
-    }
-    case WXK_RIGHT:
-    {
-    if ( x_page > 0 )
-    Scroll(start_x + 1, start_y);
-    break;
-    }
-    case WXK_HOME:
-    {
-    Scroll(0, 0);
-    break;
-    }
-    // This is new
-    case WXK_END:
     {
-    Scroll(start_x, y_pages+y);
-    break;
-    }
-    // end
-    }
+        UnhookWindowsHookEx(wxTheKeyboardHook);
+        FreeProcInstance(wxTheKeyboardHookProc);
     }
-*/
-
-// Setup background and foreground colours correctly
-void wxWindow::SetupColours()
-{
-    if ( GetParent() )
-        SetBackgroundColour(GetParent()->GetBackgroundColour());
 }
 
-void wxWindow::OnIdle(wxIdleEvent& event)
+int APIENTRY _EXPORT
+wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
 {
-    // Check if we need to send a LEAVE event
-    if ( m_mouseInWindow )
+    DWORD hiWord = HIWORD(lParam);
+    if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) )
     {
-        POINT pt;
-        ::GetCursorPos(&pt);
-        if ( ::WindowFromPoint(pt) != GetHwnd() )
+        int id;
+        if ( (id = wxCharCodeMSWToWX(wParam)) != 0 )
         {
-            // Generate a LEAVE event
-            m_mouseInWindow = FALSE;
-
-            // Unfortunately the mouse button and keyboard state may have changed
-            // by the time the OnIdle function is called, so 'state' may be
-            // meaningless.
-            int state = 0;
-            if ( ::GetKeyState(VK_SHIFT) != 0 )
-                state |= MK_SHIFT;
-            if ( ::GetKeyState(VK_CONTROL) != 0 )
-                state |= MK_CONTROL;
+            wxKeyEvent event(wxEVT_CHAR_HOOK);
+            if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+                event.m_altDown = TRUE;
 
-            wxMouseEvent event(wxEVT_LEAVE_WINDOW);
-            InitMouseEvent(event, pt.x, pt.y, state);
+            event.m_eventObject = NULL;
+            event.m_keyCode = id;
+            /* begin Albert's fix for control and shift key 26.5 */
+            event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
+            event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
+            /* end Albert's fix for control and shift key 26.5 */
+            event.SetTimestamp(s_currentMsg.time);
 
-            (void)GetEventHandler()->ProcessEvent(event);
+            wxWindow *win = wxGetActiveWindow();
+            if ( win )
+            {
+                if ( win->GetEventHandler()->ProcessEvent(event) )
+                    return 1;
+            }
+            else
+            {
+                if ( wxTheApp && wxTheApp->ProcessEvent(event) )
+                    return 1;
+            }
         }
     }
-
-    UpdateWindowUI();
-}
-
-// Raise the window to the top of the Z order
-void wxWindow::Raise()
-{
-    ::BringWindowToTop(GetHwnd());
-}
-
-// Lower the window to the bottom of the Z order
-void wxWindow::Lower()
-{
-    ::SetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
-}
-
-// Set this window to be the child of 'parent'.
-bool wxWindow::Reparent(wxWindow *parent)
-{
-    if ( !wxWindowBase::Reparent(parent) )
-        return FALSE;
-
-    HWND hWndChild = GetHwnd();
-    HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
-
-    ::SetParent(hWndChild, hWndParent);
-
-    return TRUE;
+    return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam);
 }
 
 #ifdef __WXDEBUG__
 const char *wxGetMessageName(int message)
 {
-    switch ( message ) {
-    case 0x0000: return "WM_NULL";
-    case 0x0001: return "WM_CREATE";
-    case 0x0002: return "WM_DESTROY";
-    case 0x0003: return "WM_MOVE";
-    case 0x0005: return "WM_SIZE";
-    case 0x0006: return "WM_ACTIVATE";
-    case 0x0007: return "WM_SETFOCUS";
-    case 0x0008: return "WM_KILLFOCUS";
-    case 0x000A: return "WM_ENABLE";
-    case 0x000B: return "WM_SETREDRAW";
-    case 0x000C: return "WM_SETTEXT";
-    case 0x000D: return "WM_GETTEXT";
-    case 0x000E: return "WM_GETTEXTLENGTH";
-    case 0x000F: return "WM_PAINT";
-    case 0x0010: return "WM_CLOSE";
-    case 0x0011: return "WM_QUERYENDSESSION";
-    case 0x0012: return "WM_QUIT";
-    case 0x0013: return "WM_QUERYOPEN";
-    case 0x0014: return "WM_ERASEBKGND";
-    case 0x0015: return "WM_SYSCOLORCHANGE";
-    case 0x0016: return "WM_ENDSESSION";
-    case 0x0017: return "WM_SYSTEMERROR";
-    case 0x0018: return "WM_SHOWWINDOW";
-    case 0x0019: return "WM_CTLCOLOR";
-    case 0x001A: return "WM_WININICHANGE";
-    case 0x001B: return "WM_DEVMODECHANGE";
-    case 0x001C: return "WM_ACTIVATEAPP";
-    case 0x001D: return "WM_FONTCHANGE";
-    case 0x001E: return "WM_TIMECHANGE";
-    case 0x001F: return "WM_CANCELMODE";
-    case 0x0020: return "WM_SETCURSOR";
-    case 0x0021: return "WM_MOUSEACTIVATE";
-    case 0x0022: return "WM_CHILDACTIVATE";
-    case 0x0023: return "WM_QUEUESYNC";
-    case 0x0024: return "WM_GETMINMAXINFO";
-    case 0x0026: return "WM_PAINTICON";
-    case 0x0027: return "WM_ICONERASEBKGND";
-    case 0x0028: return "WM_NEXTDLGCTL";
-    case 0x002A: return "WM_SPOOLERSTATUS";
-    case 0x002B: return "WM_DRAWITEM";
-    case 0x002C: return "WM_MEASUREITEM";
-    case 0x002D: return "WM_DELETEITEM";
-    case 0x002E: return "WM_VKEYTOITEM";
-    case 0x002F: return "WM_CHARTOITEM";
-    case 0x0030: return "WM_SETFONT";
-    case 0x0031: return "WM_GETFONT";
-    case 0x0037: return "WM_QUERYDRAGICON";
-    case 0x0039: return "WM_COMPAREITEM";
-    case 0x0041: return "WM_COMPACTING";
-    case 0x0044: return "WM_COMMNOTIFY";
-    case 0x0046: return "WM_WINDOWPOSCHANGING";
-    case 0x0047: return "WM_WINDOWPOSCHANGED";
-    case 0x0048: return "WM_POWER";
+    switch ( message )
+    {
+        case 0x0000: return "WM_NULL";
+        case 0x0001: return "WM_CREATE";
+        case 0x0002: return "WM_DESTROY";
+        case 0x0003: return "WM_MOVE";
+        case 0x0005: return "WM_SIZE";
+        case 0x0006: return "WM_ACTIVATE";
+        case 0x0007: return "WM_SETFOCUS";
+        case 0x0008: return "WM_KILLFOCUS";
+        case 0x000A: return "WM_ENABLE";
+        case 0x000B: return "WM_SETREDRAW";
+        case 0x000C: return "WM_SETTEXT";
+        case 0x000D: return "WM_GETTEXT";
+        case 0x000E: return "WM_GETTEXTLENGTH";
+        case 0x000F: return "WM_PAINT";
+        case 0x0010: return "WM_CLOSE";
+        case 0x0011: return "WM_QUERYENDSESSION";
+        case 0x0012: return "WM_QUIT";
+        case 0x0013: return "WM_QUERYOPEN";
+        case 0x0014: return "WM_ERASEBKGND";
+        case 0x0015: return "WM_SYSCOLORCHANGE";
+        case 0x0016: return "WM_ENDSESSION";
+        case 0x0017: return "WM_SYSTEMERROR";
+        case 0x0018: return "WM_SHOWWINDOW";
+        case 0x0019: return "WM_CTLCOLOR";
+        case 0x001A: return "WM_WININICHANGE";
+        case 0x001B: return "WM_DEVMODECHANGE";
+        case 0x001C: return "WM_ACTIVATEAPP";
+        case 0x001D: return "WM_FONTCHANGE";
+        case 0x001E: return "WM_TIMECHANGE";
+        case 0x001F: return "WM_CANCELMODE";
+        case 0x0020: return "WM_SETCURSOR";
+        case 0x0021: return "WM_MOUSEACTIVATE";
+        case 0x0022: return "WM_CHILDACTIVATE";
+        case 0x0023: return "WM_QUEUESYNC";
+        case 0x0024: return "WM_GETMINMAXINFO";
+        case 0x0026: return "WM_PAINTICON";
+        case 0x0027: return "WM_ICONERASEBKGND";
+        case 0x0028: return "WM_NEXTDLGCTL";
+        case 0x002A: return "WM_SPOOLERSTATUS";
+        case 0x002B: return "WM_DRAWITEM";
+        case 0x002C: return "WM_MEASUREITEM";
+        case 0x002D: return "WM_DELETEITEM";
+        case 0x002E: return "WM_VKEYTOITEM";
+        case 0x002F: return "WM_CHARTOITEM";
+        case 0x0030: return "WM_SETFONT";
+        case 0x0031: return "WM_GETFONT";
+        case 0x0037: return "WM_QUERYDRAGICON";
+        case 0x0039: return "WM_COMPAREITEM";
+        case 0x0041: return "WM_COMPACTING";
+        case 0x0044: return "WM_COMMNOTIFY";
+        case 0x0046: return "WM_WINDOWPOSCHANGING";
+        case 0x0047: return "WM_WINDOWPOSCHANGED";
+        case 0x0048: return "WM_POWER";
 
 #ifdef  __WIN32__
-    case 0x004A: return "WM_COPYDATA";
-    case 0x004B: return "WM_CANCELJOURNAL";
-    case 0x004E: return "WM_NOTIFY";
-    case 0x0050: return "WM_INPUTLANGCHANGEREQUEST";
-    case 0x0051: return "WM_INPUTLANGCHANGE";
-    case 0x0052: return "WM_TCARD";
-    case 0x0053: return "WM_HELP";
-    case 0x0054: return "WM_USERCHANGED";
-    case 0x0055: return "WM_NOTIFYFORMAT";
-    case 0x007B: return "WM_CONTEXTMENU";
-    case 0x007C: return "WM_STYLECHANGING";
-    case 0x007D: return "WM_STYLECHANGED";
-    case 0x007E: return "WM_DISPLAYCHANGE";
-    case 0x007F: return "WM_GETICON";
-    case 0x0080: return "WM_SETICON";
+        case 0x004A: return "WM_COPYDATA";
+        case 0x004B: return "WM_CANCELJOURNAL";
+        case 0x004E: return "WM_NOTIFY";
+        case 0x0050: return "WM_INPUTLANGCHANGEREQUEST";
+        case 0x0051: return "WM_INPUTLANGCHANGE";
+        case 0x0052: return "WM_TCARD";
+        case 0x0053: return "WM_HELP";
+        case 0x0054: return "WM_USERCHANGED";
+        case 0x0055: return "WM_NOTIFYFORMAT";
+        case 0x007B: return "WM_CONTEXTMENU";
+        case 0x007C: return "WM_STYLECHANGING";
+        case 0x007D: return "WM_STYLECHANGED";
+        case 0x007E: return "WM_DISPLAYCHANGE";
+        case 0x007F: return "WM_GETICON";
+        case 0x0080: return "WM_SETICON";
 #endif  //WIN32
 
-    case 0x0081: return "WM_NCCREATE";
-    case 0x0082: return "WM_NCDESTROY";
-    case 0x0083: return "WM_NCCALCSIZE";
-    case 0x0084: return "WM_NCHITTEST";
-    case 0x0085: return "WM_NCPAINT";
-    case 0x0086: return "WM_NCACTIVATE";
-    case 0x0087: return "WM_GETDLGCODE";
-    case 0x00A0: return "WM_NCMOUSEMOVE";
-    case 0x00A1: return "WM_NCLBUTTONDOWN";
-    case 0x00A2: return "WM_NCLBUTTONUP";
-    case 0x00A3: return "WM_NCLBUTTONDBLCLK";
-    case 0x00A4: return "WM_NCRBUTTONDOWN";
-    case 0x00A5: return "WM_NCRBUTTONUP";
-    case 0x00A6: return "WM_NCRBUTTONDBLCLK";
-    case 0x00A7: return "WM_NCMBUTTONDOWN";
-    case 0x00A8: return "WM_NCMBUTTONUP";
-    case 0x00A9: return "WM_NCMBUTTONDBLCLK";
-    case 0x0100: return "WM_KEYDOWN";
-    case 0x0101: return "WM_KEYUP";
-    case 0x0102: return "WM_CHAR";
-    case 0x0103: return "WM_DEADCHAR";
-    case 0x0104: return "WM_SYSKEYDOWN";
-    case 0x0105: return "WM_SYSKEYUP";
-    case 0x0106: return "WM_SYSCHAR";
-    case 0x0107: return "WM_SYSDEADCHAR";
-    case 0x0108: return "WM_KEYLAST";
+        case 0x0081: return "WM_NCCREATE";
+        case 0x0082: return "WM_NCDESTROY";
+        case 0x0083: return "WM_NCCALCSIZE";
+        case 0x0084: return "WM_NCHITTEST";
+        case 0x0085: return "WM_NCPAINT";
+        case 0x0086: return "WM_NCACTIVATE";
+        case 0x0087: return "WM_GETDLGCODE";
+        case 0x00A0: return "WM_NCMOUSEMOVE";
+        case 0x00A1: return "WM_NCLBUTTONDOWN";
+        case 0x00A2: return "WM_NCLBUTTONUP";
+        case 0x00A3: return "WM_NCLBUTTONDBLCLK";
+        case 0x00A4: return "WM_NCRBUTTONDOWN";
+        case 0x00A5: return "WM_NCRBUTTONUP";
+        case 0x00A6: return "WM_NCRBUTTONDBLCLK";
+        case 0x00A7: return "WM_NCMBUTTONDOWN";
+        case 0x00A8: return "WM_NCMBUTTONUP";
+        case 0x00A9: return "WM_NCMBUTTONDBLCLK";
+        case 0x0100: return "WM_KEYDOWN";
+        case 0x0101: return "WM_KEYUP";
+        case 0x0102: return "WM_CHAR";
+        case 0x0103: return "WM_DEADCHAR";
+        case 0x0104: return "WM_SYSKEYDOWN";
+        case 0x0105: return "WM_SYSKEYUP";
+        case 0x0106: return "WM_SYSCHAR";
+        case 0x0107: return "WM_SYSDEADCHAR";
+        case 0x0108: return "WM_KEYLAST";
 
 #ifdef  __WIN32__
-    case 0x010D: return "WM_IME_STARTCOMPOSITION";
-    case 0x010E: return "WM_IME_ENDCOMPOSITION";
-    case 0x010F: return "WM_IME_COMPOSITION";
+        case 0x010D: return "WM_IME_STARTCOMPOSITION";
+        case 0x010E: return "WM_IME_ENDCOMPOSITION";
+        case 0x010F: return "WM_IME_COMPOSITION";
 #endif  //WIN32
 
-    case 0x0110: return "WM_INITDIALOG";
-    case 0x0111: return "WM_COMMAND";
-    case 0x0112: return "WM_SYSCOMMAND";
-    case 0x0113: return "WM_TIMER";
-    case 0x0114: return "WM_HSCROLL";
-    case 0x0115: return "WM_VSCROLL";
-    case 0x0116: return "WM_INITMENU";
-    case 0x0117: return "WM_INITMENUPOPUP";
-    case 0x011F: return "WM_MENUSELECT";
-    case 0x0120: return "WM_MENUCHAR";
-    case 0x0121: return "WM_ENTERIDLE";
-    case 0x0200: return "WM_MOUSEMOVE";
-    case 0x0201: return "WM_LBUTTONDOWN";
-    case 0x0202: return "WM_LBUTTONUP";
-    case 0x0203: return "WM_LBUTTONDBLCLK";
-    case 0x0204: return "WM_RBUTTONDOWN";
-    case 0x0205: return "WM_RBUTTONUP";
-    case 0x0206: return "WM_RBUTTONDBLCLK";
-    case 0x0207: return "WM_MBUTTONDOWN";
-    case 0x0208: return "WM_MBUTTONUP";
-    case 0x0209: return "WM_MBUTTONDBLCLK";
-    case 0x0210: return "WM_PARENTNOTIFY";
-    case 0x0211: return "WM_ENTERMENULOOP";
-    case 0x0212: return "WM_EXITMENULOOP";
+        case 0x0110: return "WM_INITDIALOG";
+        case 0x0111: return "WM_COMMAND";
+        case 0x0112: return "WM_SYSCOMMAND";
+        case 0x0113: return "WM_TIMER";
+        case 0x0114: return "WM_HSCROLL";
+        case 0x0115: return "WM_VSCROLL";
+        case 0x0116: return "WM_INITMENU";
+        case 0x0117: return "WM_INITMENUPOPUP";
+        case 0x011F: return "WM_MENUSELECT";
+        case 0x0120: return "WM_MENUCHAR";
+        case 0x0121: return "WM_ENTERIDLE";
+        case 0x0200: return "WM_MOUSEMOVE";
+        case 0x0201: return "WM_LBUTTONDOWN";
+        case 0x0202: return "WM_LBUTTONUP";
+        case 0x0203: return "WM_LBUTTONDBLCLK";
+        case 0x0204: return "WM_RBUTTONDOWN";
+        case 0x0205: return "WM_RBUTTONUP";
+        case 0x0206: return "WM_RBUTTONDBLCLK";
+        case 0x0207: return "WM_MBUTTONDOWN";
+        case 0x0208: return "WM_MBUTTONUP";
+        case 0x0209: return "WM_MBUTTONDBLCLK";
+        case 0x0210: return "WM_PARENTNOTIFY";
+        case 0x0211: return "WM_ENTERMENULOOP";
+        case 0x0212: return "WM_EXITMENULOOP";
 
 #ifdef  __WIN32__
-    case 0x0213: return "WM_NEXTMENU";
-    case 0x0214: return "WM_SIZING";
-    case 0x0215: return "WM_CAPTURECHANGED";
-    case 0x0216: return "WM_MOVING";
-    case 0x0218: return "WM_POWERBROADCAST";
-    case 0x0219: return "WM_DEVICECHANGE";
+        case 0x0213: return "WM_NEXTMENU";
+        case 0x0214: return "WM_SIZING";
+        case 0x0215: return "WM_CAPTURECHANGED";
+        case 0x0216: return "WM_MOVING";
+        case 0x0218: return "WM_POWERBROADCAST";
+        case 0x0219: return "WM_DEVICECHANGE";
 #endif  //WIN32
 
-    case 0x0220: return "WM_MDICREATE";
-    case 0x0221: return "WM_MDIDESTROY";
-    case 0x0222: return "WM_MDIACTIVATE";
-    case 0x0223: return "WM_MDIRESTORE";
-    case 0x0224: return "WM_MDINEXT";
-    case 0x0225: return "WM_MDIMAXIMIZE";
-    case 0x0226: return "WM_MDITILE";
-    case 0x0227: return "WM_MDICASCADE";
-    case 0x0228: return "WM_MDIICONARRANGE";
-    case 0x0229: return "WM_MDIGETACTIVE";
-    case 0x0230: return "WM_MDISETMENU";
-    case 0x0233: return "WM_DROPFILES";
+        case 0x0220: return "WM_MDICREATE";
+        case 0x0221: return "WM_MDIDESTROY";
+        case 0x0222: return "WM_MDIACTIVATE";
+        case 0x0223: return "WM_MDIRESTORE";
+        case 0x0224: return "WM_MDINEXT";
+        case 0x0225: return "WM_MDIMAXIMIZE";
+        case 0x0226: return "WM_MDITILE";
+        case 0x0227: return "WM_MDICASCADE";
+        case 0x0228: return "WM_MDIICONARRANGE";
+        case 0x0229: return "WM_MDIGETACTIVE";
+        case 0x0230: return "WM_MDISETMENU";
+        case 0x0233: return "WM_DROPFILES";
 
 #ifdef  __WIN32__
-    case 0x0281: return "WM_IME_SETCONTEXT";
-    case 0x0282: return "WM_IME_NOTIFY";
-    case 0x0283: return "WM_IME_CONTROL";
-    case 0x0284: return "WM_IME_COMPOSITIONFULL";
-    case 0x0285: return "WM_IME_SELECT";
-    case 0x0286: return "WM_IME_CHAR";
-    case 0x0290: return "WM_IME_KEYDOWN";
-    case 0x0291: return "WM_IME_KEYUP";
+        case 0x0281: return "WM_IME_SETCONTEXT";
+        case 0x0282: return "WM_IME_NOTIFY";
+        case 0x0283: return "WM_IME_CONTROL";
+        case 0x0284: return "WM_IME_COMPOSITIONFULL";
+        case 0x0285: return "WM_IME_SELECT";
+        case 0x0286: return "WM_IME_CHAR";
+        case 0x0290: return "WM_IME_KEYDOWN";
+        case 0x0291: return "WM_IME_KEYUP";
 #endif  //WIN32
 
-    case 0x0300: return "WM_CUT";
-    case 0x0301: return "WM_COPY";
-    case 0x0302: return "WM_PASTE";
-    case 0x0303: return "WM_CLEAR";
-    case 0x0304: return "WM_UNDO";
-    case 0x0305: return "WM_RENDERFORMAT";
-    case 0x0306: return "WM_RENDERALLFORMATS";
-    case 0x0307: return "WM_DESTROYCLIPBOARD";
-    case 0x0308: return "WM_DRAWCLIPBOARD";
-    case 0x0309: return "WM_PAINTCLIPBOARD";
-    case 0x030A: return "WM_VSCROLLCLIPBOARD";
-    case 0x030B: return "WM_SIZECLIPBOARD";
-    case 0x030C: return "WM_ASKCBFORMATNAME";
-    case 0x030D: return "WM_CHANGECBCHAIN";
-    case 0x030E: return "WM_HSCROLLCLIPBOARD";
-    case 0x030F: return "WM_QUERYNEWPALETTE";
-    case 0x0310: return "WM_PALETTEISCHANGING";
-    case 0x0311: return "WM_PALETTECHANGED";
+        case 0x0300: return "WM_CUT";
+        case 0x0301: return "WM_COPY";
+        case 0x0302: return "WM_PASTE";
+        case 0x0303: return "WM_CLEAR";
+        case 0x0304: return "WM_UNDO";
+        case 0x0305: return "WM_RENDERFORMAT";
+        case 0x0306: return "WM_RENDERALLFORMATS";
+        case 0x0307: return "WM_DESTROYCLIPBOARD";
+        case 0x0308: return "WM_DRAWCLIPBOARD";
+        case 0x0309: return "WM_PAINTCLIPBOARD";
+        case 0x030A: return "WM_VSCROLLCLIPBOARD";
+        case 0x030B: return "WM_SIZECLIPBOARD";
+        case 0x030C: return "WM_ASKCBFORMATNAME";
+        case 0x030D: return "WM_CHANGECBCHAIN";
+        case 0x030E: return "WM_HSCROLLCLIPBOARD";
+        case 0x030F: return "WM_QUERYNEWPALETTE";
+        case 0x0310: return "WM_PALETTEISCHANGING";
+        case 0x0311: return "WM_PALETTECHANGED";
 
 #ifdef __WIN32__
         // common controls messages - although they're not strictly speaking
         // standard, it's nice to decode them nevertheless
 
         // listview
-    case 0x1000 + 0: return "LVM_GETBKCOLOR";
-    case 0x1000 + 1: return "LVM_SETBKCOLOR";
-    case 0x1000 + 2: return "LVM_GETIMAGELIST";
-    case 0x1000 + 3: return "LVM_SETIMAGELIST";
-    case 0x1000 + 4: return "LVM_GETITEMCOUNT";
-    case 0x1000 + 5: return "LVM_GETITEMA";
-    case 0x1000 + 75: return "LVM_GETITEMW";
-    case 0x1000 + 6: return "LVM_SETITEMA";
-    case 0x1000 + 76: return "LVM_SETITEMW";
-    case 0x1000 + 7: return "LVM_INSERTITEMA";
-    case 0x1000 + 77: return "LVM_INSERTITEMW";
-    case 0x1000 + 8: return "LVM_DELETEITEM";
-    case 0x1000 + 9: return "LVM_DELETEALLITEMS";
-    case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
-    case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
-    case 0x1000 + 12: return "LVM_GETNEXTITEM";
-    case 0x1000 + 13: return "LVM_FINDITEMA";
-    case 0x1000 + 83: return "LVM_FINDITEMW";
-    case 0x1000 + 14: return "LVM_GETITEMRECT";
-    case 0x1000 + 15: return "LVM_SETITEMPOSITION";
-    case 0x1000 + 16: return "LVM_GETITEMPOSITION";
-    case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
-    case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
-    case 0x1000 + 18: return "LVM_HITTEST";
-    case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
-    case 0x1000 + 20: return "LVM_SCROLL";
-    case 0x1000 + 21: return "LVM_REDRAWITEMS";
-    case 0x1000 + 22: return "LVM_ARRANGE";
-    case 0x1000 + 23: return "LVM_EDITLABELA";
-    case 0x1000 + 118: return "LVM_EDITLABELW";
-    case 0x1000 + 24: return "LVM_GETEDITCONTROL";
-    case 0x1000 + 25: return "LVM_GETCOLUMNA";
-    case 0x1000 + 95: return "LVM_GETCOLUMNW";
-    case 0x1000 + 26: return "LVM_SETCOLUMNA";
-    case 0x1000 + 96: return "LVM_SETCOLUMNW";
-    case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
-    case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
-    case 0x1000 + 28: return "LVM_DELETECOLUMN";
-    case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
-    case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
-    case 0x1000 + 31: return "LVM_GETHEADER";
-    case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
-    case 0x1000 + 34: return "LVM_GETVIEWRECT";
-    case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
-    case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
-    case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
-    case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
-    case 0x1000 + 39: return "LVM_GETTOPINDEX";
-    case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
-    case 0x1000 + 41: return "LVM_GETORIGIN";
-    case 0x1000 + 42: return "LVM_UPDATE";
-    case 0x1000 + 43: return "LVM_SETITEMSTATE";
-    case 0x1000 + 44: return "LVM_GETITEMSTATE";
-    case 0x1000 + 45: return "LVM_GETITEMTEXTA";
-    case 0x1000 + 115: return "LVM_GETITEMTEXTW";
-    case 0x1000 + 46: return "LVM_SETITEMTEXTA";
-    case 0x1000 + 116: return "LVM_SETITEMTEXTW";
-    case 0x1000 + 47: return "LVM_SETITEMCOUNT";
-    case 0x1000 + 48: return "LVM_SORTITEMS";
-    case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
-    case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
-    case 0x1000 + 51: return "LVM_GETITEMSPACING";
-    case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
-    case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
-    case 0x1000 + 53: return "LVM_SETICONSPACING";
-    case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
-    case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
-    case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
-    case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
-    case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
-    case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
-    case 0x1000 + 60: return "LVM_SETHOTITEM";
-    case 0x1000 + 61: return "LVM_GETHOTITEM";
-    case 0x1000 + 62: return "LVM_SETHOTCURSOR";
-    case 0x1000 + 63: return "LVM_GETHOTCURSOR";
-    case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
-    case 0x1000 + 65: return "LVM_SETWORKAREA";
+        case 0x1000 + 0: return "LVM_GETBKCOLOR";
+        case 0x1000 + 1: return "LVM_SETBKCOLOR";
+        case 0x1000 + 2: return "LVM_GETIMAGELIST";
+        case 0x1000 + 3: return "LVM_SETIMAGELIST";
+        case 0x1000 + 4: return "LVM_GETITEMCOUNT";
+        case 0x1000 + 5: return "LVM_GETITEMA";
+        case 0x1000 + 75: return "LVM_GETITEMW";
+        case 0x1000 + 6: return "LVM_SETITEMA";
+        case 0x1000 + 76: return "LVM_SETITEMW";
+        case 0x1000 + 7: return "LVM_INSERTITEMA";
+        case 0x1000 + 77: return "LVM_INSERTITEMW";
+        case 0x1000 + 8: return "LVM_DELETEITEM";
+        case 0x1000 + 9: return "LVM_DELETEALLITEMS";
+        case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
+        case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
+        case 0x1000 + 12: return "LVM_GETNEXTITEM";
+        case 0x1000 + 13: return "LVM_FINDITEMA";
+        case 0x1000 + 83: return "LVM_FINDITEMW";
+        case 0x1000 + 14: return "LVM_GETITEMRECT";
+        case 0x1000 + 15: return "LVM_SETITEMPOSITION";
+        case 0x1000 + 16: return "LVM_GETITEMPOSITION";
+        case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
+        case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
+        case 0x1000 + 18: return "LVM_HITTEST";
+        case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
+        case 0x1000 + 20: return "LVM_SCROLL";
+        case 0x1000 + 21: return "LVM_REDRAWITEMS";
+        case 0x1000 + 22: return "LVM_ARRANGE";
+        case 0x1000 + 23: return "LVM_EDITLABELA";
+        case 0x1000 + 118: return "LVM_EDITLABELW";
+        case 0x1000 + 24: return "LVM_GETEDITCONTROL";
+        case 0x1000 + 25: return "LVM_GETCOLUMNA";
+        case 0x1000 + 95: return "LVM_GETCOLUMNW";
+        case 0x1000 + 26: return "LVM_SETCOLUMNA";
+        case 0x1000 + 96: return "LVM_SETCOLUMNW";
+        case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
+        case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
+        case 0x1000 + 28: return "LVM_DELETECOLUMN";
+        case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
+        case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
+        case 0x1000 + 31: return "LVM_GETHEADER";
+        case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
+        case 0x1000 + 34: return "LVM_GETVIEWRECT";
+        case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
+        case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
+        case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
+        case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
+        case 0x1000 + 39: return "LVM_GETTOPINDEX";
+        case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
+        case 0x1000 + 41: return "LVM_GETORIGIN";
+        case 0x1000 + 42: return "LVM_UPDATE";
+        case 0x1000 + 43: return "LVM_SETITEMSTATE";
+        case 0x1000 + 44: return "LVM_GETITEMSTATE";
+        case 0x1000 + 45: return "LVM_GETITEMTEXTA";
+        case 0x1000 + 115: return "LVM_GETITEMTEXTW";
+        case 0x1000 + 46: return "LVM_SETITEMTEXTA";
+        case 0x1000 + 116: return "LVM_SETITEMTEXTW";
+        case 0x1000 + 47: return "LVM_SETITEMCOUNT";
+        case 0x1000 + 48: return "LVM_SORTITEMS";
+        case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
+        case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
+        case 0x1000 + 51: return "LVM_GETITEMSPACING";
+        case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
+        case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
+        case 0x1000 + 53: return "LVM_SETICONSPACING";
+        case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
+        case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
+        case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
+        case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
+        case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
+        case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
+        case 0x1000 + 60: return "LVM_SETHOTITEM";
+        case 0x1000 + 61: return "LVM_GETHOTITEM";
+        case 0x1000 + 62: return "LVM_SETHOTCURSOR";
+        case 0x1000 + 63: return "LVM_GETHOTCURSOR";
+        case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
+        case 0x1000 + 65: return "LVM_SETWORKAREA";
 
         // tree view
-    case 0x1100 + 0: return "TVM_INSERTITEMA";
-    case 0x1100 + 50: return "TVM_INSERTITEMW";
-    case 0x1100 + 1: return "TVM_DELETEITEM";
-    case 0x1100 + 2: return "TVM_EXPAND";
-    case 0x1100 + 4: return "TVM_GETITEMRECT";
-    case 0x1100 + 5: return "TVM_GETCOUNT";
-    case 0x1100 + 6: return "TVM_GETINDENT";
-    case 0x1100 + 7: return "TVM_SETINDENT";
-    case 0x1100 + 8: return "TVM_GETIMAGELIST";
-    case 0x1100 + 9: return "TVM_SETIMAGELIST";
-    case 0x1100 + 10: return "TVM_GETNEXTITEM";
-    case 0x1100 + 11: return "TVM_SELECTITEM";
-    case 0x1100 + 12: return "TVM_GETITEMA";
-    case 0x1100 + 62: return "TVM_GETITEMW";
-    case 0x1100 + 13: return "TVM_SETITEMA";
-    case 0x1100 + 63: return "TVM_SETITEMW";
-    case 0x1100 + 14: return "TVM_EDITLABELA";
-    case 0x1100 + 65: return "TVM_EDITLABELW";
-    case 0x1100 + 15: return "TVM_GETEDITCONTROL";
-    case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
-    case 0x1100 + 17: return "TVM_HITTEST";
-    case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
-    case 0x1100 + 19: return "TVM_SORTCHILDREN";
-    case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
-    case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
-    case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
-    case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
-    case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
-    case 0x1100 + 24: return "TVM_SETTOOLTIPS";
-    case 0x1100 + 25: return "TVM_GETTOOLTIPS";
+        case 0x1100 + 0: return "TVM_INSERTITEMA";
+        case 0x1100 + 50: return "TVM_INSERTITEMW";
+        case 0x1100 + 1: return "TVM_DELETEITEM";
+        case 0x1100 + 2: return "TVM_EXPAND";
+        case 0x1100 + 4: return "TVM_GETITEMRECT";
+        case 0x1100 + 5: return "TVM_GETCOUNT";
+        case 0x1100 + 6: return "TVM_GETINDENT";
+        case 0x1100 + 7: return "TVM_SETINDENT";
+        case 0x1100 + 8: return "TVM_GETIMAGELIST";
+        case 0x1100 + 9: return "TVM_SETIMAGELIST";
+        case 0x1100 + 10: return "TVM_GETNEXTITEM";
+        case 0x1100 + 11: return "TVM_SELECTITEM";
+        case 0x1100 + 12: return "TVM_GETITEMA";
+        case 0x1100 + 62: return "TVM_GETITEMW";
+        case 0x1100 + 13: return "TVM_SETITEMA";
+        case 0x1100 + 63: return "TVM_SETITEMW";
+        case 0x1100 + 14: return "TVM_EDITLABELA";
+        case 0x1100 + 65: return "TVM_EDITLABELW";
+        case 0x1100 + 15: return "TVM_GETEDITCONTROL";
+        case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
+        case 0x1100 + 17: return "TVM_HITTEST";
+        case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
+        case 0x1100 + 19: return "TVM_SORTCHILDREN";
+        case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
+        case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
+        case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
+        case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
+        case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
+        case 0x1100 + 24: return "TVM_SETTOOLTIPS";
+        case 0x1100 + 25: return "TVM_GETTOOLTIPS";
 
         // header
-    case 0x1200 + 0: return "HDM_GETITEMCOUNT";
-    case 0x1200 + 1: return "HDM_INSERTITEMA";
-    case 0x1200 + 10: return "HDM_INSERTITEMW";
-    case 0x1200 + 2: return "HDM_DELETEITEM";
-    case 0x1200 + 3: return "HDM_GETITEMA";
-    case 0x1200 + 11: return "HDM_GETITEMW";
-    case 0x1200 + 4: return "HDM_SETITEMA";
-    case 0x1200 + 12: return "HDM_SETITEMW";
-    case 0x1200 + 5: return "HDM_LAYOUT";
-    case 0x1200 + 6: return "HDM_HITTEST";
-    case 0x1200 + 7: return "HDM_GETITEMRECT";
-    case 0x1200 + 8: return "HDM_SETIMAGELIST";
-    case 0x1200 + 9: return "HDM_GETIMAGELIST";
-    case 0x1200 + 15: return "HDM_ORDERTOINDEX";
-    case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
-    case 0x1200 + 17: return "HDM_GETORDERARRAY";
-    case 0x1200 + 18: return "HDM_SETORDERARRAY";
-    case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
+        case 0x1200 + 0: return "HDM_GETITEMCOUNT";
+        case 0x1200 + 1: return "HDM_INSERTITEMA";
+        case 0x1200 + 10: return "HDM_INSERTITEMW";
+        case 0x1200 + 2: return "HDM_DELETEITEM";
+        case 0x1200 + 3: return "HDM_GETITEMA";
+        case 0x1200 + 11: return "HDM_GETITEMW";
+        case 0x1200 + 4: return "HDM_SETITEMA";
+        case 0x1200 + 12: return "HDM_SETITEMW";
+        case 0x1200 + 5: return "HDM_LAYOUT";
+        case 0x1200 + 6: return "HDM_HITTEST";
+        case 0x1200 + 7: return "HDM_GETITEMRECT";
+        case 0x1200 + 8: return "HDM_SETIMAGELIST";
+        case 0x1200 + 9: return "HDM_GETIMAGELIST";
+        case 0x1200 + 15: return "HDM_ORDERTOINDEX";
+        case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
+        case 0x1200 + 17: return "HDM_GETORDERARRAY";
+        case 0x1200 + 18: return "HDM_SETORDERARRAY";
+        case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
 
         // tab control
-    case 0x1300 + 2: return "TCM_GETIMAGELIST";
-    case 0x1300 + 3: return "TCM_SETIMAGELIST";
-    case 0x1300 + 4: return "TCM_GETITEMCOUNT";
-    case 0x1300 + 5: return "TCM_GETITEMA";
-    case 0x1300 + 60: return "TCM_GETITEMW";
-    case 0x1300 + 6: return "TCM_SETITEMA";
-    case 0x1300 + 61: return "TCM_SETITEMW";
-    case 0x1300 + 7: return "TCM_INSERTITEMA";
-    case 0x1300 + 62: return "TCM_INSERTITEMW";
-    case 0x1300 + 8: return "TCM_DELETEITEM";
-    case 0x1300 + 9: return "TCM_DELETEALLITEMS";
-    case 0x1300 + 10: return "TCM_GETITEMRECT";
-    case 0x1300 + 11: return "TCM_GETCURSEL";
-    case 0x1300 + 12: return "TCM_SETCURSEL";
-    case 0x1300 + 13: return "TCM_HITTEST";
-    case 0x1300 + 14: return "TCM_SETITEMEXTRA";
-    case 0x1300 + 40: return "TCM_ADJUSTRECT";
-    case 0x1300 + 41: return "TCM_SETITEMSIZE";
-    case 0x1300 + 42: return "TCM_REMOVEIMAGE";
-    case 0x1300 + 43: return "TCM_SETPADDING";
-    case 0x1300 + 44: return "TCM_GETROWCOUNT";
-    case 0x1300 + 45: return "TCM_GETTOOLTIPS";
-    case 0x1300 + 46: return "TCM_SETTOOLTIPS";
-    case 0x1300 + 47: return "TCM_GETCURFOCUS";
-    case 0x1300 + 48: return "TCM_SETCURFOCUS";
-    case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
-    case 0x1300 + 50: return "TCM_DESELECTALL";
+        case 0x1300 + 2: return "TCM_GETIMAGELIST";
+        case 0x1300 + 3: return "TCM_SETIMAGELIST";
+        case 0x1300 + 4: return "TCM_GETITEMCOUNT";
+        case 0x1300 + 5: return "TCM_GETITEMA";
+        case 0x1300 + 60: return "TCM_GETITEMW";
+        case 0x1300 + 6: return "TCM_SETITEMA";
+        case 0x1300 + 61: return "TCM_SETITEMW";
+        case 0x1300 + 7: return "TCM_INSERTITEMA";
+        case 0x1300 + 62: return "TCM_INSERTITEMW";
+        case 0x1300 + 8: return "TCM_DELETEITEM";
+        case 0x1300 + 9: return "TCM_DELETEALLITEMS";
+        case 0x1300 + 10: return "TCM_GETITEMRECT";
+        case 0x1300 + 11: return "TCM_GETCURSEL";
+        case 0x1300 + 12: return "TCM_SETCURSEL";
+        case 0x1300 + 13: return "TCM_HITTEST";
+        case 0x1300 + 14: return "TCM_SETITEMEXTRA";
+        case 0x1300 + 40: return "TCM_ADJUSTRECT";
+        case 0x1300 + 41: return "TCM_SETITEMSIZE";
+        case 0x1300 + 42: return "TCM_REMOVEIMAGE";
+        case 0x1300 + 43: return "TCM_SETPADDING";
+        case 0x1300 + 44: return "TCM_GETROWCOUNT";
+        case 0x1300 + 45: return "TCM_GETTOOLTIPS";
+        case 0x1300 + 46: return "TCM_SETTOOLTIPS";
+        case 0x1300 + 47: return "TCM_GETCURFOCUS";
+        case 0x1300 + 48: return "TCM_SETCURFOCUS";
+        case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
+        case 0x1300 + 50: return "TCM_DESELECTALL";
 
         // toolbar
-    case WM_USER+1: return "TB_ENABLEBUTTON";
-    case WM_USER+2: return "TB_CHECKBUTTON";
-    case WM_USER+3: return "TB_PRESSBUTTON";
-    case WM_USER+4: return "TB_HIDEBUTTON";
-    case WM_USER+5: return "TB_INDETERMINATE";
-    case WM_USER+9: return "TB_ISBUTTONENABLED";
-    case WM_USER+10: return "TB_ISBUTTONCHECKED";
-    case WM_USER+11: return "TB_ISBUTTONPRESSED";
-    case WM_USER+12: return "TB_ISBUTTONHIDDEN";
-    case WM_USER+13: return "TB_ISBUTTONINDETERMINATE";
-    case WM_USER+17: return "TB_SETSTATE";
-    case WM_USER+18: return "TB_GETSTATE";
-    case WM_USER+19: return "TB_ADDBITMAP";
-    case WM_USER+20: return "TB_ADDBUTTONS";
-    case WM_USER+21: return "TB_INSERTBUTTON";
-    case WM_USER+22: return "TB_DELETEBUTTON";
-    case WM_USER+23: return "TB_GETBUTTON";
-    case WM_USER+24: return "TB_BUTTONCOUNT";
-    case WM_USER+25: return "TB_COMMANDTOINDEX";
-    case WM_USER+26: return "TB_SAVERESTOREA";
-    case WM_USER+76: return "TB_SAVERESTOREW";
-    case WM_USER+27: return "TB_CUSTOMIZE";
-    case WM_USER+28: return "TB_ADDSTRINGA";
-    case WM_USER+77: return "TB_ADDSTRINGW";
-    case WM_USER+29: return "TB_GETITEMRECT";
-    case WM_USER+30: return "TB_BUTTONSTRUCTSIZE";
-    case WM_USER+31: return "TB_SETBUTTONSIZE";
-    case WM_USER+32: return "TB_SETBITMAPSIZE";
-    case WM_USER+33: return "TB_AUTOSIZE";
-    case WM_USER+35: return "TB_GETTOOLTIPS";
-    case WM_USER+36: return "TB_SETTOOLTIPS";
-    case WM_USER+37: return "TB_SETPARENT";
-    case WM_USER+39: return "TB_SETROWS";
-    case WM_USER+40: return "TB_GETROWS";
-    case WM_USER+42: return "TB_SETCMDID";
-    case WM_USER+43: return "TB_CHANGEBITMAP";
-    case WM_USER+44: return "TB_GETBITMAP";
-    case WM_USER+45: return "TB_GETBUTTONTEXTA";
-    case WM_USER+75: return "TB_GETBUTTONTEXTW";
-    case WM_USER+46: return "TB_REPLACEBITMAP";
-    case WM_USER+47: return "TB_SETINDENT";
-    case WM_USER+48: return "TB_SETIMAGELIST";
-    case WM_USER+49: return "TB_GETIMAGELIST";
-    case WM_USER+50: return "TB_LOADIMAGES";
-    case WM_USER+51: return "TB_GETRECT";
-    case WM_USER+52: return "TB_SETHOTIMAGELIST";
-    case WM_USER+53: return "TB_GETHOTIMAGELIST";
-    case WM_USER+54: return "TB_SETDISABLEDIMAGELIST";
-    case WM_USER+55: return "TB_GETDISABLEDIMAGELIST";
-    case WM_USER+56: return "TB_SETSTYLE";
-    case WM_USER+57: return "TB_GETSTYLE";
-    case WM_USER+58: return "TB_GETBUTTONSIZE";
-    case WM_USER+59: return "TB_SETBUTTONWIDTH";
-    case WM_USER+60: return "TB_SETMAXTEXTROWS";
-    case WM_USER+61: return "TB_GETTEXTROWS";
-    case WM_USER+41: return "TB_GETBITMAPFLAGS";
+        case WM_USER+1: return "TB_ENABLEBUTTON";
+        case WM_USER+2: return "TB_CHECKBUTTON";
+        case WM_USER+3: return "TB_PRESSBUTTON";
+        case WM_USER+4: return "TB_HIDEBUTTON";
+        case WM_USER+5: return "TB_INDETERMINATE";
+        case WM_USER+9: return "TB_ISBUTTONENABLED";
+        case WM_USER+10: return "TB_ISBUTTONCHECKED";
+        case WM_USER+11: return "TB_ISBUTTONPRESSED";
+        case WM_USER+12: return "TB_ISBUTTONHIDDEN";
+        case WM_USER+13: return "TB_ISBUTTONINDETERMINATE";
+        case WM_USER+17: return "TB_SETSTATE";
+        case WM_USER+18: return "TB_GETSTATE";
+        case WM_USER+19: return "TB_ADDBITMAP";
+        case WM_USER+20: return "TB_ADDBUTTONS";
+        case WM_USER+21: return "TB_INSERTBUTTON";
+        case WM_USER+22: return "TB_DELETEBUTTON";
+        case WM_USER+23: return "TB_GETBUTTON";
+        case WM_USER+24: return "TB_BUTTONCOUNT";
+        case WM_USER+25: return "TB_COMMANDTOINDEX";
+        case WM_USER+26: return "TB_SAVERESTOREA";
+        case WM_USER+76: return "TB_SAVERESTOREW";
+        case WM_USER+27: return "TB_CUSTOMIZE";
+        case WM_USER+28: return "TB_ADDSTRINGA";
+        case WM_USER+77: return "TB_ADDSTRINGW";
+        case WM_USER+29: return "TB_GETITEMRECT";
+        case WM_USER+30: return "TB_BUTTONSTRUCTSIZE";
+        case WM_USER+31: return "TB_SETBUTTONSIZE";
+        case WM_USER+32: return "TB_SETBITMAPSIZE";
+        case WM_USER+33: return "TB_AUTOSIZE";
+        case WM_USER+35: return "TB_GETTOOLTIPS";
+        case WM_USER+36: return "TB_SETTOOLTIPS";
+        case WM_USER+37: return "TB_SETPARENT";
+        case WM_USER+39: return "TB_SETROWS";
+        case WM_USER+40: return "TB_GETROWS";
+        case WM_USER+42: return "TB_SETCMDID";
+        case WM_USER+43: return "TB_CHANGEBITMAP";
+        case WM_USER+44: return "TB_GETBITMAP";
+        case WM_USER+45: return "TB_GETBUTTONTEXTA";
+        case WM_USER+75: return "TB_GETBUTTONTEXTW";
+        case WM_USER+46: return "TB_REPLACEBITMAP";
+        case WM_USER+47: return "TB_SETINDENT";
+        case WM_USER+48: return "TB_SETIMAGELIST";
+        case WM_USER+49: return "TB_GETIMAGELIST";
+        case WM_USER+50: return "TB_LOADIMAGES";
+        case WM_USER+51: return "TB_GETRECT";
+        case WM_USER+52: return "TB_SETHOTIMAGELIST";
+        case WM_USER+53: return "TB_GETHOTIMAGELIST";
+        case WM_USER+54: return "TB_SETDISABLEDIMAGELIST";
+        case WM_USER+55: return "TB_GETDISABLEDIMAGELIST";
+        case WM_USER+56: return "TB_SETSTYLE";
+        case WM_USER+57: return "TB_GETSTYLE";
+        case WM_USER+58: return "TB_GETBUTTONSIZE";
+        case WM_USER+59: return "TB_SETBUTTONWIDTH";
+        case WM_USER+60: return "TB_SETMAXTEXTROWS";
+        case WM_USER+61: return "TB_GETTEXTROWS";
+        case WM_USER+41: return "TB_GETBITMAPFLAGS";
 
 #endif //WIN32
 
-    default:
-        static char s_szBuf[128];
-        sprintf(s_szBuf, "<unknown message = %d>", message);
-        return s_szBuf;
-  }
+        default:
+            static char s_szBuf[128];
+            sprintf(s_szBuf, "<unknown message = %d>", message);
+            return s_szBuf;
+    }
 }
 #endif //__WXDEBUG__