]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/frame.cpp
Quick VA fix
[wxWidgets.git] / src / os2 / frame.cpp
index 14a35cba8f790e03b8dc4c3e76b051eb577041e4..18269f66d1fa8a7817f9a1758de51a3dda7775ea 100644 (file)
@@ -125,12 +125,6 @@ bool wxFrame::Create(
 
     m_bIconized = FALSE;
 
-    //
-    // We pass NULL as parent to MSWCreate because frames with parents behave
-    // very strangely under Win95 shell.
-    // Alteration by JACS: keep normal Windows behaviour (float on top of parent)
-    // with this ulStyle.
-    //
     if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
         pParent = NULL;
 
@@ -345,31 +339,44 @@ void wxFrame::DoGetPosition(
 // ----------------------------------------------------------------------------
 
 void wxFrame::DoShowWindow(
-  int                               nShowCmd
+  int                               bShowCmd
 )
 {
-    ::WinShowWindow(GetHwnd(), nShowCmd);
-    m_bIconized = nShowCmd == SWP_MINIMIZE;
+    HWND                            hClient = NULLHANDLE;
+    SWP                             vSwp;
+
+    //
+    // Reset the window position
+    //
+    hClient = WinWindowFromID(GetHwnd(), FID_CLIENT);
+    WinQueryWindowPos(GetHwnd(), &vSwp);
+    WinSetWindowPos( GetHwnd()
+                    ,HWND_TOP
+                    ,vSwp.x
+                    ,vSwp.y
+                    ,vSwp.cx
+                    ,vSwp.cy
+                    ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
+                   );
+    ::WinShowWindow(GetHwnd(), (BOOL)bShowCmd);
+    ::WinShowWindow(hClient, (BOOL)bShowCmd);
 } // end of wxFrame::DoShowWindow
 
 bool wxFrame::Show(
   bool                              bShow
 )
 {
-    DoShowWindow(bShow ? SWP_SHOW : SWP_HIDE);
+    SWP                             vSwp;
+
+    DoShowWindow((int)bShow);
 
     if (bShow)
     {
         wxActivateEvent             vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
 
-        ::WinSetWindowPos( (HWND) GetHWND()
-                          ,HWND_TOP
-                          ,0
-                          ,0
-                          ,0
-                          ,0
-                          ,SWP_ZORDER
-                         );
+        ::WinQueryWindowPos(GetHwnd(), &vSwp);
+        m_bIconized = vSwp.fl & SWP_MINIMIZE;
+        ::WinEnableWindow(GetHwnd(), TRUE);
         vEvent.SetEventObject(this);
         GetEventHandler()->ProcessEvent(vEvent);
     }
@@ -382,15 +389,18 @@ bool wxFrame::Show(
         {
             HWND                    hWndParent = GetHwndOf(GetParent());
 
+            ::WinQueryWindowPos(hWndParent, &vSwp);
+            m_bIconized = vSwp.fl & SWP_MINIMIZE;
             if (hWndParent)
                 ::WinSetWindowPos( hWndParent
                                   ,HWND_TOP
-                                  ,0
-                                  ,0
-                                  ,0
-                                  ,0
-                                  ,SWP_ZORDER
+                                  ,vSwp.x
+                                  ,vSwp.y
+                                  ,vSwp.cx
+                                  ,vSwp.cy
+                                  ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
                                  );
+            ::WinEnableWindow(hWndParent, TRUE);
         }
     }
     return TRUE;
@@ -444,13 +454,18 @@ void wxFrame::SetIcon(
 {
     wxFrameBase::SetIcon(rIcon);
 
-    if (m_icon.Ok())
+    if ((m_icon.GetHICON()) != NULLHANDLE)
     {
-        WinSendMsg( GetHwnd()
-                   ,WM_SETICON
-                   ,(MPARAM)((HICON)m_icon.GetHICON())
-                   ,NULL
-                  );
+        ::WinSendMsg( GetHwnd()
+                     ,WM_SETICON
+                     ,(MPARAM)((HPOINTER)m_icon.GetHICON())
+                     ,NULL
+                    );
+        ::WinSendMsg( GetHwnd()
+                     ,WM_UPDATEFRAME
+                     ,(MPARAM)FCF_ICON
+                     ,(MPARAM)0
+                    );
     }
 } // end of wxFrame::SetIcon
 
@@ -521,44 +536,93 @@ void wxFrame::SetMenuBar(
   wxMenuBar*                        pMenuBar
 )
 {
+    ERRORID                         vError;
+    wxString                        sError;
+    HWND                            hClient = NULLHANDLE;
+    HWND                            hFrame = NULLHANDLE;
+    HWND                            hTitlebar = NULLHANDLE;
+    HWND                            hHScroll = NULLHANDLE;
+    HWND                            hVScroll = NULLHANDLE;
+    HWND                            hMenuBar = NULLHANDLE;
+    SWP                             vSwp;
+    SWP                             vSwpTitlebar;
+    SWP                             vSwpVScroll;
+    SWP                             vSwpHScroll;
+    SWP                             vSwpMenu;
+
     if (!pMenuBar)
     {
         DetachMenuBar();
         return;
     }
 
-    wxCHECK_RET(!pMenuBar->GetFrame(), wxT("this menubar is already attached"));
-
-    if (m_frameMenuBar)
-        delete m_frameMenuBar;
+    m_frameMenuBar = NULL;
 
-    m_hMenu = pMenuBar->Create();
-    m_ulMenubarId = pMenuBar->GetMenubarId();
-    if (m_ulMenubarId != FID_MENU)
+    // Can set a menubar several times.
+    // TODO: how to prevent a memory leak if you have a currently-unattached
+    // menubar? wxWindows assumes that the frame will delete the menu (otherwise
+    // there are problems for MDI).
+    if (pMenuBar->GetHMenu())
     {
-        ::WinSetWindowUShort( m_hMenu
-                             ,QWS_ID
-                             ,(unsigned short)m_ulMenubarId
-                            );
+        m_hMenu = pMenuBar->GetHMenu();
     }
+    else
+    {
+        pMenuBar->Detach();
 
-    if (!m_hMenu)
-        return;
+        m_hMenu = pMenuBar->Create();
 
+        if (!m_hMenu)
+            return;
+    }
+
+    //
+    // Set the parent and owner of the menubar to be the frame
+    //
+    if (!::WinSetParent(m_hMenu, GetHwnd(), FALSE))
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+        wxLogError("Error setting parent for submenu. Error: %s\n", sError);
+    }
+
+    if (!::WinSetOwner(m_hMenu, GetHwnd()))
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+        wxLogError("Error setting parent for submenu. Error: %s\n", sError);
+    }
     InternalSetMenuBar();
 
     m_frameMenuBar = pMenuBar;
     pMenuBar->Attach(this);
+
+    //
+    // Now resize the client to fit the new frame
+    //
+    WinQueryWindowPos(GetHwnd(), &vSwp);
+    hClient = WinWindowFromID(GetHwnd(), FID_CLIENT);
+    hTitlebar = WinWindowFromID(GetHwnd(), FID_TITLEBAR);
+    WinQueryWindowPos(hTitlebar, &vSwpTitlebar);
+    hHScroll = WinWindowFromID(GetHwnd(), FID_HORZSCROLL);
+    WinQueryWindowPos(hHScroll, &vSwpHScroll);
+    hVScroll = WinWindowFromID(GetHwnd(), FID_VERTSCROLL);
+    WinQueryWindowPos(hVScroll, &vSwpVScroll);
+    hMenuBar = WinWindowFromID(GetHwnd(), FID_MENU);
+    WinQueryWindowPos(hMenuBar, &vSwpMenu);
+    WinSetWindowPos( hClient
+                    ,HWND_TOP
+                    ,SV_CXSIZEBORDER/2
+                    ,(SV_CYSIZEBORDER/2) + vSwpHScroll.cy/2
+                    ,vSwp.cx - ((SV_CXSIZEBORDER + 1) + vSwpVScroll.cx)
+                    ,vSwp.cy - ((SV_CYSIZEBORDER + 1) + vSwpTitlebar.cy + vSwpMenu.cy + vSwpHScroll.cy/2)
+                    ,SWP_SIZE | SWP_MOVE
+                   );
 } // end of wxFrame::SetMenuBar
 
 void wxFrame::InternalSetMenuBar()
 {
-
-    ::WinPostMsg( GetHwnd()
-                 ,WM_UPDATEFRAME
-                 ,(MPARAM)FCF_MENU
-                 ,NULL
-                );
+    WinSendMsg((HWND)GetHwnd(), WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
 } // end of wxFrame::InternalSetMenuBar
 
 //
@@ -585,6 +649,130 @@ void wxFrame::OnSysColourChanged(
     wxWindow::OnSysColourChanged(rEvent);
 } // end of wxFrame::OnSysColourChanged
 
+// Pass TRUE to show full screen, FALSE to restore.
+bool wxFrame::ShowFullScreen(
+  bool                              bShow
+, long                              lStyle
+)
+{
+    /*
+    // TODO
+    if (show)
+    {
+        if (IsFullScreen())
+            return FALSE;
+
+        m_fsIsShowing = TRUE;
+        m_fsStyle = style;
+
+            wxToolBar *theToolBar = GetToolBar();
+            wxStatusBar *theStatusBar = GetStatusBar();
+
+        int dummyWidth;
+
+        if (theToolBar)
+            theToolBar->GetSize(&dummyWidth, &m_fsToolBarHeight);
+        if (theStatusBar)
+            theStatusBar->GetSize(&dummyWidth, &m_fsStatusBarHeight);
+
+        // zap the toolbar, menubar, and statusbar
+
+        if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
+        {
+            theToolBar->SetSize(-1,0);
+            theToolBar->Show(FALSE);
+        }
+
+        if (style & wxFULLSCREEN_NOMENUBAR)
+            SetMenu((HWND)GetHWND(), (HMENU) NULL);
+
+        // Save the number of fields in the statusbar
+        if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
+        {
+            m_fsStatusBarFields = theStatusBar->GetFieldsCount();
+            SetStatusBar((wxStatusBar*) NULL);
+                delete theStatusBar;
+        }
+        else
+            m_fsStatusBarFields = 0;
+
+        // zap the frame borders
+
+        // save the 'normal' window style
+        m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
+
+           // save the old position, width & height, maximize state
+        m_fsOldSize = GetRect();
+            m_fsIsMaximized = IsMaximized();
+
+           // decide which window style flags to turn off
+        LONG newStyle = m_fsOldWindowStyle;
+        LONG offFlags = 0;
+
+        if (style & wxFULLSCREEN_NOBORDER)
+            offFlags |= WS_BORDER;
+        if (style & wxFULLSCREEN_NOCAPTION)
+            offFlags |= (WS_CAPTION | WS_SYSMENU);
+
+        newStyle &= (~offFlags);
+
+        // change our window style to be compatible with full-screen mode
+        SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
+
+        // resize to the size of the desktop
+        int width, height;
+
+        RECT rect;
+        ::GetWindowRect(GetDesktopWindow(), &rect);
+        width = rect.right - rect.left;
+        height = rect.bottom - rect.top;
+
+        SetSize(width, height);
+
+        // now flush the window style cache and actually go full-screen
+        SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
+
+        wxSizeEvent event(wxSize(width, height), GetId());
+        GetEventHandler()->ProcessEvent(event);
+
+        return TRUE;
+    }
+    else
+    {
+        if (!IsFullScreen())
+            return FALSE;
+
+        m_fsIsShowing = FALSE;
+
+        wxToolBar *theToolBar = GetToolBar();
+
+        // restore the toolbar, menubar, and statusbar
+        if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
+        {
+            theToolBar->SetSize(-1, m_fsToolBarHeight);
+            theToolBar->Show(TRUE);
+        }
+
+        if ((m_fsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_fsStatusBarFields > 0))
+        {
+            CreateStatusBar(m_fsStatusBarFields);
+            PositionStatusBar();
+        }
+
+        if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
+            SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
+
+        Maximize(m_fsIsMaximized);
+        SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
+        SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
+            m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
+
+        return TRUE;
+    }
+*/
+    return TRUE;
+} // end of wxFrame::ShowFullScreen
+
 //
 // Frame window
 //
@@ -601,90 +789,177 @@ bool wxFrame::OS2Create(
 , long                              ulStyle
 )
 {
-    ULONG                           ulPmFlags = 0;
-    ULONG                           ulExtraFlags = 0;
-    ULONG                           ulTempFlags = FCF_TITLEBAR |
-                                                  FCF_SYSMENU |
-                                                  FCF_MINBUTTON |
-                                                  FCF_MAXBUTTON |
-                                                  FCF_SIZEBORDER |
-                                                  FCF_ICON |
-                                                  FCF_MENU |
-                                                  FCF_ACCELTABLE |
-                                                  FCF_SHELLPOSITION |
-                                                  FCF_TASKLIST;
+    ULONG                           ulCreateFlags = 0L;
+    ULONG                           ulStyleFlags = 0L;
+    ULONG                           ulExtraFlags = 0L;
+    FRAMECDATA                      vFrameCtlData;
+    HWND                            hParent = NULLHANDLE;
+    HWND                            hClient = NULLHANDLE;
+    HWND                            hFrame = NULLHANDLE;
+    HWND                            hTitlebar = NULLHANDLE;
+    HWND                            hHScroll = NULLHANDLE;
+    HWND                            hVScroll = NULLHANDLE;
+    SWP                             vSwp;
+    SWP                             vSwpTitlebar;
+    SWP                             vSwpVScroll;
+    SWP                             vSwpHScroll;
 
     m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
 
-    if ((ulStyle & wxCAPTION) == wxCAPTION)
-        ulPmFlags = FCF_TASKLIST;
+    if (pParent)
+        hParent = GetWinHwnd(pParent);
+    else
+        hParent = HWND_DESKTOP;
+
+    if (ulStyle == wxDEFAULT_FRAME_STYLE)
+        ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
+                        FCF_MINMAX | FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_TASKLIST;
     else
-        ulPmFlags = FCF_NOMOVEWITHOWNER;
-
-    if (ulStyle & wxMINIMIZE_BOX)
-        ulPmFlags |= FCF_MINBUTTON;
-    if (ulStyle & wxMAXIMIZE_BOX)
-        ulPmFlags |= FCF_MAXBUTTON;
-    if (ulStyle & wxTHICK_FRAME)
-        ulPmFlags |= FCF_DLGBORDER;
-    if (ulStyle & wxSYSTEM_MENU)
-        ulPmFlags |= FCF_SYSMENU;
+    {
+        if ((ulStyle & wxCAPTION) == wxCAPTION)
+            ulCreateFlags = FCF_TASKLIST;
+        else
+            ulCreateFlags = FCF_NOMOVEWITHOWNER;
+
+        if (ulStyle & wxMINIMIZE_BOX)
+            ulCreateFlags |= FCF_MINBUTTON;
+        if (ulStyle & wxMAXIMIZE_BOX)
+            ulCreateFlags |= FCF_MAXBUTTON;
+        if (ulStyle & wxTHICK_FRAME)
+            ulCreateFlags |= FCF_DLGBORDER;
+        if (ulStyle & wxSYSTEM_MENU)
+            ulCreateFlags |= FCF_SYSMENU;
+        if (ulStyle & wxCAPTION)
+            ulCreateFlags |= FCF_TASKLIST;
+        if (ulStyle & wxCLIP_CHILDREN)
+        {
+            // Invalid for frame windows under PM
+        }
+
+        if (ulStyle & wxTINY_CAPTION_VERT)
+            ulCreateFlags |= FCF_TASKLIST;
+        if (ulStyle & wxTINY_CAPTION_HORIZ)
+            ulCreateFlags |= FCF_TASKLIST;
+
+        if ((ulStyle & wxTHICK_FRAME) == 0)
+            ulCreateFlags |= FCF_BORDER;
+        if (ulStyle & wxFRAME_TOOL_WINDOW)
+            ulExtraFlags = kFrameToolWindow;
+
+        if (ulStyle & wxSTAY_ON_TOP)
+            ulCreateFlags |= FCF_SYSMODAL;
+    }
     if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
-        ulPmFlags |= WS_MINIMIZED;
+        ulStyleFlags |= WS_MINIMIZED;
     if (ulStyle & wxMAXIMIZE)
-        ulPmFlags |= WS_MAXIMIZED;
-    if (ulStyle & wxCAPTION)
-        ulPmFlags |= FCF_TASKLIST;
-    if (ulStyle & wxCLIP_CHILDREN)
+        ulStyleFlags |= WS_MAXIMIZED;
+
+    //
+    // Clear the visible flag, we always call show
+    //
+    ulStyleFlags &= (unsigned long)~WS_VISIBLE;
+    m_bIconized = FALSE;
+
+    //
+    // Set the frame control block
+    //
+    vFrameCtlData.cb            = sizeof(vFrameCtlData);
+    vFrameCtlData.flCreateFlags = ulCreateFlags;
+    vFrameCtlData.hmodResources = 0L;
+    vFrameCtlData.idResources   = 0;
+
+    //
+    // Create the frame window
+    //
+    if (!wxWindow::OS2Create( hParent
+                             ,WC_FRAME
+                             ,zTitle
+                             ,ulStyleFlags
+                             ,(long)nX
+                             ,(long)nY
+                             ,(long)nWidth
+                             ,(long)nHeight
+                             ,NULLHANDLE
+                             ,HWND_TOP
+                             ,(long)nId
+                             ,(void*)&vFrameCtlData
+                             ,NULL
+                            ))
     {
-        // Invalid for frame windows under PM
+        return FALSE;
     }
 
+    hFrame = GetHwnd();
+
     //
-    // Keep this in wxFrame because it saves recoding this function
-    // in wxTinyFrame
+    // Since under PM the controling window proc is associated with the client window handle
+    // not the frame's we have to perform the hook here in order to associated the client handle,
+    // not the frame's with the window object !
     //
-#if wxUSE_ITSY_BITSY
-    if (ulStyle & wxTINY_CAPTION_VERT)
-        ulExtraFlags |= kVertCaption;
-    if (ulStyle & wxTINY_CAPTION_HORIZ)
-        ulExtraFlags |= kHorzCaption;
-#else
-    if (ulStyle & wxTINY_CAPTION_VERT)
-        ulPmFlags |= FCF_TASKLIST;
-    if (ulStyle & wxTINY_CAPTION_HORIZ)
-        ulPmFlags |= FCF_TASKLIST;
-#endif
-    if ((ulStyle & wxTHICK_FRAME) == 0)
-        ulPmFlags |= FCF_BORDER;
-    if (ulStyle & wxFRAME_TOOL_WINDOW)
-        ulExtraFlags = kFrameToolWindow;
-
-    if (ulStyle & wxSTAY_ON_TOP)
-        ulPmFlags |= FCF_SYSMODAL;
 
-    if (ulPmFlags & ulTempFlags)
-        ulPmFlags = FCF_STANDARD;
+    wxWndHook = this;
     //
-    // Clear the visible flag, we always call show
+    // Create the client window.  We must call the API from here rather than
+    // the static base class create because we need a separate handle
     //
-    ulPmFlags &= (unsigned long)~WS_VISIBLE;
-    m_bIconized = FALSE;
-    if ( !wxWindow::OS2Create( nId
-                              ,pParent
-                              ,zWclass
-                              ,pWxWin
-                              ,zTitle
-                              ,nX
-                              ,nY
-                              ,nWidth
-                              ,nHeight
-                              ,ulPmFlags
-                              ,NULL
-                              ,ulExtraFlags))
+    if ((hClient = ::WinCreateWindow( hFrame   // Frame is parent
+                                     ,wxFrameClassName
+                                     ,NULL        // Window title
+                                     ,0           // No styles
+                                     ,0, 0, 0, 0  // Window position
+                                     ,NULLHANDLE  // Owner
+                                     ,HWND_TOP    // Sibling
+                                     ,FID_CLIENT  // standard client ID
+                                     ,NULL        // Creation data
+                                     ,NULL        // Window Pres Params
+                                     )) == 0L)
     {
         return FALSE;
     }
+
+    wxWndHook = NULL;
+    //
+    // Send anything to initialize the frame
+    //
+    ::WinSendMsg( hFrame
+                 ,WM_UPDATEFRAME
+                 ,(MPARAM)FCF_TASKLIST
+                 ,(MPARAM)0
+                );
+
+    //
+    // Now size everything.  If adding a menu the client will need to be resized.
+    //
+    if (!::WinSetWindowPos( hFrame
+                           ,HWND_TOP
+                           ,nX
+                           ,nY
+                           ,nWidth
+                           ,nHeight
+                           ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
+                          ))
+        return FALSE;
+
+    WinQueryWindowPos(GetHwnd(), &vSwp);
+    hClient = WinWindowFromID(GetHwnd(), FID_CLIENT);
+    hTitlebar = WinWindowFromID(GetHwnd(), FID_TITLEBAR);
+    WinQueryWindowPos(hTitlebar, &vSwpTitlebar);
+    hHScroll = WinWindowFromID(GetHwnd(), FID_HORZSCROLL);
+    WinQueryWindowPos(hHScroll, &vSwpHScroll);
+    hVScroll = WinWindowFromID(GetHwnd(), FID_VERTSCROLL);
+    WinQueryWindowPos(hVScroll, &vSwpVScroll);
+    WinSetWindowPos( hClient
+                    ,HWND_TOP
+                    ,SV_CXSIZEBORDER/2
+                    ,(SV_CYSIZEBORDER/2) + vSwpHScroll.cy/2
+                    ,vSwp.cx - ((SV_CXSIZEBORDER + 1) + vSwpVScroll.cx)
+                    ,vSwp.cy - ((SV_CYSIZEBORDER + 1) + vSwpTitlebar.cy + vSwpHScroll.cy/2)
+                    ,SWP_SIZE | SWP_MOVE
+                   );
+
+    //
+    // Set the client window's background, otherwise it is transparent!
+    //
     return TRUE;
 } // end of wxFrame::OS2Create