]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
use new style creation (MSWCreateControl() and MSWGetStyle()); adjust the drop down...
[wxWidgets.git] / src / msw / window.cpp
index 7dec91edbc98503c0f0fa148d6c4fb4720e035ef..51c815981dd819b312bb70ba6d319118b88ca285 100644 (file)
@@ -17,7 +17,7 @@
 // headers
 // ---------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "window.h"
 #endif
 
@@ -29,8 +29,7 @@
 #endif
 
 #ifndef WX_PRECOMP
-    #include <windows.h>
-    #include "wx/msw/winundef.h"
+    #include "wx/msw/wrapwin.h"
     #include "wx/window.h"
     #include "wx/accel.h"
     #include "wx/setup.h"
     #include "wx/statbox.h"
 #endif
 
-#if wxUSE_OWNER_DRAWN
+#if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
     #include "wx/ownerdrw.h"
 #endif
 
+#include "wx/module.h"
+
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
 #endif
 
 #if wxUSE_ACCESSIBILITY
     #include "wx/access.h"
+    #include <ole2.h>
     #include <oleacc.h>
     #ifndef WM_GETOBJECT
         #define WM_GETOBJECT 0x003D
 
 #include "wx/textctrl.h"
 #include "wx/notebook.h"
+#include "wx/listctrl.h"
 
 #include <string.h>
 
-#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__)) || defined(__CYGWIN10__)
+#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)) || defined(__CYGWIN10__)
     #include <shellapi.h>
     #include <mmsystem.h>
 #endif
     #include <windowsx.h>
 #endif
 
-#if (!defined(__GNUWIN32_OLD__) && !defined(__TWIN32__) && !defined(__WXMICROWIN__)) || defined(__CYGWIN10__)
+#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)) || defined(__CYGWIN10__)
     #ifdef __WIN95__
         #include <commctrl.h>
     #endif
-#elif !defined(__WXMICROWIN__) // broken compiler
-    #ifndef __TWIN32__
-        #include "wx/msw/gnuwin32/extra.h"
-    #endif
+#elif !defined(__WXMICROWIN__) && !defined(__WXWINCE__) // broken compiler
+    #include "wx/msw/gnuwin32/extra.h"
 #endif
 
-// ----------------------------------------------------------------------------
-// standard constants not available with all compilers/headers
-// ----------------------------------------------------------------------------
+#include "wx/msw/missing.h"
 
-// This didn't appear in mingw until 2.95.2
-#ifndef SIF_TRACKPOS
-#define SIF_TRACKPOS 16
-#endif
-
-#if wxUSE_MOUSEWHEEL
-    #ifndef WM_MOUSEWHEEL
-        #define WM_MOUSEWHEEL           0x020A
-    #endif
-    #ifndef WHEEL_DELTA
-        #define WHEEL_DELTA             120
-    #endif
-    #ifndef SPI_GETWHEELSCROLLLINES
-        #define SPI_GETWHEELSCROLLLINES 104
-    #endif
-#endif // wxUSE_MOUSEWHEEL
-
-#ifndef VK_OEM_1
-    #define VK_OEM_1        0xBA
-    #define VK_OEM_PLUS     0xBB
-    #define VK_OEM_COMMA    0xBC
-    #define VK_OEM_MINUS    0xBD
-    #define VK_OEM_PERIOD   0xBE
-    #define VK_OEM_2        0xBF
-    #define VK_OEM_3        0xC0
-    #define VK_OEM_4        0xDB
-    #define VK_OEM_5        0xDC
-    #define VK_OEM_6        0xDD
-    #define VK_OEM_7        0xDE
+#if defined(__WXWINCE__)
+#include "wx/msw/wince/missing.h"
 #endif
 
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
 
-// the last Windows message we got (FIXME-MT)
-extern MSG s_currentMsg;
-
 #if wxUSE_MENUS_NATIVE
 wxMenu *wxCurrentPopupMenu = NULL;
 #endif // wxUSE_MENUS_NATIVE
@@ -173,12 +142,13 @@ static bool gs_hasStdCmap = FALSE;
 LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
                                    WPARAM wParam, LPARAM lParam);
 
+
 #ifdef  __WXDEBUG__
     const char *wxGetMessageName(int message);
 #endif  //__WXDEBUG__
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
-void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
+extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
 wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 
 // this magical function is used to translate VK_APPS key presses to right
@@ -201,15 +171,45 @@ static inline void wxBringWindowToTop(HWND hwnd)
 
     // activate (set focus to) specified window
     ::SetFocus(hwnd);
+#endif
 
     // raise top level parent to top of z order
-    ::SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
-#else // !__WXMICROWIN__
-    if ( !::BringWindowToTop(hwnd) )
+    if (!::SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE))
+    {
+        wxLogLastError(_T("SetWindowPos"));
+    }
+}
+
+// ensure that all our parent windows have WS_EX_CONTROLPARENT style
+static void EnsureParentHasControlParentStyle(wxWindow *parent)
+{
+    /*
+       If we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our
+       parent as well as otherwise several Win32 functions using
+       GetNextDlgTabItem() to iterate over all controls such as
+       IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed,
+       all of them iterate over all the controls starting from the currently
+       focused one and stop iterating when they get back to the focus but
+       unless all parents have WS_EX_CONTROLPARENT bit set, they would never
+       get back to the initial (focused) window: as we do have this style,
+       GetNextDlgTabItem() will leave this window and continue in its parent,
+       but if the parent doesn't have it, it wouldn't recurse inside it later
+       on and so wouldn't have a chance of getting back to this window neither.
+     */
+#ifndef __WXWINCE__
+    while ( parent && !parent->IsTopLevel() )
     {
-        wxLogLastError(_T("BringWindowToTop"));
+        LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE);
+        if ( !(exStyle & WS_EX_CONTROLPARENT) )
+        {
+            // force the parent to have this style
+            ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE,
+                            exStyle | WS_EX_CONTROLPARENT);
+        }
+
+        parent = parent->GetParent();
     }
-#endif // __WXMICROWIN__/!__WXMICROWIN__
+#endif // !__WXWINCE__
 }
 
 // ---------------------------------------------------------------------------
@@ -221,14 +221,119 @@ static inline void wxBringWindowToTop(HWND hwnd)
 #ifdef __WXUNIVERSAL__
     IMPLEMENT_ABSTRACT_CLASS(wxWindowMSW, wxWindowBase)
 #else // __WXMSW__
+#if wxUSE_EXTENDED_RTTI
+
+// windows that are created from a parent window during its Create method, eg. spin controls in a calendar controls
+// must never been streamed out separately otherwise chaos occurs. Right now easiest is to test for negative ids, as
+// windows with negative ids never can be recreated anyway
+
+bool wxWindowStreamingCallback( const wxObject *object, wxWriter * , wxPersister * , wxxVariantArray & )
+{
+    const wxWindow * win = dynamic_cast<const wxWindow*>(object) ;
+    if ( win && win->GetId() < 0 )
+        return false ;
+    return true ;
+}
+
+IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxWindow, wxWindowBase,"wx/window.h", wxWindowStreamingCallback)
+
+// make wxWindowList known before the property is used
+
+wxCOLLECTION_TYPE_INFO( wxWindow* , wxWindowList ) ;
+
+template<> void wxCollectionToVariantArray( wxWindowList const &theList, wxxVariantArray &value)
+{
+    wxListCollectionToVariantArray<wxWindowList::compatibility_iterator>( theList , value ) ;
+}
+
+WX_DEFINE_FLAGS( wxWindowStyle )
+
+wxBEGIN_FLAGS( wxWindowStyle )
+    // new style border flags, we put them first to
+    // use them for streaming out
+
+    wxFLAGS_MEMBER(wxBORDER_SIMPLE)
+    wxFLAGS_MEMBER(wxBORDER_SUNKEN)
+    wxFLAGS_MEMBER(wxBORDER_DOUBLE)
+    wxFLAGS_MEMBER(wxBORDER_RAISED)
+    wxFLAGS_MEMBER(wxBORDER_STATIC)
+    wxFLAGS_MEMBER(wxBORDER_NONE)
+    
+    // old style border flags
+    wxFLAGS_MEMBER(wxSIMPLE_BORDER)
+    wxFLAGS_MEMBER(wxSUNKEN_BORDER)
+    wxFLAGS_MEMBER(wxDOUBLE_BORDER)
+    wxFLAGS_MEMBER(wxRAISED_BORDER)
+    wxFLAGS_MEMBER(wxSTATIC_BORDER)
+    wxFLAGS_MEMBER(wxBORDER)
+
+    // standard window styles
+    wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
+    wxFLAGS_MEMBER(wxCLIP_CHILDREN)
+    wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
+    wxFLAGS_MEMBER(wxWANTS_CHARS)
+    wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
+    wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
+    wxFLAGS_MEMBER(wxVSCROLL)
+    wxFLAGS_MEMBER(wxHSCROLL)
+
+wxEND_FLAGS( wxWindowStyle )
+
+wxBEGIN_PROPERTIES_TABLE(wxWindow)
+       wxEVENT_PROPERTY( Close , wxEVT_CLOSE_WINDOW , wxCloseEvent)
+       wxEVENT_PROPERTY( Create , wxEVT_CREATE , wxWindowCreateEvent )
+       wxEVENT_PROPERTY( Destroy , wxEVT_DESTROY , wxWindowDestroyEvent )
+    // Always constructor Properties first
+
+    wxREADONLY_PROPERTY( Parent,wxWindow*, GetParent,  , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
+       wxPROPERTY( Id,wxWindowID, SetId, GetId, -1, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
+       wxPROPERTY( Position,wxPoint, SetPosition , GetPosition, wxPoint(-1,-1) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos
+       wxPROPERTY( Size,wxSize, SetSize, GetSize, wxSize(-1,-1) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size
+    wxPROPERTY( WindowStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
+
+    // Then all relations of the object graph
+
+    wxREADONLY_PROPERTY_COLLECTION( Children , wxWindowList , wxWindowBase* , GetWindowChildren , wxPROP_OBJECT_GRAPH /*flags*/ , wxT("Helpstring") , wxT("group"))
+
+   // and finally all other properties
+
+       wxPROPERTY( ExtraStyle , long , SetExtraStyle , GetExtraStyle , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // extstyle
+       wxPROPERTY( BackgroundColour , wxColour , SetBackgroundColour , GetBackgroundColour , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // bg
+       wxPROPERTY( ForegroundColour , wxColour , SetForegroundColour , GetForegroundColour , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // fg
+       wxPROPERTY( Enabled , bool , Enable , IsEnabled , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
+       wxPROPERTY( Shown , bool , Show , IsShown , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
+#if 0
+    // possible property candidates (not in xrc) or not valid in all subclasses
+       wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxT("") )
+       wxPROPERTY( Font , wxFont , SetFont , GetWindowFont  , )
+       wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxT("") )
+       // MaxHeight, Width , MinHeight , Width
+       // TODO switch label to control and title to toplevels
+
+       wxPROPERTY( ThemeEnabled , bool , SetThemeEnabled , GetThemeEnabled , )
+       //wxPROPERTY( Cursor , wxCursor , SetCursor , GetCursor , )
+       // wxPROPERTY( ToolTip , wxString , SetToolTip , GetToolTipText , )
+       wxPROPERTY( AutoLayout , bool , SetAutoLayout , GetAutoLayout , )
+
+
+
+#endif
+wxEND_PROPERTIES_TABLE()
+
+wxBEGIN_HANDLERS_TABLE(wxWindow)
+wxEND_HANDLERS_TABLE()
+
+wxCONSTRUCTOR_DUMMY(wxWindow)
+
+#else
     IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
+#endif
 #endif // __WXUNIVERSAL__/__WXMSW__
 
 BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase)
     EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
-    EVT_IDLE(wxWindowMSW::OnIdle)
 END_EVENT_TABLE()
 
 // ===========================================================================
@@ -258,7 +363,7 @@ wxWindow *wxWindowMSW::FindItem(long id) const
     }
 #endif // wxUSE_CONTROLS
 
-    wxWindowList::Node *current = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
     while (current)
     {
         wxWindow *childWin = current->GetData();
@@ -276,7 +381,7 @@ wxWindow *wxWindowMSW::FindItem(long id) const
 // Find an item given the MS Windows handle
 wxWindow *wxWindowMSW::FindItemByHWND(WXHWND hWnd, bool controlOnly) const
 {
-    wxWindowList::Node *current = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
     while (current)
     {
         wxWindow *parent = current->GetData();
@@ -319,13 +424,9 @@ bool wxWindowMSW::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
 
 void wxWindowMSW::Init()
 {
-    // generic
-    InitBase();
-
     // MSW specific
     m_isBeingDeleted = FALSE;
     m_oldWndProc = NULL;
-    m_useCtl3D = FALSE;
     m_mouseInWindow = FALSE;
     m_lastKeydownProcessed = FALSE;
 
@@ -338,7 +439,6 @@ void wxWindowMSW::Init()
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
-    m_backgroundTransparent = FALSE;
 
     // as all windows are created with WS_VISIBLE style...
     m_isShown = TRUE;
@@ -376,9 +476,6 @@ wxWindowMSW::~wxWindowMSW()
     //     find their parent frame (see above).
     DestroyChildren();
 
-    if ( m_parent )
-        m_parent->RemoveChild(this);
-
     if ( m_hWnd )
     {
         // VZ: test temp removed to understand what really happens here
@@ -446,7 +543,7 @@ void wxWindowMSW::SetFocus()
     HWND hWnd = GetHwnd();
     wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
 
-#ifndef __WXMICROWIN__
+#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
     ::SetLastError(0);
 #endif
 
@@ -469,8 +566,6 @@ void wxWindowMSW::SetFocus()
 
 void wxWindowMSW::SetFocusFromKbd()
 {
-    wxWindowBase::SetFocusFromKbd();
-
     // when the focus is given to the control with DLGC_HASSETSEL style from
     // keyboard its contents should be entirely selected: this is what
     // ::IsDialogMessage() does and so we should do it as well to provide the
@@ -479,6 +574,11 @@ void wxWindowMSW::SetFocusFromKbd()
     {
         ::SendMessage(GetHwnd(), EM_SETSEL, 0, -1);
     }
+
+    // do this after (maybe) setting the selection as like this when
+    // wxEVT_SET_FOCUS handler is called, the selection would have been already
+    // set correctly -- this may be important
+    wxWindowBase::SetFocusFromKbd();
 }
 
 // Get the window with the focus
@@ -512,7 +612,7 @@ bool wxWindowMSW::Enable(bool enable)
     // well but when it is enabled back, only those of the children which
     // hadn't been already disabled in the beginning should be enabled again,
     // so we have to keep the list of those children
-    for ( wxWindowList::Node *node = GetChildren().GetFirst();
+    for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
           node;
           node = node->GetNext() )
     {
@@ -567,7 +667,7 @@ bool wxWindowMSW::Show(bool show)
     int cshow = show ? SW_SHOW : SW_HIDE;
     ::ShowWindow(hWnd, cshow);
 
-    if ( show )
+    if ( show && IsTopLevel() )
     {
         wxBringWindowToTop(hWnd);
     }
@@ -676,201 +776,75 @@ void wxWindowMSW::WarpPointer (int x, int y)
     }
 }
 
-#if WXWIN_COMPATIBILITY
-void wxWindowMSW::MSWDeviceToLogical (float *x, float *y) const
-{
-}
-#endif // WXWIN_COMPATIBILITY
-
 // ---------------------------------------------------------------------------
 // scrolling stuff
 // ---------------------------------------------------------------------------
 
-#if WXWIN_COMPATIBILITY
-void wxWindowMSW::SetScrollRange(int orient, int range, bool refresh)
+// convert wxHORIZONTAL/wxVERTICAL to SB_HORZ/SB_VERT
+static inline int wxDirToWinStyle(int orient)
 {
-#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)
-    {
-        range1 += (pageSize - 1);
-    }
-
-    SCROLLINFO info;
-    int dir;
-
-    if ( orient == wxHORIZONTAL ) {
-        dir = SB_HORZ;
-    } else {
-        dir = SB_VERT;
-    }
-
-    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 wxWindowMSW::SetScrollPage(int orient, int page, bool refresh)
-{
-#if defined(__WIN95__)
-    SCROLLINFO info;
-    int dir;
-
-    if ( orient == wxHORIZONTAL ) {
-        dir = SB_HORZ;
-        m_xThumbSize = page;
-    } else {
-        dir = SB_VERT;
-        m_yThumbSize = page;
-    }
-
-    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
-}
-
-int wxWindowMSW::OldGetScrollRange(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 = GetScrollPage(orient);
-        if ( pageSize > 1 )
-        {
-            maxPos -= (pageSize - 1);
-        }
-#endif
-        return maxPos;
-    }
-    else
-        return 0;
-}
-
-int wxWindowMSW::GetScrollPage(int orient) const
-{
-    if ( orient == wxHORIZONTAL )
-        return m_xThumbSize;
-    else
-        return m_yThumbSize;
+    return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
 }
 
-#endif // WXWIN_COMPATIBILITY
-
 inline int GetScrollPosition(HWND hWnd, int wOrient)
 {
 #ifdef __WXMICROWIN__
     return ::GetScrollPosWX(hWnd, wOrient);
 #else
-    return ::GetScrollPos(hWnd, wOrient);
+    WinStruct<SCROLLINFO> scrollInfo;
+    scrollInfo.cbSize = sizeof(SCROLLINFO);
+    scrollInfo.fMask = SIF_POS;
+    if ( !::GetScrollInfo(hWnd,
+                          wOrient,
+                          &scrollInfo) )
+    {
+        // Not neccessarily an error, if there are no scrollbars yet.
+        // wxLogLastError(_T("GetScrollInfo"));
+    }
+    return scrollInfo.nPos;
+//    return ::GetScrollPos(hWnd, wOrient);
 #endif
 }
 
 int wxWindowMSW::GetScrollPos(int orient) const
 {
-    int wOrient;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
-
     HWND hWnd = GetHwnd();
     wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
 
-    return GetScrollPosition(hWnd, wOrient);
+    return GetScrollPosition(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT);
 }
 
 // This now returns the whole range, not just the number
 // of positions that we can scroll.
 int wxWindowMSW::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
+    int maxPos;
     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;
+    if ( !hWnd )
+        return 0;
+#if 0
+    ::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+                     &minPos, &maxPos);
 #endif
-
-        return maxPos;
+    WinStruct<SCROLLINFO> scrollInfo;
+    scrollInfo.fMask = SIF_RANGE;
+    if ( !::GetScrollInfo(hWnd,
+                          orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+                          &scrollInfo) )
+    {
+        // Most of the time this is not really an error, since the return
+        // value can also be zero when there is no scrollbar yet.
+        // wxLogLastError(_T("GetScrollInfo"));
     }
-    else
-        return 0;
+    maxPos = scrollInfo.nMax;
+
+    // undo "range - 1" done in SetScrollbar()
+    return maxPos + 1;
 }
 
 int wxWindowMSW::GetScrollThumb(int orient) const
 {
-    if ( orient == wxHORIZONTAL )
-        return m_xThumbSize;
-    else
-        return m_yThumbSize;
+    return orient == wxHORIZONTAL ? m_xThumbSize : m_yThumbSize;
 }
 
 void wxWindowMSW::SetScrollPos(int orient, int pos, bool refresh)
@@ -878,77 +852,48 @@ void wxWindowMSW::SetScrollPos(int orient, int pos, bool refresh)
     HWND hWnd = GetHwnd();
     wxCHECK_RET( hWnd, _T("SetScrollPos: no HWND") );
 
-    int dir = orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
-
-#if defined(__WIN95__)
-    SCROLLINFO info;
-    info.cbSize = sizeof(SCROLLINFO);
+    WinStruct<SCROLLINFO> info;
     info.nPage = 0;
     info.nMin = 0;
     info.nPos = pos;
     info.fMask = SIF_POS;
-
-    ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else // !__WIN95__
-    ::SetScrollPos(hWnd, dir, pos, refresh);
-#endif // __WIN95__/!__WIN95__
-}
-
-// New function that will replace some of the above.
-void wxWindowMSW::SetScrollbar(int orient, int pos, int thumbVisible,
-                            int range, bool refresh)
-{
-#if defined(__WIN95__)
-    int oldRange = range - thumbVisible;
-
-    int range1 = oldRange;
-
-    // Try to adjust the range to cope with page size > 1
-    // - a Windows API quirk
-    int pageSize = thumbVisible;
-    if ( pageSize > 1 && range > 0)
+    if ( HasFlag(wxALWAYS_SHOW_SB) )
     {
-        range1 += (pageSize - 1);
+        // disable scrollbar instead of removing it then
+        info.fMask |= SIF_DISABLENOSCROLL;
     }
 
-    SCROLLINFO info;
-    int dir;
-
-    if ( orient == wxHORIZONTAL ) {
-        dir = SB_HORZ;
-    } else {
-        dir = SB_VERT;
-    }
+    ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+                    &info, refresh);
+}
 
-    info.cbSize = sizeof(SCROLLINFO);
-    info.nPage = pageSize; // Have to set this, or scrollbar goes awry
-    info.nMin = 0;
-    info.nMax = range1;
+// New function that will replace some of the above.
+void wxWindowMSW::SetScrollbar(int orient,
+                               int pos,
+                               int pageSize,
+                               int range,
+                               bool refresh)
+{
+    WinStruct<SCROLLINFO> info;
+    info.nPage = pageSize;
+    info.nMin = 0;              // range is nMax - nMin + 1
+    info.nMax = range - 1;      //  as both nMax and nMax are inclusive
     info.nPos = pos;
     info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
-
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollInfo(hWnd, dir, &info, refresh);
-#else
-    int wOrient;
-    if ( orient == wxHORIZONTAL )
-        wOrient = SB_HORZ;
-    else
-        wOrient = SB_VERT;
+    if ( HasFlag(wxALWAYS_SHOW_SB) )
+    {
+        // disable scrollbar instead of removing it then
+        info.fMask |= SIF_DISABLENOSCROLL;
+    }
 
     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;
+        ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+                        &info, refresh);
     }
+
+    *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
@@ -968,7 +913,12 @@ void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
         pr = NULL;
     }
 
+#ifdef __WXWINCE__
+    // FIXME: is this the exact equivalent of the line below?
+    ::ScrollWindowEx(GetHwnd(), dx, dy, pr, pr, 0, 0, SW_ERASE|SW_INVALIDATE);
+#else
     ::ScrollWindow(GetHwnd(), dx, dy, pr, pr);
+#endif
 }
 
 static bool ScrollVertically(HWND hwnd, int kind, int count)
@@ -1028,7 +978,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
 
     // we don't need to subclass the window of our own class (in the Windows
     // sense of the word)
-    if ( !wxCheckWindowWndProc(hWnd, (WXFARPROC)wxWndProc) )
+       if ( !wxCheckWindowWndProc(hWnd, (WXFARPROC)wxWndProc) )
     {
         ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc);
     }
@@ -1074,6 +1024,28 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
     // unicows.dll, we can override unicows hooks by setting
     // Unicows_{Set,Get}WindowLong and Unicows_RegisterClass to our own
     // versions that keep track of fake<->real wnd proc mapping.
+
+       // On WinCE (at least), the wndproc comparison doesn't work,
+       // so have to use something like this.
+#ifdef __WXWINCE__
+       extern const wxChar *wxCanvasClassName;
+       extern const wxChar *wxCanvasClassNameNR;
+       extern const wxChar *wxMDIFrameClassName;
+       extern const wxChar *wxMDIFrameClassNameNoRedraw;
+       extern const wxChar *wxMDIChildFrameClassName;
+       extern const wxChar *wxMDIChildFrameClassNameNoRedraw;
+       wxString str(wxGetWindowClass(hWnd));
+       if (str == wxCanvasClassName ||
+               str == wxCanvasClassNameNR ||
+               str == wxMDIFrameClassName ||
+               str == wxMDIFrameClassNameNoRedraw ||
+               str == wxMDIChildFrameClassName ||
+               str == wxMDIChildFrameClassNameNoRedraw ||
+               str == _T("wxTLWHiddenParent"))
+               return TRUE; // Effectively means don't subclass
+       else
+               return FALSE;
+#else
     WNDCLASS cls;
     if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) )
     {
@@ -1083,6 +1055,7 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
     }
 
     return wndProc == (WXFARPROC)cls.lpfnWndProc;
+#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -1146,7 +1119,7 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
 WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 {
     // translate the style
-    WXDWORD style = WS_CHILD;
+    WXDWORD style = WS_CHILD | WS_VISIBLE;
 
     if ( flags & wxCLIP_CHILDREN )
         style |= WS_CLIPCHILDREN;
@@ -1154,8 +1127,16 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     if ( flags & wxCLIP_SIBLINGS )
         style |= WS_CLIPSIBLINGS;
 
-    wxBorder border = (wxBorder)(flags & wxBORDER_MASK);
-    if ( border != wxBORDER_NONE && border != wxBORDER_DEFAULT )
+    if ( flags & wxVSCROLL )
+        style |= WS_VSCROLL;
+
+    if ( flags & wxHSCROLL )
+        style |= WS_HSCROLL;
+
+    const wxBorder border = GetBorder(flags);
+
+    // WS_BORDER is only required for wxBORDER_SIMPLE
+    if ( border == wxBORDER_SIMPLE )
         style |= WS_BORDER;
 
     // now deal with ext style if the caller wants it
@@ -1163,18 +1144,20 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     {
         *exstyle = 0;
 
+#ifndef __WXWINCE__
         if ( flags & wxTRANSPARENT_WINDOW )
             *exstyle |= WS_EX_TRANSPARENT;
+#endif
 
-        switch ( flags & wxBORDER_MASK )
+        switch ( border )
         {
             default:
+            case wxBORDER_DEFAULT:
                 wxFAIL_MSG( _T("unknown border style") );
                 // fall through
 
             case wxBORDER_NONE:
             case wxBORDER_SIMPLE:
-            case wxBORDER_DEFAULT:
                 break;
 
             case wxBORDER_STATIC:
@@ -1182,11 +1165,12 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
                 break;
 
             case wxBORDER_RAISED:
-                *exstyle |= WS_EX_WINDOWEDGE;
+                *exstyle |= WS_EX_DLGMODALFRAME;
                 break;
 
             case wxBORDER_SUNKEN:
                 *exstyle |= WS_EX_CLIENTEDGE;
+                style &= ~WS_BORDER;
                 break;
 
             case wxBORDER_DOUBLE:
@@ -1195,7 +1179,7 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
         }
 
         // wxUniv doesn't use Windows dialog navigation functions at all
-#ifndef __WXUNIVERSAL__
+#if !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__)
         // to make the dialog navigation work with the nested panels we must
         // use this style (top level windows such as dialogs don't need it)
         if ( (flags & wxTAB_TRAVERSAL) && !IsTopLevel() )
@@ -1208,125 +1192,6 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     return style;
 }
 
-// Make a Windows extended style from the given wxWindows window style
-WXDWORD wxWindowMSW::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 )
-            // It seems that WS_EX_WINDOWEDGE doesn't work, but WS_EX_DLGMODALFRAME does
-            exStyle |= WS_EX_DLGMODALFRAME; /* WS_EX_WINDOWEDGE */;
-        if ( style & wxSTATIC_BORDER )
-            exStyle |= WS_EX_STATICEDGE;
-#endif
-    }
-
-    return exStyle;
-}
-
-// 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 wxWindowMSW::Determine3DEffects(WXDWORD defaultBorderStyle,
-                                        bool *want3D) const
-{
-    // If matches certain criteria, then assume no 3D effects
-    // unless specifically requested (dealt with in MakeExtendedStyle)
-    if ( !GetParent()
-#if wxUSE_CONTROLS
-            || !IsKindOf(CLASSINFO(wxControl))
-#endif // wxUSE_CONTROLS
-            || (m_windowStyle & wxNO_BORDER) )
-    {
-        *want3D = FALSE;
-        return MakeExtendedStyle(m_windowStyle);
-    }
-
-    // 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) )
-    {
-        *want3D = TRUE;
-        nativeBorder = TRUE;
-    }
-
-    // 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
-
-    return exStyle;
-}
-
-#if WXWIN_COMPATIBILITY
-// 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 wxWindowMSW::OnCommand(wxWindow& win, wxCommandEvent& event)
-{
-    if ( GetEventHandler()->ProcessEvent(event)  )
-        return;
-    if ( m_parent )
-        m_parent->GetEventHandler()->OnCommand(win, event);
-}
-#endif // WXWIN_COMPATIBILITY_2
-
-#if WXWIN_COMPATIBILITY
-wxObject* wxWindowMSW::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
-
 // Setup background and foreground colours correctly
 void wxWindowMSW::SetupColours()
 {
@@ -1349,7 +1214,7 @@ bool wxWindowMSW::IsMouseInWindow() const
     return hwnd != NULL;
 }
 
-void wxWindowMSW::OnIdle(wxIdleEvent& WXUNUSED(event))
+void wxWindowMSW::OnInternalIdle()
 {
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
@@ -1362,7 +1227,7 @@ void wxWindowMSW::OnIdle(wxIdleEvent& WXUNUSED(event))
             m_mouseInWindow = FALSE;
 
             // Unfortunately the mouse button and keyboard state may have
-            // changed by the time the OnIdle function is called, so 'state'
+            // changed by the time the OnInternalIdle function is called, so 'state'
             // may be meaningless.
             int state = 0;
             if ( wxIsShiftDown() )
@@ -1395,7 +1260,8 @@ void wxWindowMSW::OnIdle(wxIdleEvent& WXUNUSED(event))
         }
     }
 
-    UpdateWindowUI();
+    if (wxUpdateUIEvent::CanUpdate(this))
+        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
 // Set this window to be the child of 'parent'.
@@ -1409,15 +1275,14 @@ bool wxWindowMSW::Reparent(wxWindowBase *parent)
 
     ::SetParent(hWndChild, hWndParent);
 
-    return TRUE;
-}
+#ifndef __WXWINCE__
+    if ( ::GetWindowLong(hWndChild, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
+    {
+        EnsureParentHasControlParentStyle(GetParent());
+    }
+#endif // !__WXWINCE__
 
-void wxWindowMSW::Clear()
-{
-    wxClientDC dc((wxWindow *)this);
-    wxBrush brush(GetBackgroundColour(), wxSOLID);
-    dc.SetBackground(brush);
-    dc.Clear();
+    return TRUE;
 }
 
 static inline void SendSetRedraw(HWND hwnd, bool on)
@@ -1468,7 +1333,7 @@ void wxWindowMSW::Update()
         wxLogLastError(_T("UpdateWindow"));
     }
 
-#if defined(__WIN32__) && !defined(__WXMICROWIN__)
+#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
     // just calling UpdateWindow() is not enough, what we did in our WM_PAINT
     // handler needs to be really drawn right now
     (void)::GdiFlush();
@@ -1479,8 +1344,8 @@ void wxWindowMSW::Update()
 // drag and drop
 // ---------------------------------------------------------------------------
 
-#if wxUSE_DRAG_AND_DROP
 
+#if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 {
     if ( m_dropTarget != 0 ) {
@@ -1492,16 +1357,17 @@ void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
     if ( m_dropTarget != 0 )
         m_dropTarget->Register(m_hWnd);
 }
-
 #endif // wxUSE_DRAG_AND_DROP
 
 // old style file-manager drag&drop support: we retain the old-style
 // DragAcceptFiles in parallel with SetDropTarget.
 void wxWindowMSW::DragAcceptFiles(bool accept)
 {
+#if !defined(__WXWINCE__)
     HWND hWnd = GetHwnd();
     if ( hWnd )
         ::DragAcceptFiles(hWnd, (BOOL)accept);
+#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -1824,48 +1690,6 @@ void wxWindowMSW::GetTextExtent(const wxString& string,
         *externalLeading = tm.tmExternalLeading;
 }
 
-#if wxUSE_CARET && WXWIN_COMPATIBILITY
-// ---------------------------------------------------------------------------
-// Caret manipulation
-// ---------------------------------------------------------------------------
-
-void wxWindowMSW::CreateCaret(int w, int h)
-{
-    SetCaret(new wxCaret(this, w, h));
-}
-
-void wxWindowMSW::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
-{
-    wxFAIL_MSG("not implemented");
-}
-
-void wxWindowMSW::ShowCaret(bool show)
-{
-    wxCHECK_RET( m_caret, "no caret to show" );
-
-    m_caret->Show(show);
-}
-
-void wxWindowMSW::DestroyCaret()
-{
-    SetCaret(NULL);
-}
-
-void wxWindowMSW::SetCaretPos(int x, int y)
-{
-    wxCHECK_RET( m_caret, "no caret to move" );
-
-    m_caret->Move(x, y);
-}
-
-void wxWindowMSW::GetCaretPos(int *x, int *y) const
-{
-    wxCHECK_RET( m_caret, "no caret to get position of" );
-
-    m_caret->GetPosition(x, y);
-}
-#endif // wxUSE_CARET
-
 // ---------------------------------------------------------------------------
 // popup menu
 // ---------------------------------------------------------------------------
@@ -1882,15 +1706,21 @@ static void wxYieldForCommandsOnly()
     // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
     // want to process it here)
     MSG msg;
-    while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE)
-                && msg.message != WM_QUIT )
+    while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE) )
     {
-        wxTheApp->DoMessage((WXMSG *)&msg);
-    }
+        if ( msg.message == WM_QUIT )
+        {
+            // if we retrieved a WM_QUIT, insert back into the message queue.
+            ::PostQuitMessage(0);
+            break;
+        }
 
-    // If we retrieved a WM_QUIT, insert back into the message queue.
-    if (msg.message == WM_QUIT)
-        ::PostQuitMessage(0);
+        // luckily (as we don't have access to wxEventLoopImpl method from here
+        // anyhow...) we don't need to pre process WM_COMMANDs so dispatch it
+        // immediately
+        ::TranslateMessage(&msg);
+        ::DispatchMessage(&msg);
+    }
 }
 
 bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
@@ -1905,7 +1735,11 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
     point.y = y;
     ::ClientToScreen(hWnd, &point);
     wxCurrentPopupMenu = menu;
-    ::TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL);
+    UINT flags = 0;
+#if !defined(__WXWINCE__)
+    flags = TPM_RIGHTBUTTON;
+#endif
+    ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
     // we need to do it righ now as otherwise the events are never going to be
     // sent to wxCurrentPopupMenu from HandleCommand()
@@ -1979,10 +1813,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
             switch ( msg->wParam )
             {
                 case VK_TAB:
-                    // assume that nobody wants Shift-TAB for himself - if we
-                    // don't do it there is no easy way for a control to grab
-                    // TABs but still let Shift-TAB work as navugation key
-                    if ( (lDlgCode & DLGC_WANTTAB) && !bShiftDown ) {
+                    if ( lDlgCode & DLGC_WANTTAB ) {
                         bProcess = FALSE;
                     }
                     else {
@@ -2126,34 +1957,79 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         // place edit control from being closed with Escape in a dialog
         if ( msg->message != WM_KEYDOWN || msg->wParam != VK_ESCAPE )
         {
-            // ::IsDialogMessage() can enter in an infinite loop when the
-            // currently focused window is disabled or hidden and its parent
-            // has WS_EX_CONTROLPARENT style, so don't call it in this case
+            // ::IsDialogMessage() is broken and may sometimes hang the
+            // application by going into an infinite loop, so we try to detect
+            // [some of] the situatations when this may happen and not call it
+            // then
+
+            // assume we can call it by default
             bool canSafelyCallIsDlgMsg = TRUE;
 
             HWND hwndFocus = ::GetFocus();
-            while ( hwndFocus )
+
+            // if the currently focused window itself has WS_EX_CONTROLPARENT style, ::IsDialogMessage() will also enter
+            // an infinite loop, because it will recursively check the child
+            // windows but not the window itself and so if none of the children
+            // accepts focus it loops forever (as it only stops when it gets
+            // back to the window it started from)
+            //
+            // while it is very unusual that a window with WS_EX_CONTROLPARENT
+            // style has the focus, it can happen. One such possibility is if
+            // all windows are either toplevel, wxDialog, wxPanel or static
+            // controls and no window can actually accept keyboard input.
+#if !defined(__WXWINCE__)
+            if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
             {
-                if ( !::IsWindowEnabled(hwndFocus) ||
-                        !::IsWindowVisible(hwndFocus) )
+                // passimistic by default
+                canSafelyCallIsDlgMsg = FALSE;
+                for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+                      node;
+                      node = node->GetNext() )
                 {
-                    // it would enter an infinite loop if we do this!
-                    canSafelyCallIsDlgMsg = FALSE;
+                    wxWindow * const win = node->GetData();
+                    if ( win->AcceptsFocus() &&
+                            !(::GetWindowLong(GetHwndOf(win), GWL_EXSTYLE) &
+                                WS_EX_CONTROLPARENT) )
+                    {
+                        // it shouldn't hang...
+                        canSafelyCallIsDlgMsg = TRUE;
 
-                    break;
+                        break;
+                    }
                 }
+            }
+#endif // !__WXWINCE__
+
+            if ( canSafelyCallIsDlgMsg )
+            {
+                // ::IsDialogMessage() can enter in an infinite loop when the
+                // currently focused window is disabled or hidden and its
+                // parent has WS_EX_CONTROLPARENT style, so don't call it in
+                // this case
+                while ( hwndFocus )
+                {
+                    if ( !::IsWindowEnabled(hwndFocus) ||
+                            !::IsWindowVisible(hwndFocus) )
+                    {
+                        // it would enter an infinite loop if we do this!
+                        canSafelyCallIsDlgMsg = FALSE;
+
+                        break;
+                    }
 
-                if ( !(::GetWindowLong(hwndFocus, GWL_STYLE) & WS_CHILD) )
-                {
-                    // it's a top level window, don't go further -- e.g. even
-                    // if the parent of a dialog is disabled, this doesn't
-                    // break navigation inside the dialog
-                    break;
-                }
+                    if ( !(::GetWindowLong(hwndFocus, GWL_STYLE) & WS_CHILD) )
+                    {
+                        // it's a top level window, don't go further -- e.g. even
+                        // if the parent of a dialog is disabled, this doesn't
+                        // break navigation inside the dialog
+                        break;
+                    }
 
-                hwndFocus = ::GetParent(hwndFocus);
+                    hwndFocus = ::GetParent(hwndFocus);
+                }
             }
 
+            // let IsDialogMessage() have the message if it's safe to call it
             if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) )
             {
                 // IsDialogMessage() did something...
@@ -2193,11 +2069,9 @@ bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* WXUNUSED(pMsg))
 }
 
 // ---------------------------------------------------------------------------
-// message params unpackers (different for Win16 and Win32)
+// message params unpackers
 // ---------------------------------------------------------------------------
 
-#ifdef __WIN32__
-
 void wxWindowMSW::UnpackCommand(WXWPARAM wParam, WXLPARAM lParam,
                              WORD *id, WXHWND *hwnd, WORD *cmd)
 {
@@ -2240,50 +2114,6 @@ void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
     *hmenu = (WXHMENU)lParam;
 }
 
-#else // Win16
-
-void wxWindowMSW::UnpackCommand(WXWPARAM wParam, WXLPARAM lParam,
-                             WXWORD *id, WXHWND *hwnd, WXWORD *cmd)
-{
-    *id = (WXWORD)wParam;
-    *hwnd = (WXHWND)LOWORD(lParam);
-    *cmd = HIWORD(lParam);
-}
-
-void wxWindowMSW::UnpackActivate(WXWPARAM wParam, WXLPARAM lParam,
-                              WXWORD *state, WXWORD *minimized, WXHWND *hwnd)
-{
-    *state = (WXWORD)wParam;
-    *minimized = LOWORD(lParam);
-    *hwnd = (WXHWND)HIWORD(lParam);
-}
-
-void wxWindowMSW::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
-                            WXWORD *code, WXWORD *pos, WXHWND *hwnd)
-{
-    *code = (WXWORD)wParam;
-    *pos = LOWORD(lParam);
-    *hwnd = (WXHWND)HIWORD(lParam);
-}
-
-void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
-                              WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
-{
-    *hwnd = (WXHWND)LOWORD(lParam);
-    *nCtlColor = (int)HIWORD(lParam);
-    *hdc = (WXHDC)wParam;
-}
-
-void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
-                                WXWORD *item, WXWORD *flags, WXHMENU *hmenu)
-{
-    *item = (WXWORD)wParam;
-    *flags = LOWORD(lParam);
-    *hmenu = (WXHMENU)HIWORD(lParam);
-}
-
-#endif // Win32/16
-
 // ---------------------------------------------------------------------------
 // Main wxWindows window proc and the window proc for wxWindow
 // ---------------------------------------------------------------------------
@@ -2309,10 +2139,9 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w
 {
     // trace all messages - useful for the debugging
 #ifdef __WXDEBUG__
-#if wxUSE_LOG
-    wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
-               wxGetMessageName(message), (long) wParam, lParam);
-#endif // wxUSE_LOG
+    wxLogTrace(wxTraceMessages,
+               wxT("Processing %s(hWnd=%08lx, wParam=%8lx, lParam=%8lx)"),
+               wxGetMessageName(message), (long)hWnd, (long)wParam, lParam);
 #endif // __WXDEBUG__
 
     wxWindowMSW *wnd = wxFindWinFromHandle((WXHWND) hWnd);
@@ -2380,6 +2209,26 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
             break;
 
+#if !defined(__WXWINCE__)
+        case WM_MOVING:
+            {
+                LPRECT pRect = (LPRECT)lParam;
+                wxRect rc;
+                rc.SetLeft(pRect->left);
+                rc.SetTop(pRect->top);
+                rc.SetRight(pRect->right);
+                rc.SetBottom(pRect->bottom);
+                processed = HandleMoving(rc);
+                if (processed) {
+                    pRect->left = rc.GetLeft();
+                    pRect->top = rc.GetTop();
+                    pRect->right = rc.GetRight();
+                    pRect->bottom = rc.GetBottom();
+                }
+            }
+            break;
+#endif
+
         case WM_SIZE:
             switch ( wParam )
             {
@@ -2408,7 +2257,27 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 
-#ifndef __WXMICROWIN__
+#if !defined(__WXWINCE__)
+        case WM_SIZING:
+            {
+                LPRECT pRect = (LPRECT)lParam;
+                wxRect rc;
+                rc.SetLeft(pRect->left);
+                rc.SetTop(pRect->top);
+                rc.SetRight(pRect->right);
+                rc.SetBottom(pRect->bottom);
+                processed = HandleSizing(rc);
+                if (processed) {
+                    pRect->left = rc.GetLeft();
+                    pRect->top = rc.GetTop();
+                    pRect->right = rc.GetRight();
+                    pRect->bottom = rc.GetBottom();
+                }
+            }
+            break;
+#endif
+
+#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
@@ -2433,8 +2302,35 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             break;
 
         case WM_PAINT:
-            processed = HandlePaint();
+            {
+                if ( wParam )
+                {
+                    // cast to wxWindow is needed for wxUniv
+                    wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
+                    processed = HandlePaint();
+                }
+                else
+                {
+                    processed = HandlePaint();
+                }
+                break;
+            }
+
+#ifndef __WXWINCE__
+        case WM_PRINT:
+            {
+                // Don't call the wx handlers in this case
+                if ( wxIsKindOf(this, wxListCtrl) )
+                    break;
+
+                if ( lParam & PRF_ERASEBKGND )
+                    HandleEraseBkgnd((WXHDC)(HDC)wParam);
+
+                wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
+                processed = HandlePaint();
+            }
             break;
+#endif
 
         case WM_CLOSE:
 #ifdef __WXUNIVERSAL__
@@ -2461,6 +2357,62 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                                         wParam);
             break;
 
+            // Seems to be broken currently
+#if 0 // ndef __WXWINCE__
+        case WM_MOUSELEAVE:
+           {
+            wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
+           
+            // only process this message if the mouse is not in the window,
+            // This can also check for children in composite windows. 
+            // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
+            // if the mouse does not enter the window from it's child before 
+            // leaving the scope of the window. ( perhaps this can be picked
+            // up in the OnIdle code as before, for this special case )
+            if ( /*IsComposite() && */ !IsMouseInWindow() )
+            {
+                m_mouseInWindow = FALSE;
+
+                // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE 
+                int state = 0;
+                if ( wxIsShiftDown() )
+                    state |= MK_SHIFT;
+                if ( wxIsCtrlDown() )
+                    state |= MK_CONTROL;
+                if ( GetKeyState( VK_LBUTTON ) )
+                    state |= MK_LBUTTON;
+                if ( GetKeyState( VK_MBUTTON ) )
+                    state |= MK_MBUTTON;
+                if ( GetKeyState( VK_RBUTTON ) )
+                    state |= MK_RBUTTON;
+
+                POINT pt;
+                if ( !::GetCursorPos(&pt) )
+                {
+                    wxLogLastError(_T("GetCursorPos"));
+                }
+
+                // we need to have client coordinates here for symmetry with
+                // wxEVT_ENTER_WINDOW
+                RECT rect = wxGetWindowRect(GetHwnd());
+                pt.x -= rect.left;
+                pt.y -= rect.top;
+
+                wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
+                InitMouseEvent(event2, pt.x, pt.y, state);
+
+                (void)GetEventHandler()->ProcessEvent(event2);
+            }
+            // always pass processed back as false, this allows the window
+            // manager to process the message too.  This is needed to ensure
+            // windows XP themes work properly as the mouse moves over widgets
+            // like buttons.
+            processed = false;
+           }
+           break;
+#endif
+ // __WXWINCE__
+           
 #if wxUSE_MOUSEWHEEL
         case WM_MOUSEWHEEL:
             processed = HandleMouseWheel(wParam, lParam);
@@ -2564,11 +2516,9 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 
-#ifdef __WIN95__
         case WM_NOTIFY:
             processed = HandleNotify((int)wParam, lParam, &rc.result);
             break;
-#endif  // Win95
 
             // for these messages we must return TRUE if process the message
 #ifdef WM_DRAWITEM
@@ -2724,6 +2674,12 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 
+#if wxUSE_HOTKEY
+        case WM_HOTKEY:
+            processed = HandleHotKey((WORD)wParam, lParam);
+            break;
+#endif // wxUSE_HOTKEY
+
         case WM_HSCROLL:
         case WM_VSCROLL:
             {
@@ -2740,7 +2696,6 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
         // CTLCOLOR messages are sent by children to query the parent for their
         // colors#ifndef __WXMICROWIN__
 #ifndef __WXMICROWIN__
-#ifdef __WIN32__
         case WM_CTLCOLORMSGBOX:
         case WM_CTLCOLOREDIT:
         case WM_CTLCOLORLISTBOX:
@@ -2748,9 +2703,6 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
         case WM_CTLCOLORDLG:
         case WM_CTLCOLORSCROLLBAR:
         case WM_CTLCOLORSTATIC:
-#else // Win16
-        case WM_CTLCOLOR:
-#endif // Win32/16
             {
                 WXWORD nCtlColor;
                 WXHDC hdc;
@@ -2773,9 +2725,11 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             processed = HandleSysColorChange();
             break;
 
+#if !defined(__WXWINCE__)
         case WM_DISPLAYCHANGE:
             processed = HandleDisplayChange();
             break;
+#endif
 
         case WM_PALETTECHANGED:
             processed = HandlePaletteChanged((WXHWND) (HWND) wParam);
@@ -2798,9 +2752,11 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 
+#if !defined(__WXWINCE__)
         case WM_DROPFILES:
             processed = HandleDropFiles(wParam);
             break;
+#endif
 
         case WM_INITDIALOG:
             processed = HandleInitDialog((WXHWND)(HWND)wParam);
@@ -2812,6 +2768,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 
+#if !defined(__WXWINCE__)
         case WM_QUERYENDSESSION:
             processed = HandleQueryEndSession(lParam, &rc.allow);
             break;
@@ -2823,6 +2780,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
         case WM_GETMINMAXINFO:
             processed = HandleGetMinMaxInfo((MINMAXINFO*)lParam);
             break;
+#endif
 
         case WM_SETCURSOR:
             processed = HandleSetCursor((WXHWND)(HWND)wParam,
@@ -2844,7 +2802,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                 //WPARAM dwFlags = (WPARAM) (DWORD) wParam;
                 LPARAM dwObjId = (LPARAM) (DWORD) lParam;
 
-                if (dwObjId == OBJID_CLIENT && GetOrCreateAccessible())
+                if (dwObjId == (LPARAM)OBJID_CLIENT && GetOrCreateAccessible())
                 {
                     return LresultFromObject(IID_IAccessible, wParam, (IUnknown*) GetAccessible()->GetIAccessible());
                 }
@@ -2852,21 +2810,29 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
 #endif
 
-#if defined(__WIN32__) && defined(WM_HELP)
+#if defined(WM_HELP)
         case WM_HELP:
             {
+                // HELPINFO doesn't seem to be supported on WinCE.
+#ifndef __WXWINCE__
                 HELPINFO* info = (HELPINFO*) lParam;
                 // Don't yet process menu help events, just windows
                 if (info->iContextType == HELPINFO_WINDOW)
                 {
+#endif
                     wxWindowMSW* subjectOfHelp = this;
                     bool eventProcessed = FALSE;
                     while (subjectOfHelp && !eventProcessed)
                     {
                         wxHelpEvent helpEvent(wxEVT_HELP,
                                               subjectOfHelp->GetId(),
-                                              wxPoint(info->MousePos.x,
-                                              info->MousePos.y) );
+#ifdef __WXWINCE__
+                                              wxPoint(0, 0)
+#else
+                                              wxPoint(info->MousePos.x, info->MousePos.y)
+#endif
+                                              );
+
                         helpEvent.SetEventObject(this);
                         eventProcessed =
                             GetEventHandler()->ProcessEvent(helpEvent);
@@ -2877,6 +2843,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                     }
 
                     processed = eventProcessed;
+#ifndef __WXWINCE__
                 }
                 else if (info->iContextType == HELPINFO_MENUITEM)
                 {
@@ -2886,9 +2853,12 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
 
                 }
                 //else: processed is already FALSE
+#endif
             }
             break;
+#endif
 
+#if !defined(__WXWINCE__)
         case WM_CONTEXTMENU:
             {
                 // we don't convert from screen to client coordinates as
@@ -2896,9 +2866,11 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                 wxPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
 
                 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
+                evtCtx.SetEventObject(this);
                 processed = GetEventHandler()->ProcessEvent(evtCtx);
             }
             break;
+#endif
 
         case WM_MENUCHAR:
             // we're only interested in our own menus, not MF_SYSMENU
@@ -2913,16 +2885,13 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                 }
             }
             break;
-#endif // __WIN32__
     }
 
     if ( !processed )
     {
 #ifdef __WXDEBUG__
-#if wxUSE_LOG
         wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
                    wxGetMessageName(message));
-#endif // wxUSE_LOG
 #endif // __WXDEBUG__
         rc.result = MSWDefWindowProc(message, wParam, lParam);
     }
@@ -3037,6 +3006,8 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
         nonDefault = TRUE;
     }
 
+    AdjustForParentClientOrigin(x, y);
+
     return nonDefault;
 }
 
@@ -3064,7 +3035,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     // which is the same but without CS_[HV]REDRAW class styles so using it
     // ensures that the window is not fully repainted on each resize
     wxString className(wclass);
-    if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE )
+    if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
     {
         className += wxT("NR");
     }
@@ -3072,18 +3043,37 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     // do create the window
     wxWindowCreationHook hook(this);
 
-    m_hWnd = (WXHWND)::CreateWindowEx
-                       (
-                            extendedStyle,
-                            className,
-                            title ? title : wxT(""),
-                            style,
-                            x, y, w, h,
-                            (HWND)MSWGetParent(),
-                            (HMENU)controlId,
-                            wxGetInstance(),
-                            NULL                        // no extra data
-                       );
+#ifdef __WXWINCE__
+    if (extendedStyle == 0)
+    {
+        m_hWnd = (WXHWND)::CreateWindow
+            (
+            className,
+            title ? title : wxEmptyString,
+            style,
+            x, y, w, h,
+            (HWND)MSWGetParent(),
+            (HMENU)controlId,
+            wxGetInstance(),
+            NULL                        // no extra data
+            );
+    }
+    else
+#endif
+    {
+        m_hWnd = (WXHWND)::CreateWindowEx
+            (
+            extendedStyle,
+            className,
+            title ? title : wxEmptyString,
+            style,
+            x, y, w, h,
+            (HWND)MSWGetParent(),
+            (HMENU)controlId,
+            wxGetInstance(),
+            NULL                        // no extra data
+            );
+    }
 
     if ( !m_hWnd )
     {
@@ -3130,7 +3120,7 @@ bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
     //     correct button tooltips
 #if 0
     // try all our children
-    wxWindowList::Node *node = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
     while ( node )
     {
         wxWindow *child = node->GetData();
@@ -3161,12 +3151,13 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code,
     // this message is supposed to be sent to Unicode programs only) -- hence
     // we need to handle it as well, otherwise no tooltips will be shown in
     // this case
-
+#ifndef __WXWINCE__
     if ( !(code == (WXUINT) TTN_NEEDTEXTA || code == (WXUINT) TTN_NEEDTEXTW) || ttip.empty() )
     {
         // not a tooltip message or no tooltip to show anyhow
         return FALSE;
     }
+#endif
 
     LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
 
@@ -3183,9 +3174,33 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code,
         // in Unicode mode this is just what we need
         ttText->lpszText = (wxChar *)ttip.c_str();
 #else // !Unicode
+/*
         MultiByteToWideChar(CP_ACP, 0, ttip, ttip.length()+1,
                             (wchar_t *)ttText->szText,
                             sizeof(ttText->szText) / sizeof(wchar_t));
+*/
+        // Fix by dimitrishortcut: see patch 771772
+
+        // FIXME: szText has a max of 80 bytes, so limit the tooltip string
+        // length accordingly. Ideally lpszText should be used, but who
+        // would be responsible for freeing the buffer?
+
+        // Maximum length of a tip is 39 characters. 39 is 80/2 minus 1 byte
+        // needed for NULL character.
+        size_t tipLength = wxMin(ttip.Len(), 39);
+
+        // Convert to WideChar without adding the NULL character. The NULL
+        // character is added afterwards (Could have used ttip.Left(tipLength)
+        // and a cchMultiByte parameter of tipLength+1, but this is more
+        //efficient.
+        ::MultiByteToWideChar(CP_ACP, 0, ttip, tipLength,
+                             (wchar_t *)ttText->szText,
+                             sizeof(ttText->szText) / sizeof(wchar_t));
+
+        // Add the NULL character.
+        ttText->szText[tipLength*2+0] = '\0';
+        ttText->szText[tipLength*2+1] = '\0';
+
 #endif // Unicode/!Unicode
     }
 
@@ -3221,6 +3236,7 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
 
 bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd)
 {
+#ifndef __WXWINCE__
     wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(TRUE);
@@ -3236,10 +3252,14 @@ bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd)
     }
 
     return rc;
+#else
+    return FALSE;
+#endif
 }
 
 bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 {
+#ifndef __WXWINCE__
     // do nothing if the session isn't ending
     if ( !endSession )
         return FALSE;
@@ -3254,6 +3274,9 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
     event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) );
 
     return wxTheApp->ProcessEvent(event);
+#else
+    return FALSE;
+#endif
 }
 
 // ---------------------------------------------------------------------------
@@ -3262,30 +3285,13 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 
 bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
 {
-    // if we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our
-    // parent as well as otherwise several Win32 functions using
-    // GetNextDlgTabItem() to iterate over all controls such as
-    // IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed,
-    // all of them iterate over all the controls starting from the focus and
-    // stop iterating when they get back to the focus but unless all parents
-    // have WS_EX_CONTROLPARENT bit set, they would never get back to focus
+    // VZ: why is this commented out for WinCE? If it doesn't support
+    //     WS_EX_CONTROLPARENT at all it should be somehow handled globally,
+    //     not with multiple #ifdef's!
+#ifndef __WXWINCE__
     if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT )
-    {
-        // there is no need to do anything for the top level windows
-        const wxWindow *parent = GetParent();
-        while ( parent && !parent->IsTopLevel() )
-        {
-            LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE);
-            if ( !(exStyle & WS_EX_CONTROLPARENT) )
-            {
-                // force the parent to have this style
-                ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE,
-                                exStyle | WS_EX_CONTROLPARENT);
-            }
-
-            parent = parent->GetParent();
-        }
-    }
+        EnsureParentHasControlParentStyle(GetParent());
+#endif // !__WXWINCE__
 
     // TODO: should generate this event from WM_NCCREATE
     wxWindowCreateEvent event((wxWindow *)this);
@@ -3422,7 +3428,9 @@ bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 
 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
 {
-#ifndef __WXMICROWIN__
+#if defined (__WXMICROWIN__) || defined(__WXWINCE__)
+    return FALSE;
+#else // __WXMICROWIN__
     HDROP hFilesInfo = (HDROP) wParam;
 
     // Get the total number of files dropped
@@ -3442,9 +3450,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
 
         // and now get the file name
         ::DragQueryFile(hFilesInfo, wIndex,
-                        files[wIndex].GetWriteBuf(len), len);
-
-        files[wIndex].UngetWriteBuf();
+                        wxStringBuffer(files[wIndex], len), len);
     }
     DragFinish (hFilesInfo);
 
@@ -3457,11 +3463,10 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
     event.m_pos.y = dropPoint.y;
 
     return GetEventHandler()->ProcessEvent(event);
-#else // __WXMICROWIN__
-    return FALSE;
 #endif
 }
 
+
 bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
                                   short nHitTest,
                                   int WXUNUSED(mouseMsg))
@@ -3485,15 +3490,10 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
     // first ask the user code - it may wish to set the cursor in some very
     // specific way (for example, depending on the current position)
     POINT pt;
-#ifdef __WIN32__
     if ( !::GetCursorPos(&pt) )
     {
         wxLogLastError(wxT("GetCursorPos"));
     }
-#else
-    // In WIN16 it doesn't return a value.
-    ::GetCursorPos(&pt);
-#endif
 
     int x = pt.x,
         y = pt.y;
@@ -3555,7 +3555,16 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
 // owner drawn stuff
 // ---------------------------------------------------------------------------
 
-bool wxWindowMSW::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
+#if (wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE) || \
+        (wxUSE_CONTROLS && !defined(__WXUNIVERSAL__))
+    #define WXUNUSED_UNLESS_ODRAWN(param) param
+#else
+    #define WXUNUSED_UNLESS_ODRAWN(param)
+#endif
+
+bool
+wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
+                           WXDRAWITEMSTRUCT * WXUNUSED_UNLESS_ODRAWN(itemStruct))
 {
 #if wxUSE_OWNER_DRAWN
 
@@ -3585,22 +3594,34 @@ bool wxWindowMSW::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
     }
 #endif // wxUSE_MENUS_NATIVE
 
-#if wxUSE_CONTROLS
-    wxWindow *item = FindItem(id);
-    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
+#endif // USE_OWNER_DRAWN
+
+#if wxUSE_CONTROLS && !defined(__WXUNIVERSAL__)
+
+#if wxUSE_OWNER_DRAWN
+    wxControl *item = wxDynamicCast(FindItem(id), wxControl);
+#else // !wxUSE_OWNER_DRAWN
+    // we may still have owner-drawn buttons internally because we have to make
+    // them owner-drawn to support colour change
+    wxControl *item = wxDynamicCast(FindItem(id), wxButton);
+#endif // USE_OWNER_DRAWN
+
+    if ( item )
     {
-        return ((wxControl *)item)->MSWOnDraw(itemStruct);
+        return item->MSWOnDraw(itemStruct);
     }
-#endif // wxUSE_CONTROLS
 
-#endif // USE_OWNER_DRAWN
+#endif // wxUSE_CONTROLS
 
     return FALSE;
 }
 
-bool wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
+bool
+wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
+                              WXMEASUREITEMSTRUCT *
+                                  WXUNUSED_UNLESS_ODRAWN(itemStruct))
 {
-#if wxUSE_OWNER_DRAWN
+#if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
     // is it a menu item?
     MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
     if ( id == 0 && pMeasureStruct->CtlType == ODT_MENU )
@@ -3613,12 +3634,13 @@ bool wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
                                         &pMeasureStruct->itemHeight);
     }
 
-    wxWindow *item = FindItem(id);
-    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
+    wxControl *item = wxDynamicCast(FindItem(id), wxControl);
+    if ( item )
     {
-        return ((wxControl *)item)->MSWOnMeasure(itemStruct);
+        return item->MSWOnMeasure(itemStruct);
     }
-#endif  // owner-drawn menus
+#endif // wxUSE_OWNER_DRAWN
+
     return FALSE;
 }
 
@@ -3657,7 +3679,11 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush,
 #ifndef __WXMICROWIN__
     WXHBRUSH hBrush = 0;
 
+#ifdef __WXWINCE__
+    if (FALSE)
+#else
     if ( nCtlColor == CTLCOLOR_DLG )
+#endif
     {
         hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
     }
@@ -3783,7 +3809,7 @@ void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
         // FIXME-MT
         gs_hasStdCmap = FALSE;
     }
-    wxWindowList::Node *node = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
     while ( node )
     {
         // Only propagate to non-top-level windows because Windows already
@@ -3887,7 +3913,9 @@ extern wxCOLORMAP *wxGetStdColourMap()
 
 bool wxWindowMSW::HandlePaint()
 {
-#ifdef __WIN32__
+//    if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
+//        return FALSE;
+
     HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
     if ( !hRegion )
         wxLogLastError(wxT("CreateRectRgn"));
@@ -3895,14 +3923,6 @@ bool wxWindowMSW::HandlePaint()
         wxLogLastError(wxT("GetUpdateRgn"));
 
     m_updateRegion = wxRegion((WXHRGN) hRegion);
-#else // Win16
-    RECT updateRect;
-    ::GetUpdateRect(GetHwnd(), &updateRect, FALSE);
-
-    m_updateRegion = wxRegion(updateRect.left, updateRect.top,
-                              updateRect.right - updateRect.left,
-                              updateRect.bottom - updateRect.top);
-#endif // Win32/16
 
     wxPaintEvent event(m_windowId);
     event.SetEventObject(this);
@@ -3939,6 +3959,29 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
     if ( ::IsIconic(GetHwnd()) )
         return TRUE;
 
+#if 0
+    if (GetParent() && GetParent()->GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
+    {
+        return FALSE;
+    }
+
+    if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
+    {
+        if (wxUxThemeEngine::Get())
+        {
+            WXHTHEME hTheme = wxUxThemeEngine::Get()->m_pfnOpenThemeData(GetHWND(), L"TAB");
+            if (hTheme)
+            {
+                WXURECT rect;
+                ::GetClientRect((HWND) GetHWND(), (RECT*) & rect);
+                wxUxThemeEngine::Get()->m_pfnDrawThemeBackground(hTheme, hdc, 10 /* TABP_BODY */, 0, &rect, &rect);
+                wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme);
+                return TRUE;
+            }
+        }
+    }
+#endif
+
     wxDCTemp dc(hdc);
 
     dc.SetHDC(hdc);
@@ -3971,11 +4014,16 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 
     HDC hdc = (HDC)event.GetDC()->GetHDC();
 
+#ifndef __WXWINCE__
     int mode = ::SetMapMode(hdc, MM_TEXT);
+#endif
 
     ::FillRect(hdc, &rect, hBrush);
     ::DeleteObject(hBrush);
+
+#ifndef __WXWINCE__
     ::SetMapMode(hdc, mode);
+#endif
 }
 
 // ---------------------------------------------------------------------------
@@ -4006,6 +4054,17 @@ bool wxWindowMSW::HandleMove(int x, int y)
     return GetEventHandler()->ProcessEvent(event);
 }
 
+bool wxWindowMSW::HandleMoving(wxRect& rect)
+{
+    wxMoveEvent event(rect, m_windowId);
+    event.SetEventObject(this);
+
+    bool rc = GetEventHandler()->ProcessEvent(event);
+    if (rc)
+        rect = event.GetRect();
+    return rc;
+}
+
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h),
                              WXUINT WXUNUSED(flag))
 {
@@ -4018,8 +4077,22 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h),
     return GetEventHandler()->ProcessEvent(event);
 }
 
+bool wxWindowMSW::HandleSizing(wxRect& rect)
+{
+    wxSizeEvent event(rect, m_windowId);
+    event.SetEventObject(this);
+
+    bool rc = GetEventHandler()->ProcessEvent(event);
+    if (rc)
+        rect = event.GetRect();
+    return rc;
+}
+
 bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
 {
+#ifdef __WXWINCE__
+    return FALSE;
+#else
     MINMAXINFO *info = (MINMAXINFO *)mmInfo;
 
     bool rc = FALSE;
@@ -4054,6 +4127,7 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
     }
 
     return rc;
+#endif
 }
 
 // ---------------------------------------------------------------------------
@@ -4126,6 +4200,7 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
 
 bool wxWindowMSW::HandleSysCommand(WXWPARAM wParam, WXLPARAM WXUNUSED(lParam))
 {
+#ifndef __WXWINCE__
     // 4 bits are reserved
     switch ( wParam & 0xFFFFFFF0 )
     {
@@ -4135,6 +4210,7 @@ bool wxWindowMSW::HandleSysCommand(WXWPARAM wParam, WXLPARAM WXUNUSED(lParam))
         case SC_MINIMIZE:
             return HandleMinimize();
     }
+#endif
 
     return FALSE;
 }
@@ -4157,9 +4233,15 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     event.m_leftDown = (flags & MK_LBUTTON) != 0;
     event.m_middleDown = (flags & MK_MBUTTON) != 0;
     event.m_rightDown = (flags & MK_RBUTTON) != 0;
-    event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
+ //   event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
+    // Returns different negative values on WinME and WinNT,
+    // so simply test for negative value.
+    event.m_altDown = ::GetKeyState(VK_MENU) < 0;
+
+#ifndef __WXWINCE__
+    event.SetTimestamp(::GetMessageTime());
+#endif
 
-    event.SetTimestamp(s_currentMsg.time);
     event.m_eventObject = this;
     event.SetId(GetId());
 
@@ -4190,7 +4272,13 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
     HWND hwnd = GetHwndOf(win),
          hwndUnderMouse;
 
-#ifdef __WIN32__
+#ifdef __WXWINCE__
+    hwndUnderMouse = ::ChildWindowFromPoint
+                       (
+                        hwnd,
+                        pt
+                       );
+#else
     hwndUnderMouse = ::ChildWindowFromPointEx
                        (
                         hwnd,
@@ -4199,9 +4287,9 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
                         CWP_SKIPDISABLED    |
                         CWP_SKIPTRANSPARENT
                        );
+#endif
 
     if ( !hwndUnderMouse || hwndUnderMouse == hwnd )
-#endif // __WIN32__
     {
         // now try any child window at all
         hwndUnderMouse = ::ChildWindowFromPoint(hwnd, pt);
@@ -4266,7 +4354,19 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
         {
             // Generate an ENTER event
             m_mouseInWindow = TRUE;
-
+#if _WIN32_WINNT >= 0x0400
+#ifndef __WXWINCE__
+            TRACKMOUSEEVENT trackinfo;
+
+            trackinfo.cbSize = sizeof(trackinfo);
+            trackinfo.dwFlags = TME_LEAVE;
+            trackinfo.hwndTrack = GetHwnd();
+            //Use the commctrl.h _TrackMouseEvent, which will call the
+            // appropriate TrackMouseEvent or emulate it ( win95 )
+            // else we need _WIN32_WINNT >= 0x0400 
+            _TrackMouseEvent(&trackinfo);
+#endif
+#endif
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
@@ -4304,7 +4404,6 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
     event.m_wheelRotation = (short)HIWORD(wParam);
     event.m_wheelDelta = WHEEL_DELTA;
 
-#ifdef __WIN32__
     static int s_linesPerRotation = -1;
     if ( s_linesPerRotation == -1 )
     {
@@ -4318,10 +4417,6 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
             s_linesPerRotation = 3;
         }
     }
-#else // Win16
-    // no SystemParametersInfo() under Win16
-    static const int s_linesPerRotation = 3;
-#endif
 
     event.m_linesPerAction = s_linesPerRotation;
     return GetEventHandler()->ProcessEvent(event);
@@ -4356,7 +4451,9 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
     event.m_keyCode = id;
     event.m_rawCode = (wxUint32) wParam;
     event.m_rawFlags = (wxUint32) lParam;
-    event.SetTimestamp(s_currentMsg.time);
+#ifndef __WXWINCE__
+    event.SetTimestamp(::GetMessageTime());
+#endif
 
     // translate the position to client coords
     POINT pt;
@@ -4376,8 +4473,6 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
 // WM_KEYDOWN one
 bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
 {
-    bool ctrlDown = FALSE;
-
     int id;
     if ( isASCII )
     {
@@ -4402,7 +4497,7 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
                     break;
 
                 default:
-                    ctrlDown = TRUE;
+                    //ctrlDown = TRUE;
                     break;
             }
         }
@@ -4478,10 +4573,11 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
     return FALSE;
 }
 
-#ifdef __WIN32__
-
 int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
 {
+    // FIXME: implement GetMenuItemCount for WinCE, possibly
+    // in terms of GetMenuItemInfo
+#ifndef __WXWINCE__
     const HMENU hmenu = (HMENU)lParam;
 
     MENUITEMINFO mii;
@@ -4528,19 +4624,17 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
                 }
             }
         }
-        else // failed ot get the menu text?
+        else // failed to get the menu text?
         {
             // it's not fatal, so don't show error, but still log
             // it
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
-
+#endif
     return wxNOT_FOUND;
 }
 
-#endif // __WIN32__
-
 // ---------------------------------------------------------------------------
 // joystick
 // ---------------------------------------------------------------------------
@@ -4676,16 +4770,13 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
 
     case SB_THUMBPOSITION:
     case SB_THUMBTRACK:
-#ifdef __WIN32__
         // under Win32, the scrollbar range and position are 32 bit integers,
         // but WM_[HV]SCROLL only carry the low 16 bits of them, so we must
         // explicitly query the scrollbar for the correct position (this must
         // be done only for these two SB_ events as they are the only one
         // carrying the scrollbar position)
         {
-            SCROLLINFO scrollInfo;
-            wxZeroMemory(scrollInfo);
-            scrollInfo.cbSize = sizeof(SCROLLINFO);
+            WinStruct<SCROLLINFO> scrollInfo;
             scrollInfo.fMask = SIF_TRACKPOS;
 
             if ( !::GetScrollInfo(GetHwnd(),
@@ -4693,12 +4784,12 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
                                                               : SB_VERT,
                                   &scrollInfo) )
             {
-                wxLogLastError(_T("GetScrollInfo"));
+                // Not neccessarily an error, if there are no scrollbars yet.
+                // wxLogLastError(_T("GetScrollInfo"));
             }
 
             event.SetPosition(scrollInfo.nTrackPos);
         }
-#endif // Win32
 
         event.m_eventType = wParam == SB_THUMBPOSITION
                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
@@ -4849,7 +4940,7 @@ int wxCharCodeMSWToWX(int keySym)
 int wxCharCodeWXToMSW(int id, bool *isVirtual)
 {
     *isVirtual = TRUE;
-    int keySym = 0;
+    int keySym;
     switch (id)
     {
     case WXK_CANCEL:    keySym = VK_CANCEL; break;
@@ -4923,6 +5014,18 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual)
     return keySym;
 }
 
+bool wxGetKeyState(wxKeyCode key)
+{
+    bool bVirtual;
+    int vkey = wxCharCodeWXToMSW(key, &bVirtual);
+    
+    //there aren't WXK_ macros for non-virtual key codes
+    if (bVirtual == false)
+        return false;
+
+    return GetKeyState(vkey) < 0;
+}
+
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();
@@ -4946,9 +5049,6 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
         win = wxFindWinFromHandle((WXHWND)hwnd);
         if ( !win )
         {
-            // all these hacks only work under Win32 anyhow
-#ifdef __WIN32__
-
 #if wxUSE_RADIOBOX
             // native radiobuttons return DLGC_RADIOBUTTON here and for any
             // wxWindow class which overrides WM_GETDLGCODE processing to
@@ -4968,8 +5068,6 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
                 win = wxSpinCtrl::GetSpinForTextCtrl((WXHWND)hwnd);
             }
 #endif // wxUSE_SPINCTRL
-
-#endif // Win32
         }
     }
 
@@ -4998,7 +5096,7 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
     return win;
 }
 
-#ifndef __WXMICROWIN__
+#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
 
 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
 // in active frames and dialogs, regardless of where the focus is.
@@ -5014,23 +5112,13 @@ void wxSetKeyboardHook(bool doIt)
         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
             );
     }
     else
     {
         UnhookWindowsHookEx(wxTheKeyboardHook);
-
-        // avoids warning about statement with no effect (FreeProcInstance
-        // doesn't do anything under Win32)
-#if !defined(__WIN32__) && !defined(__NT__)
-        FreeProcInstance(wxTheKeyboardHookProc);
-#endif
     }
 }
 
@@ -5051,8 +5139,9 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
             event.m_keyCode = id;
             event.m_shiftDown = wxIsShiftDown();
             event.m_controlDown = wxIsCtrlDown();
-            event.SetTimestamp(s_currentMsg.time);
-
+#ifndef __WXWINCE__
+            event.SetTimestamp(::GetMessageTime());
+#endif
             wxWindow *win = wxGetActiveWindow();
             wxEvtHandler *handler;
             if ( win )
@@ -5138,7 +5227,6 @@ const char *wxGetMessageName(int message)
         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";
@@ -5154,7 +5242,6 @@ const char *wxGetMessageName(int message)
         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";
@@ -5183,11 +5270,9 @@ const char *wxGetMessageName(int message)
         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";
-#endif  //WIN32
 
         case 0x0110: return "WM_INITDIALOG";
         case 0x0111: return "WM_COMMAND";
@@ -5215,14 +5300,12 @@ const char *wxGetMessageName(int message)
         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";
-#endif  //WIN32
 
         case 0x0220: return "WM_MDICREATE";
         case 0x0221: return "WM_MDIDESTROY";
@@ -5237,7 +5320,6 @@ const char *wxGetMessageName(int message)
         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";
@@ -5246,7 +5328,6 @@ const char *wxGetMessageName(int message)
         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";
@@ -5266,8 +5347,10 @@ const char *wxGetMessageName(int message)
         case 0x030F: return "WM_QUERYNEWPALETTE";
         case 0x0310: return "WM_PALETTEISCHANGING";
         case 0x0311: return "WM_PALETTECHANGED";
+#if wxUSE_HOTKEY
+        case 0x0312: return "WM_HOTKEY";
+#endif
 
-#ifdef __WIN32__
         // common controls messages - although they're not strictly speaking
         // standard, it's nice to decode them nevertheless
 
@@ -5489,8 +5572,6 @@ const char *wxGetMessageName(int message)
         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);
@@ -5587,3 +5668,108 @@ wxPoint wxGetMousePosition()
     return wxPoint(pt.x, pt.y);
 }
 
+#if wxUSE_HOTKEY
+
+bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
+{
+    UINT win_modifiers=0;
+    if ( modifiers & wxMOD_ALT )
+        win_modifiers |= MOD_ALT;
+    if ( modifiers & wxMOD_SHIFT )
+        win_modifiers |= MOD_SHIFT;
+    if ( modifiers & wxMOD_CONTROL )
+        win_modifiers |= MOD_CONTROL;
+    if ( modifiers & wxMOD_WIN )
+        win_modifiers |= MOD_WIN;
+
+    if ( !::RegisterHotKey(GetHwnd(), hotkeyId, win_modifiers, keycode) )
+    {
+        wxLogLastError(_T("RegisterHotKey"));
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+bool wxWindowMSW::UnregisterHotKey(int hotkeyId)
+{
+    if ( !::UnregisterHotKey(GetHwnd(), hotkeyId) )
+    {
+        wxLogLastError(_T("UnregisterHotKey"));
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam)
+{
+    int hotkeyId = wParam;
+    int virtualKey = HIWORD(lParam);
+    int win_modifiers = LOWORD(lParam);
+
+    wxKeyEvent event(CreateKeyEvent(wxEVT_HOTKEY, virtualKey, wParam, lParam));
+    event.SetId(hotkeyId);
+    event.m_shiftDown = (win_modifiers & MOD_SHIFT) != 0;
+    event.m_controlDown = (win_modifiers & MOD_CONTROL) != 0;
+    event.m_altDown = (win_modifiers & MOD_ALT) != 0;
+    event.m_metaDown = (win_modifiers & MOD_WIN) != 0;
+
+    return GetEventHandler()->ProcessEvent(event);
+}
+
+#endif // wxUSE_HOTKEY
+
+// Not verified for WinCE
+#ifndef __WXWINCE__
+/*
+ *     wxEventFixModule (needs a better name) allows message handling to continute while a menu
+ *  is being shown - ie, to continue processing messages from a worker thread.
+ * 
+ *  Code originally by Jason W. from wx-dev, reworked into a wxModule by Chris Mellon
+ */
+
+class wxEventFixModule : public wxModule {
+public:
+       //base class virtuals
+       virtual bool OnInit() {
+               wxEventFixModule::s_hMsgHookProc = SetWindowsHookEx(
+                       WH_GETMESSAGE,
+                       &wxEventFixModule::MsgHookProc,
+                       NULL,
+                       GetCurrentThreadId());
+                       wxLogDebug(_T("Loaded event fix module"));
+                       return true;
+       };
+       virtual void OnExit() {
+               UnhookWindowsHookEx(wxEventFixModule::s_hMsgHookProc);
+
+       };
+       static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
+               MSG *msg = (MSG*)lParam;
+               switch (msg->message)
+               {
+        case WM_NULL:
+            static bool bInHookProc = false;
+            if (!bInHookProc)
+            {
+                bInHookProc = true;
+                wxTheApp->ProcessPendingEvents();
+                bInHookProc = false;
+            }
+            break;
+               }
+               return CallNextHookEx(wxEventFixModule::s_hMsgHookProc, nCode, wParam, lParam);
+       };
+private:
+       static HHOOK s_hMsgHookProc;
+DECLARE_DYNAMIC_CLASS(wxEventFixModule)
+};
+HHOOK wxEventFixModule::s_hMsgHookProc = 0;
+
+IMPLEMENT_DYNAMIC_CLASS(wxEventFixModule, wxModule)
+#endif
+    // __WXWINCE__
+