Toplevel window support
authorDavid Webster <Dave.Webster@bhmi.com>
Mon, 7 Jan 2002 00:49:52 +0000 (00:49 +0000)
committerDavid Webster <Dave.Webster@bhmi.com>
Mon, 7 Jan 2002 00:49:52 +0000 (00:49 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13431 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/os2/toplevel.cpp [new file with mode: 0644]

diff --git a/src/os2/toplevel.cpp b/src/os2/toplevel.cpp
new file mode 100644 (file)
index 0000000..ced8e43
--- /dev/null
@@ -0,0 +1,887 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        msw/toplevel.cpp
+// Purpose:     implements wxTopLevelWindow for MSW
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     30.12.01
+// RCS-ID:      $Id$
+// Copyright:   (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
+// License:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+    #pragma implementation "toplevel.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/toplevel.h"
+    #include "wx/string.h"
+    #include "wx/log.h"
+    #include "wx/intl.h"
+    #include "wx/frame.h"
+#endif //WX_PRECOMP
+
+#include "wx/os2/private.h"
+
+// ----------------------------------------------------------------------------
+// stubs for missing functions under MicroWindows
+// ----------------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------------
+// globals
+// ----------------------------------------------------------------------------
+
+// list of all frames and modeless dialogs
+wxWindowList wxModelessWindows;
+
+// the name of the default wxWindows class
+extern const wxChar* wxCanvasClassName;
+extern const wxChar* wxFrameClassName;
+
+// ============================================================================
+// wxTopLevelWindowMSW implementation
+// ============================================================================
+
+// Dialog window proc
+MRESULT EXPENTRY wxDlgProc( HWND WXUNUSED(hWnd)
+                           ,UINT uMessage
+                           ,MPARAM WXUNUSED(wParam)
+                           ,MPARAM WXUNUSED(lParam)
+                          )
+{
+    if (uMessage == WM_INITDLG)
+    {
+        //
+        // For this message, returning TRUE tells system to set focus to the
+        // first control in the dialog box.
+        //
+        return (MRESULT)TRUE;
+    }
+    else
+    {
+        //
+        // For all the other ones, FALSE means that we didn't process the
+        // message
+        //
+        return (MRESULT)FALSE;
+    }
+} // end of wxDlgProc
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowOS2 creation
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowOS2::Init()
+{
+    m_bIconized = m_bMaximizeOnShow = FALSE;
+
+    //
+    // Unlike (almost?) all other windows, frames are created hidden
+    //
+    m_isShown = FALSE;
+
+    //
+    // Data to save/restore when calling ShowFullScreen
+    m_lFsStyle          = 0;
+    m_lFsOldWindowStyle = 0;
+    m_bFsIsMaximized    = FALSE;
+    m_bFsIsShowing      = FALSE;
+
+    m_hFrame    = NULLHANDLE;
+    memset(&m_vSwp, 0, sizeof(SWP));
+    memset(&m_vSwpClient, 0, sizeof(SWP));
+} // end of wxTopLevelWindowIOS2::Init
+
+long wxTopLevelWindowOS2::OS2GetCreateWindowFlags(
+  long*                             plExflags
+) const
+{
+    long                            lStyle = GetWindowStyle();
+    long                            lMsflags = 0;
+
+    if (lStyle == wxDEFAULT_FRAME_STYLE)
+        lMsflags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
+                        FCF_MINMAX | FCF_TASKLIST;
+    else
+    {
+        if ((lStyle & wxCAPTION) == wxCAPTION)
+            lMsflags = FCF_TASKLIST;
+        else
+            lMsflags = FCF_NOMOVEWITHOWNER;
+
+        if ((lStyle & wxVSCROLL) == wxVSCROLL)
+            lMsflags |= FCF_VERTSCROLL;
+        if ((lStyle & wxHSCROLL) == wxHSCROLL)
+            lMsflags |= FCF_HORZSCROLL;
+        if (lStyle & wxMINIMIZE_BOX)
+            lMsflags |= FCF_MINBUTTON;
+        if (lStyle & wxMAXIMIZE_BOX)
+            lMsflags |= FCF_MAXBUTTON;
+        if (lStyle & wxTHICK_FRAME)
+            lMsflags |= FCF_DLGBORDER;
+        if (lStyle & wxSYSTEM_MENU)
+            lMsflags |= FCF_SYSMENU;
+        if (lStyle & wxCAPTION)
+            lMsflags |= FCF_TASKLIST;
+        if (lStyle & wxCLIP_CHILDREN)
+        {
+            // Invalid for frame windows under PM
+        }
+
+        if (lStyle & wxTINY_CAPTION_VERT)
+            lMsflags |= FCF_TASKLIST;
+        if (lStyle & wxTINY_CAPTION_HORIZ)
+            lMsflags |= FCF_TASKLIST;
+
+        if ((lStyle & wxTHICK_FRAME) == 0)
+            lMsflags |= FCF_BORDER;
+        if (lStyle & wxFRAME_TOOL_WINDOW)
+            *plExflags = kFrameToolWindow;
+
+        if (lStyle & wxSTAY_ON_TOP)
+            lMsflags |= FCF_SYSMODAL;
+    }
+    return lMsflags;
+} // end of wxTopLevelWindowOS2::OS2GetCreateWindowFlags
+
+bool wxTopLevelWindowOS2::CreateDialog(
+  ULONG                             ulDlgTemplate
+, const wxString&                   rsTitle
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+)
+{
+    wxWindow*                       pParent = GetParent();
+
+    //
+    // For the dialogs without wxDIALOG_NO_PARENT style, use the top level
+    // app window as parent - this avoids creating modal dialogs without
+    // parent
+    //
+    if (!pParent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT))
+    {
+        pParent = wxTheApp->GetTopWindow();
+
+        if (pParent)
+        {
+            //
+            // Don't use transient windows as parents, this is dangerous as it
+            // can lead to a crash if the parent is destroyed before the child
+            //
+            // also don't use the window which is currently hidden as then the
+            // dialog would be hidden as well
+            if ((pParent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
+                 !pParent->IsShown())
+            {
+                pParent = NULL;
+            }
+        }
+    }
+
+    HWND                            hWndDlg;
+    HWND                            hWndParent;
+
+    if (pParent)
+        hWndParent = GetHwndOf(pParent);
+    else
+        hWndParent = HWND_DESKTOP;
+
+    hWndDlg = ::WinLoadDlg( hWndParent
+                           ,hWndParent
+                           ,(PFNWP)wxDlgProc
+                           ,NULL
+                           ,(ULONG)ulDlgTemplate
+                           ,(PVOID)this
+                          );
+
+    m_hWnd = (WXHWND) hWndDlg;
+
+    if ( !m_hWnd )
+    {
+        wxFAIL_MSG(_("Did you forget to include wx/os2/wx.rc in your resources?"));
+
+        wxLogSysError(_("Can't create dialog using template '%ul'"), ulDlgTemplate);
+
+        return FALSE;
+    }
+
+    //
+    // Move the dialog to its initial position without forcing repainting
+    //
+    int                             nX;
+    int                             nY;
+    int                             nWidth;
+    int                             nHeight;
+
+    if (!OS2GetCreateWindowCoords( rPos
+                                  ,rSize
+                                  ,nX
+                                  ,nY
+                                  ,nWidth
+                                  ,nHeight
+                                 ))
+    {
+        nX = nWidth = (int)CW_USEDEFAULT;
+    }
+
+    //
+    // We can't use CW_USEDEFAULT here as we're not calling CreateWindow()
+    // and passing CW_USEDEFAULT to MoveWindow() results in resizing the
+    // window to (0, 0) size which breaks quite a lot of things, e.g. the
+    // sizer calculation in wxSizer::Fit()
+    //
+    if (nWidth == (int)CW_USEDEFAULT)
+    {
+        //
+        // The exact number doesn't matter, the dialog will be resized
+        // again soon anyhow but it should be big enough to allow
+        // calculation relying on "totalSize - clientSize > 0" work, i.e.
+        // at least greater than the title bar height
+        //
+        nWidth = nHeight = 100;
+    }
+    if (nX == (int)CW_USEDEFAULT)
+    {
+        //
+        // Centre it on the screen - what else can we do?
+        //
+        wxSize                      vSizeDpy = wxGetDisplaySize();
+
+        nX = (vSizeDpy.x - nWidth) / 2;
+        nY = (vSizeDpy.y - nHeight) / 2;
+    }
+    ::WinSetWindowPos( GetHwnd()
+                      ,HWND_TOP
+                      ,nX
+                      ,nY
+                      ,nWidth
+                      ,nHeight
+                      ,SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW
+                     );
+    if (!rsTitle.IsNull())
+    {
+        ::WinSetWindowText(GetHwnd(), rsTitle.c_str());
+    }
+    SubclassWin(m_hWnd);
+    return TRUE;
+} // end of wxTopLevelWindowOS2::CreateDialog
+
+bool wxTopLevelWindowOS2::CreateFrame(
+  const wxString&                   rsTitle
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+)
+{
+    long                            lExflags;
+    long                            lFlags = OS2GetCreateWindowFlags(&lExflags);
+    long                            lStyle = GetWindowStyleFlag();
+    int                             nX = rPos.x;
+    int                             nY = rPos.y;
+    int                             nWidth = rSize.x;
+    int                             nHeight = rSize.y;
+    ULONG                           ulStyleFlags = 0L;
+    ERRORID                         vError;
+    wxString                        sError;
+    wxWindow*                       pParent = GetParent();
+    HWND                            hParent;
+    HWND                            hFrame;
+    HWND                            hClient;
+
+    if (pParent)
+        hParent = GetHwndOf(pParent);
+    else
+        hParent = HWND_DESKTOP;
+
+    if ((lStyle & wxMINIMIZE) || (lStyle & wxICONIZE))
+        ulStyleFlags |= WS_MINIMIZED;
+    if (lStyle & wxMAXIMIZE)
+        ulStyleFlags |= WS_MAXIMIZED;
+
+    //
+    // Clear the visible flag, we always call show
+    //
+    ulStyleFlags &= (unsigned long)~WS_VISIBLE;
+    m_bIconized = FALSE;
+
+    //
+    // Create the frame window:  We break ranks with other ports now
+    // and instead of calling down into the base wxWindow class' OS2Create
+    // we do all our own stuff here.  We will set the needed pieces
+    // of wxWindow manually, here.
+    //
+
+     hFrame = ::WinCreateStdWindow( hParent
+                                   ,ulStyleFlags          // frame-window style
+                                   ,(PULONG)&lFlags       // window style
+                                   ,(PSZ)wxFrameClassName // class name
+                                   ,(PSZ)rsTitle.c_str()  // window title
+                                   ,0L                    // default client style
+                                   ,NULLHANDLE            // resource in executable file
+                                   ,0                     // resource id
+                                   ,&hClient              // receives client window handle
+                                  );
+    if (!hFrame)
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+        wxLogError("Error creating frame. Error: %s\n", sError);
+        return FALSE;
+    }
+
+    //
+    // wxWindow class' m_hWnd set here and needed associations
+    //
+    m_hFrame = hFrame;
+    m_hWnd   = hClient;
+    wxAssociateWinWithHandle(m_hWnd, this);
+    wxAssociateWinWithHandle(m_hFrame, this);
+
+    m_backgroundColour.Set(wxString("GREY"));
+
+    LONG                            lColor = (LONG)m_backgroundColour.GetPixel();
+
+    if (!::WinSetPresParam( m_hWnd
+                           ,PP_BACKGROUNDCOLOR
+                           ,sizeof(LONG)
+                           ,(PVOID)&lColor
+                          ))
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+        wxLogError("Error creating frame. Error: %s\n", sError);
+        return FALSE;
+    }
+
+    //
+    // Now need to subclass window.  Instead of calling the SubClassWin in wxWindow
+    // we manually subclass here because we don't want to use the main wxWndProc
+    // by default
+    //
+    m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(m_hFrame, (PFNWP)wxFrameMainWndProc);
+
+    //
+    // Now size everything.  If adding a menu the client will need to be resized.
+    //
+
+    if (pParent)
+    {
+        nY = pParent->GetSize().y - (nY + nHeight);
+    }
+    else
+    {
+        RECTL                   vRect;
+
+        ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
+        nY = vRect.yTop - (nY + nHeight);
+    }
+    if (!::WinSetWindowPos( m_hFrame
+                           ,HWND_TOP
+                           ,nX
+                           ,nY
+                           ,nWidth
+                           ,nHeight
+                           ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_ZORDER
+                          ))
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+        wxLogError("Error sizing frame. Error: %s\n", sError);
+        return FALSE;
+    }
+    return TRUE;
+} // end of wxTopLevelWindowOS2::CreateFrame
+
+bool wxTopLevelWindowOS2::Create(
+  wxWindow*                         pParent
+, wxWindowID                        vId
+, const wxString&                   rsTitle
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+, long                              lStyle
+, const wxString&                   rsName
+)
+{
+    //
+    // Init our fields
+    //
+    Init();
+    m_windowStyle = lStyle;
+    SetName(rsName);
+    m_windowId = vId == -1 ? NewControlId() : vId;
+    wxTopLevelWindows.Append(this);
+    if (pParent)
+        pParent->AddChild(this);
+
+    if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
+    {
+        //
+        // We have different dialog templates to allows creation of dialogs
+        // with & without captions under OS2indows, resizeable or not (but a
+        // resizeable dialog always has caption - otherwise it would look too
+        // strange)
+        //
+        ULONG                       ulDlgTemplate;
+
+        if (lStyle & wxRESIZE_BORDER)
+            ulDlgTemplate = (ULONG)kResizeableDialog;
+        else if (lStyle & wxCAPTION)
+            ulDlgTemplate = (ULONG)kCaptionDialog;
+        else
+            ulDlgTemplate = (ULONG)kNoCaptionDialog;
+        return CreateDialog( ulDlgTemplate
+                            ,rsTitle
+                            ,rPos
+                            ,rSize
+                           );
+    }
+    else // !dialog
+    {
+        return CreateFrame( rsTitle
+                           ,rPos
+                           ,rSize
+                          );
+    }
+} // end of wxTopLevelWindowOS2::Create
+
+wxTopLevelWindowOS2::~wxTopLevelWindowOS2()
+{
+    wxTopLevelWindows.DeleteObject(this);
+
+    if (wxModelessWindows.Find(this))
+        wxModelessWindows.DeleteObject(this);
+
+    //
+    // If this is the last top-level window, exit.
+    //
+    if (wxTheApp && (wxTopLevelWindows.Number() == 0))
+    {
+        wxTheApp->SetTopWindow(NULL);
+        if ( wxTheApp->GetExitOnFrameDelete() )
+        {
+            ::WinPostMsg(NULL, WM_QUIT, 0, 0);
+        }
+    }
+} // end of wxTopLevelWindowOS2::~wxTopLevelWindowOS2
+
+//
+//  IF we have child controls in the Frame's client we need to alter
+//  the y position, because, OS/2 controls are positioned relative to
+//  wxWindows orgin (top left) not the OS/2 origin (bottom left)
+//
+void wxTopLevelWindowOS2::AlterChildPos()
+{
+    //
+    // OS/2 is the only OS concerned about this
+    //
+    wxWindow*                               pChild = NULL;
+    wxControl*                              pCtrl = NULL;
+    RECTL                                   vRect;
+    SWP                                     vSwp;
+
+    ::WinQueryWindowRect(GetHwnd(), &vRect);
+    for (wxWindowList::Node* pNode = GetChildren().GetFirst();
+         pNode;
+         pNode = pNode->GetNext())
+    {
+        wxWindow*                   pChild = pNode->GetData();
+
+        ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
+        vSwp.y += (vRect.yTop - m_vSwpClient.cy);
+        if (pChild->IsKindOf(CLASSINFO(wxControl)))
+        {
+            pCtrl = wxDynamicCast(pChild, wxControl);
+            //
+            // Must deal with controls that have margins like ENTRYFIELD.  The SWP
+            // struct of such a control will have and origin offset from its intended
+            // position by the width of the margins.
+            //
+            vSwp.y -= pCtrl->GetYComp();
+            vSwp.x -= pCtrl->GetXComp();
+        }
+        ::WinSetWindowPos( pChild->GetHWND()
+                          ,HWND_TOP
+                          ,vSwp.x
+                          ,vSwp.y
+                          ,vSwp.cx
+                          ,vSwp.cy
+                          ,SWP_MOVE
+                         );
+        ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
+        pChild = NULL;
+    }
+    ::WinQueryWindowPos(GetHwnd(), &m_vSwpClient);
+} // end of wxTopLevelWindowOS2::AlterChildPos
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowOS2 client size
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowOS2::DoSetClientSize(
+  int                               nWidth
+, int                               nHeight
+)
+{
+    //
+    // Call GetClientAreaOrigin() to take the toolbar into account
+    //
+    wxPoint                         vPt = GetClientAreaOrigin();
+
+    nWidth  += vPt.x;
+    nHeight += vPt.y;
+
+    wxWindow::DoSetClientSize( nWidth
+                              ,nHeight
+                             );
+} // end of wxTopLevelWindowOS2::DoSetClientSize
+
+void wxTopLevelWindowOS2::DoGetClientSize(
+  int*                              pnX
+, int*                              pnY
+) const
+{
+    wxWindow::DoGetClientSize( pnX
+                              ,pnY
+                             );
+
+    wxPoint                         vPt = GetClientAreaOrigin();
+
+    if (pnX)
+        *pnX -= vPt.x;
+
+    if (pnY)
+        *pnY += vPt.y;
+} // end of wxTopLevelWindowOS2::DoGetClientSize
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowOS2 showing
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowOS2::DoShowWindow(
+  int                               nShowCmd
+)
+{
+    ::WinShowWindow(m_hFrame, (BOOL)nShowCmd);
+    m_bIconized = nShowCmd == SWP_MINIMIZE;
+} // end of wxTopLevelWindowOS2::DoShowWindow
+
+bool wxTopLevelWindowOS2::Show(
+  bool                              bShow
+)
+{
+    int                             nShowCmd;
+    SWP                             vSwp;
+    RECTL                           vRect;
+
+    if (bShow)
+    {
+        if (m_bMaximizeOnShow)
+        {
+            nShowCmd = SWP_SHOW;
+            m_bMaximizeOnShow = FALSE;
+        }
+        else
+        {
+            nShowCmd = SWP_HIDE;
+        }
+    }
+    else // hide
+    {
+        nShowCmd = SWP_HIDE;
+    }
+    DoShowWindow(nShowCmd);
+
+    if (bShow)
+    {
+        wxActivateEvent             vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
+
+        ::WinQueryWindowPos(m_hFrame, &vSwp);
+        m_bIconized = vSwp.fl & SWP_MINIMIZE;
+        ::WinQueryWindowPos(m_hWnd, &m_vSwpClient);
+        ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
+        ::WinEnableWindow(m_hFrame, TRUE);
+        vEvent.SetEventObject(this);
+        GetEventHandler()->ProcessEvent(vEvent);
+    }
+    else
+    {
+        //
+        // Try to highlight the correct window (the parent)
+        //
+        if (GetParent())
+        {
+            HWND                    hWndParent = GetHwndOf(GetParent());
+
+            ::WinQueryWindowPos(hWndParent, &vSwp);
+            m_bIconized = vSwp.fl & SWP_MINIMIZE;
+            if (hWndParent)
+                ::WinSetWindowPos( hWndParent
+                                  ,HWND_TOP
+                                  ,vSwp.x
+                                  ,vSwp.y
+                                  ,vSwp.cx
+                                  ,vSwp.cy
+                                  ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
+                                 );
+            ::WinEnableWindow(hWndParent, TRUE);
+        }
+    }
+    return TRUE;
+} // end of wxTopLevelWindowOS2::Show
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowOS2 maximize/minimize
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowOS2::Maximize(
+  bool                              bMaximize
+)
+{
+    if (IsShown())
+    {
+        //
+        // Just maximize it directly
+        //
+        DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
+    }
+    else // hidden
+    {
+        //
+        // We can't maximize the hidden frame because it shows it as well, so
+        // just remember that we should do it later in this case
+        //
+        m_bMaximizeOnShow = TRUE;
+    }
+} // end of wxTopLevelWindowOS2::Maximize
+
+bool wxTopLevelWindowOS2::IsMaximized() const
+{
+    bool                            bIconic;
+
+    ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
+    return (m_vSwp.fl & SWP_MAXIMIZE);
+} // end of wxTopLevelWindowOS2::IsMaximized
+
+void wxTopLevelWindowOS2::Iconize(
+  bool                              bIconize
+)
+{
+    DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
+} // end of wxTopLevelWindowOS2::Iconize
+
+bool wxTopLevelWindowOS2::IsIconized() const
+{
+    // also update the current state
+    ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
+    if (m_vSwp.fl & SWP_MINIMIZE)
+        ((wxTopLevelWindow*)this)->m_bIconized = TRUE;
+    else
+        ((wxTopLevelWindow*)this)->m_bIconized = FALSE;
+    return m_bIconized;
+} // end of wxTopLevelWindowOS2::IsIconized
+
+void wxTopLevelWindowOS2::Restore()
+{
+    DoShowWindow(SWP_RESTORE);
+} // end of wxTopLevelWindowOS2::Restore
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowOS2 fullscreen
+// ----------------------------------------------------------------------------
+
+bool wxTopLevelWindowOS2::ShowFullScreen(
+  bool                              bShow
+, long                              lStyle
+)
+{
+    if (bShow)
+    {
+        if (IsFullScreen())
+            return FALSE;
+
+        m_bFsIsShowing = TRUE;
+        m_lFsStyle = lStyle;
+
+        //
+        // Zap the frame borders
+        //
+
+        //
+        // Save the 'normal' window lStyle
+        //
+        m_lFsOldWindowStyle = ::WinQueryWindowULong( (HWND)GetHWND()
+                                                    ,QWL_STYLE
+                                                   );
+
+        //
+        // Save the old position, width & height, maximize state
+        //
+        m_vFsOldSize = GetRect();
+        m_bFsIsMaximized = IsMaximized();
+
+        //
+        // Decide which window lStyle flags to turn off
+        //
+        LONG                        lNewStyle = m_lFsOldWindowStyle;
+        LONG                        lOffFlags = 0;
+
+        if (lStyle & wxFULLSCREEN_NOBORDER)
+            lOffFlags |= FCF_BORDER;
+        if (lStyle & wxFULLSCREEN_NOCAPTION)
+            lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
+
+        lNewStyle &= (~lOffFlags);
+
+        //
+        // Change our window style to be compatible with full-screen mode
+        //
+        ::WinSetWindowULong( (HWND)GetHWND()
+                            ,QWL_STYLE
+                            ,lNewStyle
+                           );
+
+        //
+        // Resize to the size of the desktop
+        //
+        int                         nWidth;
+        int                         nHeight;
+        RECTL                       vRect = wxGetWindowRect(HWND_DESKTOP);
+
+        nWidth = vRect.xRight - vRect.xLeft;
+        nHeight = vRect.yTop - vRect.yBottom;
+
+        SetSize( nWidth
+                ,nHeight
+               );
+
+        //
+        // Now flush the window style cache and actually go full-screen
+        //
+        ::WinSetWindowPos( m_hFrame
+                          ,HWND_TOP
+                          ,0
+                          ,0
+                          ,nWidth
+                          ,nHeight
+                          ,SWP_SIZE | SWP_MOVE
+                         );
+
+        wxSizeEvent                 vEvent( wxSize( nWidth
+                                                   ,nHeight
+                                                  )
+                                           ,GetId()
+                                          );
+
+        GetEventHandler()->ProcessEvent(vEvent);
+        return TRUE;
+    }
+    else
+    {
+        if (!IsFullScreen())
+            return FALSE;
+
+        m_bFsIsShowing = FALSE;
+        Maximize(m_bFsIsMaximized);
+        ::WinSetWindowULong( (HWND)GetHWND()
+                            ,QWL_STYLE
+                            ,m_lFsOldWindowStyle
+                           );
+        ::WinSetWindowPos( m_hFrame
+                          ,HWND_TOP
+                          ,m_vFsOldSize.x
+                          ,m_vFsOldSize.y
+                          ,m_vFsOldSize.width
+                          ,m_vFsOldSize.height
+                          ,SWP_SIZE | SWP_MOVE
+                         );
+        return TRUE;
+    }
+} // end of wxTopLevelWindowOS2::ShowFullScreen
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowOS2 misc
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowOS2::SetIcon(
+  const wxIcon&                     rIcon
+)
+{
+    //
+    // This sets m_icon
+    //
+    wxTopLevelWindowBase::SetIcon(rIcon);
+
+    if (m_icon.Ok())
+    {
+        ::WinSendMsg( m_hFrame
+                     ,WM_SETICON
+                     ,(MPARAM)((HPOINTER)m_icon.GetHICON())
+                     ,NULL
+                    );
+        ::WinSendMsg( m_hFrame
+                     ,WM_UPDATEFRAME
+                     ,(MPARAM)FCF_ICON
+                     ,(MPARAM)0
+                    );
+    }
+} // end of wxTopLevelWindowOS2::SetIcon
+
+bool wxTopLevelWindowOS2::EnableCloseButton(
+  bool                              bEnable
+)
+{
+    //
+    // Get system (a.k.a. window) menu
+    //
+    HMENU                           hMenu = ::WinWindowFromID(m_hFrame, FID_SYSMENU);
+
+    if (!hMenu)
+    {
+        wxLogLastError(_T("GetSystemMenu"));
+        return FALSE;
+    }
+
+    //
+    // Enabling/disabling the close item from it also automatically
+    // disables/enables the close title bar button
+    //
+    if (bEnable)
+        (void)::WinSendMsg( hMenu
+                           ,MM_SETITEMATTR
+                           ,MPFROM2SHORT(SC_CLOSE, FALSE)
+                           ,MPFROM2SHORT(MIA_DISABLED, FALSE)
+                          );
+    else
+        (void)::WinSendMsg( hMenu
+                           ,MM_SETITEMATTR
+                           ,MPFROM2SHORT(SC_CLOSE, FALSE)
+                           ,MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)
+                          );
+
+    //
+    // Update appearance immediately
+    //
+    ::WinSendMsg( m_hFrame
+                 ,WM_UPDATEFRAME
+                 ,(MPARAM)FCF_MENU
+                 ,(MPARAM)0
+                );
+    return TRUE;
+} // end of wxTopLevelWindowOS2::EnableCloseButton
+