]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
resolving conflicts in files I had forgot to commit (sorry)
[wxWidgets.git] / src / msw / window.cpp
index d57a865456eceed0fa3562b7740ea3790c8d1f1c..5762e1de98547a37ba8c13aaed6f4d9e37635ae0 100644 (file)
@@ -17,7 +17,7 @@
 // headers
 // ---------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "window.h"
 #endif
 
     #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
@@ -91,6 +93,7 @@
 
 #include "wx/textctrl.h"
 #include "wx/notebook.h"
+#include "wx/listctrl.h"
 
 #include <string.h>
 
     #include "wx/msw/gnuwin32/extra.h"
 #endif
 
-#if defined(__GNUG__)
 #include "wx/msw/missing.h"
-#endif
 
 #if defined(__WXWINCE__)
 #include "wx/msw/wince/missing.h"
 #endif
 
-// ----------------------------------------------------------------------------
-// standard constants not available with all compilers/headers
-// ----------------------------------------------------------------------------
-
-// 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_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
-#endif
-
-#ifndef VK_OEM_COMMA
-    #define VK_OEM_PLUS     0xBB
-    #define VK_OEM_COMMA    0xBC
-    #define VK_OEM_MINUS    0xBD
-    #define VK_OEM_PERIOD   0xBE
-#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
@@ -220,6 +180,38 @@ static inline void wxBringWindowToTop(HWND hwnd)
     }
 }
 
+// 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() )
+    {
+        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 // !__WXWINCE__
+}
+
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
@@ -229,7 +221,113 @@ 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)
@@ -326,9 +424,6 @@ bool wxWindowMSW::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
 
 void wxWindowMSW::Init()
 {
-    // generic
-    InitBase();
-
     // MSW specific
     m_isBeingDeleted = FALSE;
     m_oldWndProc = NULL;
@@ -381,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
@@ -684,12 +776,6 @@ void wxWindowMSW::WarpPointer (int x, int y)
     }
 }
 
-#if WXWIN_COMPATIBILITY
-void wxWindowMSW::MSWDeviceToLogical (float *x, float *y) const
-{
-}
-#endif // WXWIN_COMPATIBILITY
-
 // ---------------------------------------------------------------------------
 // scrolling stuff
 // ---------------------------------------------------------------------------
@@ -700,61 +786,20 @@ static inline int wxDirToWinStyle(int orient)
     return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
 }
 
-#if WXWIN_COMPATIBILITY
-void wxWindowMSW::SetScrollRange(int orient, int range, bool refresh)
-{
-    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);
-    }
-
-    WinStruct<SCROLLINFO> info;
-    info.nPage = pageSize; // Have to set this, or scrollbar goes awry
-    info.nMin = 0;
-    info.nMax = range1;
-    info.fMask = SIF_RANGE | SIF_PAGE;
-
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollInfo(hWnd, wxDirToWinStyle(orient), &info, refresh);
-}
-
-void wxWindowMSW::SetScrollPage(int orient, int page, bool refresh)
-{
-    WinStruct<SCROLLINFO> info;
-    info.nPage = page;
-    info.fMask = SIF_PAGE;
-
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-        ::SetScrollInfo(hWnd, wxDirToWinStyle(orient), &info, refresh);
-}
-
-int wxWindowMSW::GetScrollPage(int orient) const
-{
-    return orient == wxHORIZONTAL ? m_xThumbSize : m_yThumbSize;
-}
-
-#endif // WXWIN_COMPATIBILITY
-
 inline int GetScrollPosition(HWND hWnd, int wOrient)
 {
 #ifdef __WXMICROWIN__
     return ::GetScrollPosWX(hWnd, wOrient);
 #else
-    SCROLLINFO scrollInfo;
+    WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
     if ( !::GetScrollInfo(hWnd,
-                                  wOrient,
-                                  &scrollInfo) )
+                          wOrient,
+                          &scrollInfo) )
     {
-        wxLogLastError(_T("GetScrollInfo"));
+        // Not neccessarily an error, if there are no scrollbars yet.
+        // wxLogLastError(_T("GetScrollInfo"));
     }
     return scrollInfo.nPos;
 //    return ::GetScrollPos(hWnd, wOrient);
@@ -781,13 +826,15 @@ int wxWindowMSW::GetScrollRange(int orient) const
     ::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
                      &minPos, &maxPos);
 #endif
-    SCROLLINFO scrollInfo;
+    WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.fMask = SIF_RANGE;
     if ( !::GetScrollInfo(hWnd,
-                                  orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                                  &scrollInfo) )
+                          orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
+                          &scrollInfo) )
     {
-        wxLogLastError(_T("GetScrollInfo"));
+        // 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"));
     }
     maxPos = scrollInfo.nMax;
 
@@ -931,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);
     }
@@ -977,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) )
     {
@@ -986,6 +1055,7 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
     }
 
     return wndProc == (WXFARPROC)cls.lpfnWndProc;
+#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -1122,37 +1192,6 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     return style;
 }
 
-#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()
 {
@@ -1236,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)
@@ -1652,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
 // ---------------------------------------------------------------------------
@@ -1710,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)
@@ -1811,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 {
@@ -1838,6 +1837,25 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         bProcess = FALSE;
                     break;
 
+                case VK_ESCAPE:
+                    {
+#if wxUSE_BUTTON
+                        wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),
+                                                      wxButton);
+                        if ( btn && btn->IsEnabled() )
+                        {
+                            // if we do have a cancel button, do press it
+                            btn->MSWCommand(BN_CLICKED, 0 /* unused */);
+
+                            // we consumed the message
+                            return TRUE;
+                        }
+#endif // wxUSE_BUTTON
+
+                        bProcess = FALSE;
+                    }
+                    break;
+
                 case VK_RETURN:
                     {
                         if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown )
@@ -1951,8 +1969,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         }
 #endif // 1/0
 
-        // we handle VK_ESCAPE ourselves in wxDialog::OnCharHook() and we
-        // shouldn't let IsDialogMessage() get it as it _always_ eats the
+        // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
         // message even when there is no cancel button and when the message is
         // needed by the control itself: in particular, it prevents the tree in
         // place edit control from being closed with Escape in a dialog
@@ -1987,7 +2004,10 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                       node;
                       node = node->GetNext() )
                 {
-                    if ( node->GetData()->AcceptsFocus() )
+                    wxWindow * const win = node->GetData();
+                    if ( win->AcceptsFocus() &&
+                            !(::GetWindowLong(GetHwndOf(win), GWL_EXSTYLE) &
+                                WS_EX_CONTROLPARENT) )
                     {
                         // it shouldn't hang...
                         canSafelyCallIsDlgMsg = TRUE;
@@ -1996,7 +2016,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                     }
                 }
             }
-#endif
+#endif // !__WXWINCE__
 
             if ( canSafelyCallIsDlgMsg )
             {
@@ -2300,8 +2320,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__
@@ -2328,6 +2375,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);
@@ -2717,7 +2820,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());
                 }
@@ -2781,7 +2884,20 @@ 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);
-                processed = GetEventHandler()->ProcessEvent(evtCtx);
+
+                // we could have got an event from our child, reflect it back
+                // to it if this is the case
+                wxWindow *win = NULL;
+                if ( wParam != m_hWnd )
+                {
+                    win = FindItemByHWND((WXHWND)wParam);
+                }
+
+                if ( !win )
+                    win = this;
+
+                evtCtx.SetEventObject(win);
+                processed = win->GetEventHandler()->ProcessEvent(evtCtx);
             }
             break;
 #endif
@@ -2866,15 +2982,17 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
                                            int& x, int& y,
                                            int& w, int& h) const
 {
+    // yes, those are just some arbitrary hardcoded numbers
     static const int DEFAULT_Y = 200;
+    static const int DEFAULT_W = 400;
     static const int DEFAULT_H = 250;
 
     bool nonDefault = FALSE;
 
     if ( pos.x == -1 )
     {
-        // if set x to CW_USEDEFAULT, y parameter is ignored anyhow so we can
-        // just as well set it to CW_USEDEFAULT as well
+        // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we
+        // can just as well set it to CW_USEDEFAULT as well
         x =
         y = CW_USEDEFAULT;
     }
@@ -2907,9 +3025,25 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
      */
     if ( size.x == -1 )
     {
-        // as above, h is not used at all in this case anyhow
-        w =
-        h = CW_USEDEFAULT;
+        // we don't use CW_USEDEFAULT here for several reasons:
+        //
+        //  1. it results in huge frames on modern screens (1000*800 is not
+        //     uncommon on my 1280*1024 screen) which is way too big for a half
+        //     empty frame of most of wxWindows samples for example)
+        //
+        //  2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which
+        //     the default is for whatever reason 8*8 which breaks client <->
+        //     window size calculations (it would be nice if it didn't, but it
+        //     does and the simplest way to fix it seemed to change the broken
+        //     default size anyhow)
+        //
+        //  3. there is just no advantage in doing it: with x and y it is
+        //     possible that [future versions of] Windows position the new top
+        //     level window in some smart way which we can't do, but we can
+        //     guess a reasonably good size for a new window just as well
+        //     ourselves
+        w = DEFAULT_W;
+        h = DEFAULT_H;
     }
     else
     {
@@ -2920,6 +3054,8 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
         nonDefault = TRUE;
     }
 
+    AdjustForParentClientOrigin(x, y);
+
     return nonDefault;
 }
 
@@ -2947,7 +3083,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");
     }
@@ -2955,18 +3091,37 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     // do create the window
     wxWindowCreationHook hook(this);
 
-    m_hWnd = (WXHWND)::CreateWindowEx
-                       (
-                            extendedStyle,
-                            className,
-                            title ? title : wxEmptyString,
-                            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 )
     {
@@ -3067,9 +3222,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
     }
 
@@ -3154,32 +3333,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();
-        }
-    }
-#endif
+        EnsureParentHasControlParentStyle(GetParent());
+#endif // !__WXWINCE__
 
     // TODO: should generate this event from WM_NCCREATE
     wxWindowCreateEvent event((wxWindow *)this);
@@ -3338,9 +3498,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);
 
@@ -3445,7 +3603,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
 
@@ -3477,28 +3644,32 @@ bool wxWindowMSW::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
 
 #endif // USE_OWNER_DRAWN
 
-#if wxUSE_CONTROLS
+#if wxUSE_CONTROLS && !defined(__WXUNIVERSAL__)
 
 #if wxUSE_OWNER_DRAWN
-    wxWindow *item = FindItem(id);
-    if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
-        return ((wxControl *)item)->MSWOnDraw(itemStruct);
-#elif !defined(__WXUNIVERSAL__)
+    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
-    wxWindow *item = FindItem(id);
-    if ( item && item->IsKindOf(CLASSINFO(wxButton)) )
-        return ((wxButton *)item)->MSWOnDraw(itemStruct);
+    wxControl *item = wxDynamicCast(FindItem(id), wxButton);
 #endif // USE_OWNER_DRAWN
 
+    if ( item )
+    {
+        return item->MSWOnDraw(itemStruct);
+    }
+
 #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 )
@@ -3511,12 +3682,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;
 }
 
@@ -4114,7 +4286,10 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     // so simply test for negative value.
     event.m_altDown = ::GetKeyState(VK_MENU) < 0;
 
-    event.SetTimestamp(s_currentMsg.time);
+#ifndef __WXWINCE__
+    event.SetTimestamp(::GetMessageTime());
+#endif
+
     event.m_eventObject = this;
     event.SetId(GetId());
 
@@ -4227,7 +4402,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);
 
@@ -4312,7 +4499,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;
@@ -4332,8 +4521,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 )
     {
@@ -4358,7 +4545,7 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
                     break;
 
                 default:
-                    ctrlDown = TRUE;
+                    //ctrlDown = TRUE;
                     break;
             }
         }
@@ -4645,7 +4832,8 @@ 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);
@@ -4800,7 +4988,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;
@@ -4874,6 +5062,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();
@@ -4987,8 +5187,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 )
@@ -5569,3 +5770,62 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam)
 
 #endif // wxUSE_HOTKEY
 
+// Not tested under WinCE
+#ifndef __WXWINCE__
+
+// this class installs a message hook which really wakes up our idle processing
+// each time a WM_NULL is received (wxWakeUpIdle does this), even if we're
+// sitting inside a local modal loop (e.g. a menu is opened or scrollbar is
+// being dragged or even inside ::MessageBox()) and so don't control message
+// dispatching otherwise
+class wxIdleWakeUpModule : public wxModule
+{
+public:
+       virtual bool OnInit()
+    {
+               ms_hMsgHookProc = ::SetWindowsHookEx
+                            (
+                             WH_GETMESSAGE,
+                             &wxIdleWakeUpModule::MsgHookProc,
+                             NULL,
+                             GetCurrentThreadId()
+                            );
+
+        if ( !ms_hMsgHookProc )
+        {
+            wxLogLastError(_T("SetWindowsHookEx(WH_GETMESSAGE)"));
+
+            return false;
+        }
+
+        return true;
+       }
+
+       virtual void OnExit()
+    {
+               ::UnhookWindowsHookEx(wxIdleWakeUpModule::ms_hMsgHookProc);
+       }
+
+       static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
+    {
+               MSG *msg = (MSG*)lParam;
+               if ( msg->message == WM_NULL )
+               {
+            wxTheApp->ProcessPendingEvents();
+               }
+
+               return CallNextHookEx(ms_hMsgHookProc, nCode, wParam, lParam);
+       };
+
+private:
+       static HHOOK ms_hMsgHookProc;
+
+    DECLARE_DYNAMIC_CLASS(wxIdleWakeUpModule)
+};
+
+HHOOK wxIdleWakeUpModule::ms_hMsgHookProc = 0;
+
+IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule, wxModule)
+
+#endif // __WXWINCE__
+