--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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
+