]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/frame.cpp
add support for alpha in color dialog on OSX, see #14127
[wxWidgets.git] / src / msw / frame.cpp
index 245c466534831ab6397a690e99c83b0785c8cafc..34e00745ec740b3740acb1e0f0adb852344ce544 100644 (file)
     #include "wx/univ/colschem.h"
 #endif // __WXUNIVERSAL__
 
+// FIXME-VC6: Only VC6 doesn't have this in its standard headers so this
+//            could be removed once support for it is dropped.
+#ifndef WM_UNINITMENUPOPUP
+    #define WM_UNINITMENUPOPUP 0x0125
+#endif
+
 // ----------------------------------------------------------------------------
 // globals
 // ----------------------------------------------------------------------------
 
-#if wxUSE_MENUS_NATIVE
+#if wxUSE_MENUS || wxUSE_MENUS_NATIVE
     extern wxMenu *wxCurrentPopupMenu;
-#endif // wxUSE_MENUS_NATIVE
+#endif // wxUSE_MENUS || wxUSE_MENUS_NATIVE
 
 // ----------------------------------------------------------------------------
 // event tables
@@ -73,78 +79,6 @@ BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
     EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
 END_EVENT_TABLE()
 
-#if wxUSE_EXTENDED_RTTI
-WX_DEFINE_FLAGS( wxFrameStyle )
-
-wxBEGIN_FLAGS( wxFrameStyle )
-    // 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)
-
-    // frame styles
-    wxFLAGS_MEMBER(wxSTAY_ON_TOP)
-    wxFLAGS_MEMBER(wxCAPTION)
-#if WXWIN_COMPATIBILITY_2_6
-    wxFLAGS_MEMBER(wxTHICK_FRAME)
-#endif // WXWIN_COMPATIBILITY_2_6
-    wxFLAGS_MEMBER(wxSYSTEM_MENU)
-    wxFLAGS_MEMBER(wxRESIZE_BORDER)
-#if WXWIN_COMPATIBILITY_2_6
-    wxFLAGS_MEMBER(wxRESIZE_BOX)
-#endif // WXWIN_COMPATIBILITY_2_6
-    wxFLAGS_MEMBER(wxCLOSE_BOX)
-    wxFLAGS_MEMBER(wxMAXIMIZE_BOX)
-    wxFLAGS_MEMBER(wxMINIMIZE_BOX)
-
-    wxFLAGS_MEMBER(wxFRAME_TOOL_WINDOW)
-    wxFLAGS_MEMBER(wxFRAME_FLOAT_ON_PARENT)
-
-    wxFLAGS_MEMBER(wxFRAME_SHAPED)
-
-wxEND_FLAGS( wxFrameStyle )
-
-IMPLEMENT_DYNAMIC_CLASS_XTI(wxFrame, wxTopLevelWindow,"wx/frame.h")
-
-wxBEGIN_PROPERTIES_TABLE(wxFrame)
-    wxEVENT_PROPERTY( Menu , wxEVT_COMMAND_MENU_SELECTED , wxCommandEvent)
-
-    wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY_FLAGS( WindowStyle , wxFrameStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
-    wxPROPERTY( MenuBar , wxMenuBar * , SetMenuBar , GetMenuBar , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-wxEND_PROPERTIES_TABLE()
-
-wxBEGIN_HANDLERS_TABLE(wxFrame)
-wxEND_HANDLERS_TABLE()
-
-wxCONSTRUCTOR_6( wxFrame , wxWindow* , Parent , wxWindowID , Id , wxString , Title , wxPoint , Position , wxSize , Size , long , WindowStyle)
-
-#else
-IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
-#endif
-
 // ============================================================================
 // implementation
 // ============================================================================
@@ -209,7 +143,8 @@ bool wxFrame::Create(wxWindow *parent,
 
 wxFrame::~wxFrame()
 {
-    m_isBeingDeleted = true;
+    SendDestroyEvent();
+
     DeleteAllBars();
 }
 
@@ -294,7 +229,7 @@ void wxFrame::DoGetClientSize(int *x, int *y) const
         wxStatusBar *statbar = GetStatusBar();
         if ( statbar && statbar->IsShown() )
         {
-            *y -= statbar->GetClientSize().y;
+            *y -= statbar->GetSize().y;
         }
     }
 #endif // wxUSE_STATUSBAR
@@ -304,21 +239,25 @@ void wxFrame::DoGetClientSize(int *x, int *y) const
 // wxFrame: various geometry-related functions
 // ----------------------------------------------------------------------------
 
-void wxFrame::Raise()
-{
-    ::SetForegroundWindow(GetHwnd());
-}
-
 // generate an artificial resize event
-void wxFrame::SendSizeEvent()
+void wxFrame::SendSizeEvent(int flags)
 {
     if ( !m_iconized )
     {
         RECT r = wxGetWindowRect(GetHwnd());
 
-        (void)::PostMessage(GetHwnd(), WM_SIZE,
-                            IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
-                            MAKELPARAM(r.right - r.left, r.bottom - r.top));
+        if ( flags & wxSEND_EVENT_POST )
+        {
+            ::PostMessage(GetHwnd(), WM_SIZE,
+                          IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
+                          MAKELPARAM(r.right - r.left, r.bottom - r.top));
+        }
+        else // send it
+        {
+            ::SendMessage(GetHwnd(), WM_SIZE,
+                          IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
+                          MAKELPARAM(r.right - r.left, r.bottom - r.top));
+        }
     }
 }
 
@@ -425,19 +364,23 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar)
         SetToolBar(toolBar);
         menubar->SetToolBar(toolBar);
     }
-    // Now adjust size for menu bar
-    int menuHeight = 26;
 
-    //When the main window is created using CW_USEDEFAULT the height of the
-    // is created is not taken into account). So we resize the window after
-    // if a menubar is present
+    // When the main window is created using CW_USEDEFAULT the height of the
+    // menubar is not taken into account, so we resize it afterwards if a
+    // menubar is present
+    HWND hwndMenuBar = SHFindMenuBar(GetHwnd());
+    if ( hwndMenuBar )
     {
+        RECT mbRect;
+        ::GetWindowRect(hwndMenuBar, &mbRect);
+        const int menuHeight = mbRect.bottom - mbRect.top;
+
         RECT rc;
-        ::GetWindowRect((HWND) GetHWND(), &rc);
+        ::GetWindowRect(GetHwnd(), &rc);
         // adjust for menu / titlebar height
         rc.bottom -= (2*menuHeight-1);
 
-        ::MoveWindow((HWND) GetHWND(), rc.left, rc.top, rc.right, rc.bottom, FALSE);
+        ::MoveWindow(GetHwnd(), rc.left, rc.top, rc.right, rc.bottom, FALSE);
     }
 #endif
 
@@ -463,7 +406,7 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar)
 
             if ( !m_hMenu )
             {
-                wxFAIL_MSG( _T("failed to create menu bar") );
+                wxFAIL_MSG( wxT("failed to create menu bar") );
                 return;
             }
         }
@@ -486,18 +429,29 @@ void wxFrame::InternalSetMenuBar()
 
 #endif // wxUSE_MENUS_NATIVE
 
+#if wxUSE_MENUS
+wxMenu* wxFrame::MSWFindMenuFromHMENU(WXHMENU hMenu)
+{
+    return GetMenuBar() ? GetMenuBar()->MSWGetMenu(hMenu) : NULL;
+}
+#endif // wxUSE_MENUS
+
 // Responds to colour changes, and passes event on to children.
 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
-    SetOwnBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
-    Refresh();
+    // Don't override the colour explicitly set by the user, if any.
+    if ( !UseBgCol() )
+    {
+        SetOwnBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
+        Refresh();
+    }
 
 #if wxUSE_STATUSBAR
     if ( m_frameStatusBar )
     {
         wxSysColourChangedEvent event2;
         event2.SetEventObject( m_frameStatusBar );
-        m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
+        m_frameStatusBar->HandleWindowEvent(event2);
     }
 #endif // wxUSE_STATUSBAR
 
@@ -566,24 +520,9 @@ bool wxFrame::ShowFullScreen(bool show, long style)
 #if wxUSE_MENUS
         if (m_fsStyle & wxFULLSCREEN_NOMENUBAR)
         {
-            WXHMENU menu = m_hMenu;
-
-#if wxUSE_MDI_ARCHITECTURE
-            wxMDIParentFrame *frame = wxDynamicCast(this, wxMDIParentFrame);
-            if (frame)
-            {
-                wxMDIChildFrame *child = frame->GetActiveChild();
-                if (child)
-                {
-                    menu = child->GetWinMenu();
-                }
-            }
-#endif // wxUSE_MDI_ARCHITECTURE
-
-            if (menu)
-            {
-                ::SetMenu(GetHwnd(), (HMENU)menu);
-            }
+            const WXHMENU hmenu = MSWGetActiveMenu();
+            if ( hmenu )
+                ::SetMenu(GetHwnd(), (HMENU)hmenu);
         }
 #endif // wxUSE_MENUS
 
@@ -649,7 +588,7 @@ void wxFrame::PositionToolBar()
         toolbar->GetPosition( &tx, &ty );
         toolbar->GetSize( &tw, &th );
 
-        int x = 0, y = 0;
+        int x, y;
         if ( toolbar->HasFlag(wxTB_BOTTOM) )
         {
             x = 0;
@@ -698,49 +637,23 @@ void wxFrame::PositionToolBar()
                 tx = 0;
         }
 
-        int desiredW = tw;
-        int desiredH = th;
+        int desiredW,
+            desiredH;
 
         if ( toolbar->IsVertical() )
         {
+            desiredW = tw;
             desiredH = height;
         }
         else
         {
             desiredW = width;
+            desiredH = th;
         }
 
-        // use the 'real' MSW position here, don't offset relativly to the
+        // use the 'real' MSW position here, don't offset relatively to the
         // client area origin
-
-        // Optimise such that we don't have to always resize the toolbar
-        // when the frame changes, otherwise we'll get a lot of flicker.
-        bool heightChanging wxDUMMY_INITIALIZE(true);
-        bool widthChanging wxDUMMY_INITIALIZE(true);
-
-        if ( toolbar->IsVertical() )
-        {
-            // It's OK if the current height is greater than what can be shown.
-            heightChanging = (desiredH > th) ;
-            widthChanging = (desiredW != tw) ;
-
-            // The next time around, we may not have to set the size
-            if (heightChanging)
-                desiredH = desiredH + 200;
-        }
-        else
-        {
-            // It's OK if the current width is greater than what can be shown.
-            widthChanging = (desiredW > tw) ;
-            heightChanging = (desiredH != th) ;
-
-            // The next time around, we may not have to set the size
-            if (widthChanging)
-                desiredW = desiredW + 200;
-        }
-
-        if (tx != 0 || ty != 0 || widthChanging || heightChanging)
-            toolbar->SetSize(x, y, desiredW, desiredH, wxSIZE_NO_ADJUSTMENTS);
+        toolbar->SetSize(x, y, desiredW, desiredH, wxSIZE_NO_ADJUSTMENTS);
 
     }
 #endif // !WINCE_WITH_COMMANDBAR
@@ -819,13 +732,10 @@ bool wxFrame::MSWDoTranslateMessage(wxFrame *frame, WXMSG *pMsg)
         return true;
 
 #if wxUSE_MENUS && wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
-    // try the menu bar accels
+    // try the menu bar accelerators
     wxMenuBar *menuBar = GetMenuBar();
-    if ( menuBar )
-    {
-        const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
-        return acceleratorTable.Translate(frame, pMsg);
-    }
+    if ( menuBar && menuBar->GetAcceleratorTable()->Translate(frame, pMsg) )
+        return true;
 #endif // wxUSE_MENUS && wxUSE_ACCEL
 
     return false;
@@ -835,58 +745,6 @@ bool wxFrame::MSWDoTranslateMessage(wxFrame *frame, WXMSG *pMsg)
 // our private (non virtual) message handlers
 // ---------------------------------------------------------------------------
 
-bool wxFrame::HandlePaint()
-{
-    RECT rect;
-    if ( ::GetUpdateRect(GetHwnd(), &rect, FALSE) )
-    {
-#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
-        if ( m_iconized )
-        {
-            const wxIcon& icon = GetIcon();
-            HICON hIcon = icon.Ok() ? GetHiconOf(icon)
-                                    : (HICON)GetDefaultIcon();
-
-            // Hold a pointer to the dc so long as the OnPaint() message
-            // is being processed
-            PAINTSTRUCT ps;
-            HDC hdc = ::BeginPaint(GetHwnd(), &ps);
-
-            // Erase background before painting or we get white background
-            MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L);
-
-            if ( hIcon )
-            {
-                RECT rect;
-                ::GetClientRect(GetHwnd(), &rect);
-
-                // FIXME: why hardcoded?
-                static const int icon_width = 32;
-                static const int icon_height = 32;
-
-                int icon_x = (int)((rect.right - icon_width)/2);
-                int icon_y = (int)((rect.bottom - icon_height)/2);
-
-                ::DrawIcon(hdc, icon_x, icon_y, hIcon);
-            }
-
-            ::EndPaint(GetHwnd(), &ps);
-
-            return true;
-        }
-        else
- #endif
-        {
-            return wxWindow::HandlePaint();
-        }
-    }
-    else
-    {
-        // nothing to paint - processed
-        return true;
-    }
-}
-
 bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id)
 {
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
@@ -946,116 +804,33 @@ bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id)
     return false;
 }
 
-bool wxFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control)
+bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
 {
-    // sign extend to int from short before comparing with the other int ids
-    int id = (signed short)id_;
-
-    if ( control )
-    {
-        // In case it's e.g. a toolbar.
-        wxWindow *win = wxFindWinFromHandle(control);
-        if ( win )
-            return win->MSWCommand(cmd, id);
-    }
-
-    // handle here commands from menus and accelerators
-    if ( cmd == 0 || cmd == 1 )
-    {
-#if wxUSE_MENUS_NATIVE
-        if ( wxCurrentPopupMenu )
-        {
-            wxMenu *popupMenu = wxCurrentPopupMenu;
-            wxCurrentPopupMenu = NULL;
-
-            return popupMenu->MSWCommand(cmd, id);
-        }
-#endif // wxUSE_MENUS_NATIVE
-
-#if defined(__SMARTPHONE__) && defined(__WXWINCE__)
-        // handle here commands from Smartphone menu bar
-        if ( wxTopLevelWindow::HandleCommand(id, cmd, control ) )
-        {
-            return true;
-        }
-#endif // __SMARTPHONE__ && __WXWINCE__
-
-        if ( ProcessCommand(id) )
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
-
 #if wxUSE_MENUS
 
-bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
-{
-    int item;
-    if ( flags == 0xFFFF && hMenu == 0 )
-    {
-        // menu was removed from screen
-        item = -1;
-    }
-#ifndef __WXMICROWIN__
-    else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) )
-    {
-        item = nItem;
-    }
+#if defined(WINCE_WITHOUT_COMMANDBAR)
+    if (GetToolBar() && GetToolBar()->FindById(id))
+        return GetToolBar()->MSWCommand(cmd, id);
 #endif
-    else
-    {
-        // don't give hints for separators (doesn't make sense) nor for the
-        // items opening popup menus (they don't have them anyhow) but do clear
-        // the status line - otherwise, we would be left with the help message
-        // for the previous item which doesn't apply any more
-        DoGiveHelp(wxEmptyString, true);
 
-        return false;
-    }
-
-    wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
-    event.SetEventObject(this);
-
-    return GetEventHandler()->ProcessEvent(event);
-}
-
-bool wxFrame::HandleMenuLoop(const wxEventType& evtType, WXWORD isPopup)
-{
-    // we don't have the menu id here, so we use the id to specify if the event
-    // was from a popup menu or a normal one
-    wxMenuEvent event(evtType, isPopup ? -1 : 0);
-    event.SetEventObject(this);
-
-    return GetEventHandler()->ProcessEvent(event);
-}
-
-bool wxFrame::HandleInitMenuPopup(WXHMENU hMenu)
-{
-    wxMenu* menu = NULL;
-    if (GetMenuBar())
+    // we only need to handle the menu and accelerator commands from the items
+    // of our menu bar, base wxWindow class already handles the rest
+    if ( !control && (cmd == 0 /* menu */ || cmd == 1 /* accel */) )
     {
-        int nCount = GetMenuBar()->GetMenuCount();
-        for (int n = 0; n < nCount; n++)
+#if wxUSE_MENUS_NATIVE
+        if ( !wxCurrentPopupMenu )
+#endif // wxUSE_MENUS_NATIVE
         {
-            if (GetMenuBar()->GetMenu(n)->GetHMenu() == hMenu)
-            {
-                menu = GetMenuBar()->GetMenu(n);
-                break;
-            }
+            wxMenuItem * const mitem = FindItemInMenuBar((signed short)id);
+            if ( mitem )
+                return ProcessCommand(mitem);
         }
     }
+#endif // wxUSE_MENUS
 
-    wxMenuEvent event(wxEVT_MENU_OPEN, 0, menu);
-    event.SetEventObject(this);
-
-    return GetEventHandler()->ProcessEvent(event);
+    return wxFrameBase::HandleCommand(id, cmd, control);;
 }
 
-#endif // wxUSE_MENUS
-
 // ---------------------------------------------------------------------------
 // the window proc for wxFrame
 // ---------------------------------------------------------------------------
@@ -1084,41 +859,24 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara
                 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
                               &id, &hwnd, &cmd);
 
-                processed = HandleCommand(id, cmd, (WXHWND)hwnd);
-            }
-            break;
+                HandleCommand(id, cmd, (WXHWND)hwnd);
 
-        case WM_PAINT:
-            processed = HandlePaint();
-            break;
-
-#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
-#if wxUSE_MENUS
-        case WM_INITMENUPOPUP:
-            processed = HandleInitMenuPopup((WXHMENU) wParam);
-            break;
-
-        case WM_MENUSELECT:
-            {
-                WXWORD item, flags;
-                WXHMENU hmenu;
-                UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
-
-                processed = HandleMenuSelect(item, flags, hmenu);
+                // don't pass WM_COMMAND to the base class whether we processed
+                // it or not because we did generate an event for it (our
+                // HandleCommand() calls the base class version) and we must
+                // not do it again or the handlers which skip the event would
+                // be called twice
+                processed = true;
             }
             break;
 
-        case WM_EXITMENULOOP:
-            processed = HandleMenuLoop(wxEVT_MENU_CLOSE, (WXWORD)wParam);
-            break;
-#endif // wxUSE_MENUS
-
+#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_QUERYDRAGICON:
             {
                 const wxIcon& icon = GetIcon();
-                HICON hIcon = icon.Ok() ? GetHiconOf(icon)
+                HICON hIcon = icon.IsOk() ? GetHiconOf(icon)
                                         : (HICON)GetDefaultIcon();
-                rc = (long)hIcon;
+                rc = (WXLRESULT)hIcon;
                 processed = rc != 0;
             }
             break;