]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Various changes to make pop up menus work
[wxWidgets.git] / src / msw / window.cpp
index b47f269cfd1770a7aeeb5b7451c3ceaf64cc2205..4ee8e7b1f36dfbd65187e9e42c997bc09f4a05b1 100644 (file)
@@ -386,45 +386,27 @@ bool wxWindowMSW::Create(wxWindow *parent,
 
     parent->AddChild(this);
 
 
     parent->AddChild(this);
 
-    // all windows are created visible
-    DWORD msflags = WS_CHILD | WS_VISIBLE;
+    // note that all windows are created visible by default
+    WXDWORD exstyle;
+    DWORD msflags = WS_VISIBLE | MSWGetCreateWindowFlags(&exstyle);
 
 #ifdef __WXUNIVERSAL__
 
 #ifdef __WXUNIVERSAL__
-    // no 3d effects, we draw them ourselves
-    WXDWORD exStyle = 0;
-#else // !wxUniversal
-    if ( style & wxCLIP_CHILDREN )
-        msflags |= WS_CLIPCHILDREN;
-    if ( style & wxCLIP_SIBLINGS )
-        msflags |= WS_CLIPSIBLINGS;
-
-    bool want3D;
-    WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
-
-    // Even with extended styles, need to combine with WS_BORDER
-    // for them to look right.
-    if ( want3D ||
-        (m_windowStyle & (wxBORDER |
-                          wxSIMPLE_BORDER |
-                          wxRAISED_BORDER |
-                          wxSUNKEN_BORDER |
-                          wxDOUBLE_BORDER)) )
-    {
-        msflags |= WS_BORDER;
-    }
-#endif // wxUniversal/!wxUniversal
+    // no borders, we draw them ourselves
+    exstyle = 0;
+    msflags &= ~WS_BORDER;
+#endif // wxUniversal
 
     if ( style & wxPOPUP_WINDOW )
     {
         // a popup window floats on top of everything
 
     if ( style & wxPOPUP_WINDOW )
     {
         // a popup window floats on top of everything
-        exStyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
+        exstyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
 
         // it is also created hidden as other top level windows
         msflags &= ~WS_VISIBLE;
         m_isShown = FALSE;
     }
 
 
         // it is also created hidden as other top level windows
         msflags &= ~WS_VISIBLE;
         m_isShown = FALSE;
     }
 
-    return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exStyle);
+    return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle);
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -962,7 +944,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
     wxAssociateWinWithHandle(hwnd, this);
 
     m_oldWndProc = (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
     wxAssociateWinWithHandle(hwnd, this);
 
     m_oldWndProc = (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
-    
+
     // we don't need to subclass the window of our own class (in the Windows
     // sense of the word)
     if ( !wxCheckWindowWndProc(hWnd, (WXFARPROC)wxWndProc) )
     // we don't need to subclass the window of our own class (in the Windows
     // sense of the word)
     if ( !wxCheckWindowWndProc(hWnd, (WXFARPROC)wxWndProc) )
@@ -1017,17 +999,134 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
     //     FIXME: Doesn't handle wnd procs set by SetWindowLong, only these set
     //            with RegisterClass!!
 
     //     FIXME: Doesn't handle wnd procs set by SetWindowLong, only these set
     //            with RegisterClass!!
 
-    static wxChar buffer[512];
-    WNDCLASS cls;
+    if ( wxUsingUnicowsDll() )
+    {
+        static wxChar buffer[512];
+        WNDCLASS cls;
 
 
-    ::GetClassName((HWND)hWnd, buffer, 512);
-    ::GetClassInfo(wxGetInstance(), buffer, &cls);
-    return wndProc == (WXFARPROC)cls.lpfnWndProc;
-#else
-    return wndProc == (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
+        ::GetClassName((HWND)hWnd, buffer, 512);
+        ::GetClassInfo(wxGetInstance(), buffer, &cls);
+        return wndProc == (WXFARPROC)cls.lpfnWndProc;
+    }
+    else
 #endif
 #endif
+    {
+        return wndProc == (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
+    }
+}
+
+// ----------------------------------------------------------------------------
+// Style handling
+// ----------------------------------------------------------------------------
+
+void wxWindowMSW::SetWindowStyleFlag(long flags)
+{
+    long flagsOld = GetWindowStyleFlag();
+    if ( flags == flagsOld )
+        return;
+
+    // update the internal variable
+    wxWindowBase::SetWindowStyleFlag(flags);
+
+    // now update the Windows style as well if needed - and if the window had
+    // been already created
+    if ( !GetHwnd() )
+        return;
+
+    WXDWORD exstyle, exstyleOld;
+    long style = MSWGetStyle(flags, &exstyle),
+         styleOld = MSWGetStyle(flagsOld, &exstyleOld);
+
+    if ( style != styleOld )
+    {
+        // some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by
+        // this function so instead of simply setting the style to the new
+        // value we clear the bits which were set in styleOld but are set in
+        // the new one and set the ones which were not set before
+        long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE);
+        styleReal &= ~styleOld;
+        styleReal |= style;
+
+        ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
+    }
+
+    // and the extended style
+    if ( exstyle != exstyleOld )
+    {
+        long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+        exstyleReal &= ~exstyleOld;
+        exstyleReal |= exstyle;
+
+        ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
+
+        // we must call SetWindowPos() to flash the cached extended style and
+        // also to make the change to wxSTAY_ON_TOP style take effect: just
+        // setting the style simply doesn't work
+        if ( !::SetWindowPos(GetHwnd(),
+                             exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
+                                                         : HWND_NOTOPMOST,
+                             0, 0, 0, 0,
+                             SWP_NOMOVE | SWP_NOSIZE) )
+        {
+            wxLogLastError(_T("SetWindowPos"));
+        }
+    }
 }
 
 }
 
+WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
+{
+    // translate the style
+    WXDWORD style = WS_CHILD;
+
+    if ( flags & wxCLIP_CHILDREN )
+        style |= WS_CLIPCHILDREN;
+
+    if ( flags & wxCLIP_SIBLINGS )
+        style |= WS_CLIPSIBLINGS;
+
+    wxBorder border = (wxBorder)(flags & wxBORDER_MASK);
+    if ( border != wxBORDER_NONE && border != wxBORDER_DEFAULT )
+        style |= WS_BORDER;
+
+    // now deal with ext style if the caller wants it
+    if ( exstyle )
+    {
+        *exstyle = 0;
+
+        if ( flags & wxTRANSPARENT_WINDOW )
+            *exstyle |= WS_EX_TRANSPARENT;
+
+        switch ( flags & wxBORDER_MASK )
+        {
+            default:
+                wxFAIL_MSG( _T("unknown border style") );
+                // fall through
+
+            case wxBORDER_NONE:
+            case wxBORDER_SIMPLE:
+            case wxBORDER_DEFAULT:
+                break;
+
+            case wxBORDER_STATIC:
+                *exstyle |= WS_EX_STATICEDGE;
+                break;
+
+            case wxBORDER_RAISED:
+                *exstyle |= WS_EX_WINDOWEDGE;
+                break;
+
+            case wxBORDER_SUNKEN:
+                *exstyle |= WS_EX_CLIENTEDGE;
+                break;
+
+            case wxBORDER_DOUBLE:
+                *exstyle |= WS_EX_DLGMODALFRAME;
+                break;
+        }
+    }
+
+    return style;
+}
 
 // Make a Windows extended style from the given wxWindows window style
 WXDWORD wxWindowMSW::MakeExtendedStyle(long style, bool eliminateBorders)
 
 // Make a Windows extended style from the given wxWindows window style
 WXDWORD wxWindowMSW::MakeExtendedStyle(long style, bool eliminateBorders)
@@ -1175,7 +1274,9 @@ void wxWindowMSW::OnIdle(wxIdleEvent& WXUNUSED(event))
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
-        if ( !IsMouseInWindow() && !HasCapture())
+        // note that we should generate the leave event whether the window has
+        // or doesn't have mouse capture
+        if ( !IsMouseInWindow() )
         {
             // Generate a LEAVE event
             m_mouseInWindow = FALSE;
         {
             // Generate a LEAVE event
             m_mouseInWindow = FALSE;
@@ -1544,15 +1645,6 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
             break;
         }
 
             break;
         }
 
-        if ( i == 3 )
-        {
-            // how did it happen? maybe OnSize() handler does something really
-            // strange in this class?
-            wxFAIL_MSG( _T("logic error in DoSetClientSize") );
-
-            break;
-        }
-
         int widthClient = width,
             heightClient = height;
 
         int widthClient = width,
             heightClient = height;
 
@@ -2611,21 +2703,6 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 #endif // __WIN32__
             }
             break;
 #endif // __WIN32__
-
-            // unfortunately this doesn't really work as then window which
-            // doesn't accept focus doesn't get any mouse events neither which
-            // means it can't get any input at all
-#if 0 //def __WXUNIVERSAL__
-        case WM_NCHITTEST:
-            // we shouldn't allow the windows which don't want to get focus to
-            // get it
-            if ( !AcceptsFocus() )
-            {
-                rc.result = HTTRANSPARENT;
-                processed = TRUE;
-            }
-            break;
-#endif // __WXUNIVERSAL__
     }
 
     if ( !processed )
     }
 
     if ( !processed )
@@ -3349,30 +3426,38 @@ WXHBRUSH wxWindowMSW::OnCtlColor(WXHDC WXUNUSED(hDC),
 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
 {
 #if wxUSE_PALETTE
 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
 {
 #if wxUSE_PALETTE
-        // same as below except we don't respond to our own messages
-        if (hWndPalChange != GetHWND()) {
+    // same as below except we don't respond to our own messages
+    if ( hWndPalChange != GetHWND() )
+    {
         // check to see if we our our parents have a custom palette
         wxWindow *win = this;
         // check to see if we our our parents have a custom palette
         wxWindow *win = this;
-        while (!win->HasCustomPalette() && win->GetParent()) win = win->GetParent();
-        if (win->HasCustomPalette()) {
-            /* realize the palette to see whether redrawing is needed */
-            HDC hdc = GetDC((HWND) hWndPalChange);
-            win->m_palette.SetHPALETTE( (WXHPALETTE)
-                ::SelectPalette(hdc, (HPALETTE) win->m_palette.GetHPALETTE(), false) );
+        while ( win && !win->HasCustomPalette() )
+        {
+            win = win->GetParent();
+        }
+
+        if ( win && win->HasCustomPalette() )
+        {
+            // realize the palette to see whether redrawing is needed
+            HDC hdc = ::GetDC((HWND) hWndPalChange);
+            win->m_palette.SetHPALETTE((WXHPALETTE)
+                    ::SelectPalette(hdc, GetHpaletteOf(win->m_palette), FALSE));
 
             int result = ::RealizePalette(hdc);
 
             int result = ::RealizePalette(hdc);
-            /* restore the palette (before releasing the DC) */
-            win->m_palette.SetHPALETTE( (WXHPALETTE)
-                ::SelectPalette(hdc, (HPALETTE) win->m_palette.GetHPALETTE(), true) );
-            RealizePalette(hdc);
-            ReleaseDC((HWND) hWndPalChange, hdc);
-            /* now check for the need to redraw */
+
+            // restore the palette (before releasing the DC)
+            win->m_palette.SetHPALETTE((WXHPALETTE)
+                    ::SelectPalette(hdc, GetHpaletteOf(win->m_palette), FALSE));
+            ::RealizePalette(hdc);
+            ::ReleaseDC((HWND) hWndPalChange, hdc);
+
+            // now check for the need to redraw
             if (result > 0)
                 InvalidateRect((HWND) hWndPalChange, NULL, TRUE);
             if (result > 0)
                 InvalidateRect((HWND) hWndPalChange, NULL, TRUE);
-            }
-
         }
         }
-#endif
+
+    }
+#endif // wxUSE_PALETTE
 
     wxPaletteChangedEvent event(GetId());
     event.SetEventObject(this);
 
     wxPaletteChangedEvent event(GetId());
     event.SetEventObject(this);
@@ -3392,19 +3477,19 @@ bool wxWindowMSW::HandleQueryNewPalette()
         /* realize the palette to see whether redrawing is needed */
         HDC hdc = GetDC((HWND) GetHWND());
         win->m_palette.SetHPALETTE( (WXHPALETTE)
         /* realize the palette to see whether redrawing is needed */
         HDC hdc = GetDC((HWND) GetHWND());
         win->m_palette.SetHPALETTE( (WXHPALETTE)
-             ::SelectPalette(hdc, (HPALETTE) win->m_palette.GetHPALETTE(), false) );
+             ::SelectPalette(hdc, (HPALETTE) win->m_palette.GetHPALETTE(), FALSE) );
 
         int result = ::RealizePalette(hdc);
         /* restore the palette (before releasing the DC) */
         win->m_palette.SetHPALETTE( (WXHPALETTE)
 
         int result = ::RealizePalette(hdc);
         /* restore the palette (before releasing the DC) */
         win->m_palette.SetHPALETTE( (WXHPALETTE)
-             ::SelectPalette(hdc, (HPALETTE) win->m_palette.GetHPALETTE(), true) );
+             ::SelectPalette(hdc, (HPALETTE) win->m_palette.GetHPALETTE(), TRUE) );
         ::RealizePalette(hdc);
         ::ReleaseDC((HWND) GetHWND(), hdc);
         /* now check for the need to redraw */
         if (result > 0)
             ::InvalidateRect((HWND) GetHWND(), NULL, TRUE);
         }
         ::RealizePalette(hdc);
         ::ReleaseDC((HWND) GetHWND(), hdc);
         /* now check for the need to redraw */
         if (result > 0)
             ::InvalidateRect((HWND) GetHWND(), NULL, TRUE);
         }
-#endif
+#endif // wxUSE_PALETTE
 
     wxQueryNewPaletteEvent event(GetId());
     event.SetEventObject(this);
 
     wxQueryNewPaletteEvent event(GetId());
     event.SetEventObject(this);
@@ -3660,27 +3745,32 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
 
     bool rc = FALSE;
 
 
     bool rc = FALSE;
 
-    if ( m_minWidth != -1 )
+    int minWidth = GetMinWidth(),
+        minHeight = GetMinHeight(),
+        maxWidth = GetMaxWidth(),
+        maxHeight = GetMaxHeight();
+
+    if ( minWidth != -1 )
     {
     {
-        info->ptMinTrackSize.x = m_minWidth;
+        info->ptMinTrackSize.x = minWidth;
         rc = TRUE;
     }
 
         rc = TRUE;
     }
 
-    if ( m_minHeight != -1 )
+    if ( minHeight != -1 )
     {
     {
-        info->ptMinTrackSize.y = m_minHeight;
+        info->ptMinTrackSize.y = minHeight;
         rc = TRUE;
     }
 
         rc = TRUE;
     }
 
-    if ( m_maxWidth != -1 )
+    if ( maxWidth != -1 )
     {
     {
-        info->ptMaxTrackSize.x = m_maxWidth;
+        info->ptMaxTrackSize.x = maxWidth;
         rc = TRUE;
     }
 
         rc = TRUE;
     }
 
-    if ( m_maxHeight != -1 )
+    if ( maxHeight != -1 )
     {
     {
-        info->ptMaxTrackSize.y = m_maxHeight;
+        info->ptMaxTrackSize.y = maxHeight;
         rc = TRUE;
     }
 
         rc = TRUE;
     }
 
@@ -5059,6 +5149,7 @@ wxPoint wxGetMousePosition()
 {
     POINT pt;
     GetCursorPos( & pt );
 {
     POINT pt;
     GetCursorPos( & pt );
+
     return wxPoint(pt.x, pt.y);
 }
 
     return wxPoint(pt.x, pt.y);
 }