home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / toplevel.cpp < prev    next >
C/C++ Source or Header  |  2002-08-27  |  33KB  |  1,026 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name:        msw/toplevel.cpp
  3. // Purpose:     implements wxTopLevelWindow for MSW
  4. // Author:      Vadim Zeitlin
  5. // Modified by:
  6. // Created:     30.12.01
  7. // RCS-ID:      $Id: toplevel.cpp,v 1.22 2002/08/25 17:58:44 SN Exp $
  8. // Copyright:   (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
  9. // License:     wxWindows license
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "toplevel.h"
  22. #endif
  23.  
  24. // For compilers that support precompilation, includes "wx.h".
  25. #include "wx/wxprec.h"
  26.  
  27. #ifdef __BORLANDC__
  28.     #pragma hdrstop
  29. #endif
  30.  
  31. #ifndef WX_PRECOMP
  32.     #include "wx/app.h"
  33.     #include "wx/toplevel.h"
  34.     #include "wx/string.h"
  35.     #include "wx/log.h"
  36.     #include "wx/intl.h"
  37.     #include "wx/frame.h"
  38.     #include "wx/control.h"
  39.     #include "wx/containr.h"        // wxSetFocusToChild()
  40. #endif //WX_PRECOMP
  41.  
  42. #include "wx/os2/private.h"
  43.  
  44. // ----------------------------------------------------------------------------
  45. // stubs for missing functions under MicroWindows
  46. // ----------------------------------------------------------------------------
  47.  
  48.  
  49. // ----------------------------------------------------------------------------
  50. // globals
  51. // ----------------------------------------------------------------------------
  52.  
  53. // list of all frames and modeless dialogs
  54. wxWindowList wxModelessWindows;
  55.  
  56. // the name of the default wxWindows class
  57. extern void          wxAssociateWinWithHandle( HWND         hWnd
  58.                                               ,wxWindowOS2* pWin
  59.                                              );
  60. bool                 wxTopLevelWindowOS2::m_sbInitialized = FALSE;
  61. wxWindow*            wxTopLevelWindowOS2::m_spHiddenParent = NULL;
  62.  
  63. // ============================================================================
  64. // wxTopLevelWindowOS2 implementation
  65. // ============================================================================
  66.  
  67. BEGIN_EVENT_TABLE(wxTopLevelWindowOS2, wxTopLevelWindowBase)
  68.     EVT_ACTIVATE(wxTopLevelWindowOS2::OnActivate)
  69. END_EVENT_TABLE()
  70.  
  71. // ============================================================================
  72. // wxTopLevelWindowMSW implementation
  73. // ============================================================================
  74.  
  75. // Dialog window proc
  76. MRESULT EXPENTRY wxDlgProc( HWND WXUNUSED(hWnd)
  77.                            ,UINT uMessage
  78.                            ,MPARAM WXUNUSED(wParam)
  79.                            ,MPARAM WXUNUSED(lParam)
  80.                           )
  81. {
  82.     switch(uMessage)
  83.     {
  84.         case WM_INITDLG:
  85.             //
  86.             // For this message, returning TRUE tells system to set focus to
  87.             // the first control in the dialog box, but we set the focus
  88.             // ourselves, however in OS/2 we must return true to enable the dialog
  89.             //
  90.             return (MRESULT)TRUE;
  91.         default:
  92.             //
  93.             // For all the other ones, FALSE means that we didn't process the
  94.             // message
  95.             //
  96.             return (MRESULT)FALSE;
  97.     }
  98. } // end of wxDlgProc
  99.  
  100. // ----------------------------------------------------------------------------
  101. // wxTopLevelWindowOS2 creation
  102. // ----------------------------------------------------------------------------
  103.  
  104. void wxTopLevelWindowOS2::Init()
  105. {
  106.     m_bIconized = m_bMaximizeOnShow = FALSE;
  107.  
  108.     //
  109.     // Unlike (almost?) all other windows, frames are created hidden
  110.     //
  111.     m_isShown = FALSE;
  112.  
  113.     //
  114.     // Data to save/restore when calling ShowFullScreen
  115.     m_lFsStyle          = 0;
  116.     m_lFsOldWindowStyle = 0;
  117.     m_bFsIsMaximized    = FALSE;
  118.     m_bFsIsShowing      = FALSE;
  119.  
  120.     m_hFrame    = NULLHANDLE;
  121.     memset(&m_vSwp, 0, sizeof(SWP));
  122.     memset(&m_vSwpClient, 0, sizeof(SWP));
  123.     m_pWinLastFocused = (wxWindow *)NULL;
  124. } // end of wxTopLevelWindowIOS2::Init
  125.  
  126. void wxTopLevelWindowOS2::OnActivate(
  127.   wxActivateEvent&                  rEvent
  128. )
  129. {
  130.     if (rEvent.GetActive())
  131.     {
  132.         //
  133.         // Restore focus to the child which was last focused
  134.         //
  135.         wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), m_hWnd);
  136.  
  137.         wxWindow*                   pParent = m_pWinLastFocused ? m_pWinLastFocused->GetParent()
  138.                                                                 : NULL;
  139.         if (!pParent)
  140.         {
  141.             pParent = this;
  142.         }
  143.  
  144.         wxSetFocusToChild( pParent
  145.                           ,&m_pWinLastFocused
  146.                          );
  147.     }
  148.     else // deactivating
  149.     {
  150.         //
  151.         // Remember the last focused child if it is our child
  152.         //
  153.         m_pWinLastFocused = FindFocus();
  154.  
  155.         //
  156.         // So we NULL it out if it's a child from some other frame
  157.         //
  158.         wxWindow*                   pWin = m_pWinLastFocused;
  159.  
  160.         while (pWin)
  161.         {
  162.             if (pWin->IsTopLevel())
  163.             {
  164.                 if (pWin != this)
  165.                 {
  166.                     m_pWinLastFocused = NULL;
  167.                 }
  168.                 break;
  169.             }
  170.             pWin = pWin->GetParent();
  171.         }
  172.  
  173.         wxLogTrace(_T("focus"),
  174.                    _T("wxTLW %08x deactivated, last focused: %08x."),
  175.                    m_hWnd,
  176.                    m_pWinLastFocused ? GetHwndOf(m_pWinLastFocused)
  177.                                      : NULL);
  178.         rEvent.Skip();
  179.     }
  180. } // end of wxTopLevelWindowOS2::OnActivate
  181.  
  182. WXDWORD wxTopLevelWindowOS2::OS2GetStyle(
  183.   long                              lStyle
  184. , WXDWORD*                          pdwExflags
  185. ) const
  186. {
  187.     long                            lMsflags = wxWindow::OS2GetStyle( (lStyle & ~wxBORDER_MASK) | wxBORDER_NONE
  188.                                                                      ,pdwExflags
  189.                                                                     );
  190.  
  191.     if (lStyle == wxDEFAULT_FRAME_STYLE)
  192.         lMsflags |= FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
  193.                     FCF_MINMAX | FCF_TASKLIST;
  194.     else
  195.     {
  196.         if ((lStyle & wxCAPTION) == wxCAPTION)
  197.             lMsflags |= FCF_TASKLIST;
  198.         else
  199.             lMsflags |= FCF_NOMOVEWITHOWNER;
  200.  
  201.         if ((lStyle & wxVSCROLL) == wxVSCROLL)
  202.             lMsflags |= FCF_VERTSCROLL;
  203.         if ((lStyle & wxHSCROLL) == wxHSCROLL)
  204.             lMsflags |= FCF_HORZSCROLL;
  205.         if (lStyle & wxMINIMIZE_BOX)
  206.             lMsflags |= FCF_MINBUTTON;
  207.         if (lStyle & wxMAXIMIZE_BOX)
  208.             lMsflags |= FCF_MAXBUTTON;
  209.         if (lStyle & wxTHICK_FRAME)
  210.             lMsflags |= FCF_DLGBORDER;
  211.         if (lStyle & wxSYSTEM_MENU)
  212.             lMsflags |= FCF_SYSMENU;
  213.         if (lStyle & wxCAPTION)
  214.             lMsflags |= FCF_TASKLIST;
  215.         if (lStyle & wxCLIP_CHILDREN)
  216.         {
  217.             // Invalid for frame windows under PM
  218.         }
  219.  
  220.         if (lStyle & wxTINY_CAPTION_VERT)
  221.             lMsflags |= FCF_TASKLIST;
  222.         if (lStyle & wxTINY_CAPTION_HORIZ)
  223.             lMsflags |= FCF_TASKLIST;
  224.  
  225.         if ((lStyle & wxTHICK_FRAME) == 0)
  226.             lMsflags |= FCF_BORDER;
  227.         if (lStyle & wxFRAME_TOOL_WINDOW)
  228.             *pdwExflags = kFrameToolWindow;
  229.  
  230.         if (lStyle & wxSTAY_ON_TOP)
  231.             lMsflags |= FCF_SYSMODAL;
  232.     }
  233.     return lMsflags;
  234. } // end of wxTopLevelWindowOS2::OS2GetCreateWindowFlags
  235.  
  236. WXHWND wxTopLevelWindowOS2::OS2GetParent() const
  237. {
  238.     //
  239.     // For the frames without wxFRAME_FLOAT_ON_PARENT style we should use NULL
  240.     // parent HWND or it would be always on top of its parent which is not what
  241.     // we usually want (in fact, we only want it for frames with the
  242.     // wxFRAME_FLOAT_ON_PARENT flag)
  243.     //
  244.     wxWindow*                           pParent;
  245.  
  246.     if (HasFlag(wxFRAME_FLOAT_ON_PARENT) )
  247.     {
  248.         pParent = GetParent();
  249.  
  250.         // this flag doesn't make sense then and will be ignored
  251.         wxASSERT_MSG( pParent,
  252.                       _T("wxFRAME_FLOAT_ON_PARENT but no parent?") );
  253.     }
  254.     else // don't float on parent, must not be owned
  255.     {
  256.         pParent = NULL;
  257.     }
  258.     if (HasFlag(wxFRAME_NO_TASKBAR) && !pParent)
  259.     {
  260.         if (!m_spHiddenParent)
  261.         {
  262.             m_spHiddenParent = new wxTopLevelWindowOS2(NULL, -1, _T(""));
  263.  
  264.             //
  265.             // We shouldn't leave it in wxTopLevelWindows or we wouldn't
  266.             // terminate the app when the last user-created frame is deleted --
  267.             // see ~wxTopLevelWindowMSW
  268.             //
  269.             wxTopLevelWindows.DeleteObject(m_spHiddenParent);
  270.         }
  271.         pParent = m_spHiddenParent;
  272.     }
  273.     return pParent ? pParent->GetHWND() : NULL;
  274. } // end of wxTopLevelWindowOS2::OS2GetParent
  275.  
  276. bool wxTopLevelWindowOS2::CreateDialog(
  277.   ULONG                             ulDlgTemplate
  278. , const wxString&                   rsTitle
  279. , const wxPoint&                    rPos
  280. , const wxSize&                     rSize
  281. )
  282. {
  283.     wxWindow*                       pParent = GetParent();
  284.  
  285.     //
  286.     // For the dialogs without wxDIALOG_NO_PARENT style, use the top level
  287.     // app window as parent - this avoids creating modal dialogs without
  288.     // parent
  289.     //
  290.     if (!pParent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT))
  291.     {
  292.         pParent = wxTheApp->GetTopWindow();
  293.  
  294.         if (pParent)
  295.         {
  296.             //
  297.             // Don't use transient windows as parents, this is dangerous as it
  298.             // can lead to a crash if the parent is destroyed before the child
  299.             //
  300.             // also don't use the window which is currently hidden as then the
  301.             // dialog would be hidden as well
  302.             if ((pParent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
  303.                  !pParent->IsShown())
  304.             {
  305.                 pParent = NULL;
  306.             }
  307.         }
  308.     }
  309.  
  310.     HWND                            hWndDlg;
  311.     HWND                            hWndOwner;
  312.  
  313.     if (pParent)
  314.         hWndOwner = GetHwndOf(pParent);
  315.     else
  316.         hWndOwner = HWND_DESKTOP;
  317.  
  318.     hWndDlg = ::WinLoadDlg( HWND_DESKTOP
  319.                            ,hWndOwner
  320.                            ,(PFNWP)wxDlgProc
  321.                            ,NULL
  322.                            ,(ULONG)ulDlgTemplate
  323.                            ,(PVOID)this
  324.                           );
  325.  
  326.     m_hWnd = (WXHWND) hWndDlg;
  327.  
  328.     if ( !m_hWnd )
  329.     {
  330.         wxFAIL_MSG(_("Did you forget to include wx/os2/wx.rc in your resources?"));
  331.  
  332.         wxLogSysError(_("Can't create dialog using template '%ul'"), ulDlgTemplate);
  333.  
  334.         return FALSE;
  335.     }
  336.  
  337.     //
  338.     // Move the dialog to its initial position without forcing repainting
  339.     //
  340.     int                             nX;
  341.     int                             nY;
  342.     int                             nWidth;
  343.     int                             nHeight;
  344.  
  345.     if (!OS2GetCreateWindowCoords( rPos
  346.                                   ,rSize
  347.                                   ,nX
  348.                                   ,nY
  349.                                   ,nWidth
  350.                                   ,nHeight
  351.                                  ))
  352.     {
  353.         nX = nWidth = (int)CW_USEDEFAULT;
  354.     }
  355.  
  356.     //
  357.     // We can't use CW_USEDEFAULT here as we're not calling CreateWindow()
  358.     // and passing CW_USEDEFAULT to MoveWindow() results in resizing the
  359.     // window to (0, 0) size which breaks quite a lot of things, e.g. the
  360.     // sizer calculation in wxSizer::Fit()
  361.     //
  362.     if (nWidth == (int)CW_USEDEFAULT)
  363.     {
  364.         //
  365.         // The exact number doesn't matter, the dialog will be resized
  366.         // again soon anyhow but it should be big enough to allow
  367.         // calculation relying on "totalSize - clientSize > 0" work, i.e.
  368.         // at least greater than the title bar height
  369.         //
  370.         nWidth = nHeight = 100;
  371.     }
  372.     if (nX == (int)CW_USEDEFAULT)
  373.     {
  374.         //
  375.         // Centre it on the screen - what else can we do?
  376.         //
  377.         wxSize                      vSizeDpy = wxGetDisplaySize();
  378.  
  379.         nX = (vSizeDpy.x - nWidth) / 2;
  380.         nY = (vSizeDpy.y - nHeight) / 2;
  381.     }
  382.     m_backgroundColour.Set(wxString("LIGHT GREY"));
  383.  
  384.     LONG                            lColor = (LONG)m_backgroundColour.GetPixel();
  385.  
  386.     if (!::WinSetPresParam( m_hWnd
  387.                            ,PP_BACKGROUNDCOLOR
  388.                            ,sizeof(LONG)
  389.                            ,(PVOID)&lColor
  390.                           ))
  391.     {
  392.         return FALSE;
  393.     }
  394.  
  395.     ::WinSetWindowPos( GetHwnd()
  396.                       ,HWND_TOP
  397.                       ,nX
  398.                       ,nY
  399.                       ,nWidth
  400.                       ,nHeight
  401.                       ,SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW | SWP_ACTIVATE
  402.                      );
  403.     ::WinQueryWindowPos(GetHwnd(), GetSwp());
  404.     m_hFrame = m_hWnd;
  405.     SubclassWin(m_hWnd);
  406.     return TRUE;
  407. } // end of wxTopLevelWindowOS2::CreateDialog
  408.  
  409. bool wxTopLevelWindowOS2::CreateFrame(
  410.   const wxString&                   rsTitle
  411. , const wxPoint&                    rPos
  412. , const wxSize&                     rSize
  413. )
  414. {
  415.     WXDWORD                         lExflags;
  416.     WXDWORD                         lFlags = OS2GetCreateWindowFlags(&lExflags);
  417.     long                            lStyle = GetWindowStyleFlag();
  418.     int                             nX = rPos.x;
  419.     int                             nY = rPos.y;
  420.     int                             nWidth = rSize.x;
  421.     int                             nHeight = rSize.y;
  422.     ULONG                           ulStyleFlags = 0L;
  423.     ERRORID                         vError;
  424.     wxString                        sError;
  425.     wxWindow*                       pParent = GetParent();
  426.     HWND                            hParent;
  427.     HWND                            hFrame;
  428.     HWND                            hClient;
  429.  
  430.     if (pParent)
  431.         hParent = GetHwndOf(pParent);
  432.     else
  433.         hParent = HWND_DESKTOP;
  434.  
  435.     if ((lStyle & wxMINIMIZE) || (lStyle & wxICONIZE))
  436.         ulStyleFlags |= WS_MINIMIZED;
  437.     if (lStyle & wxMAXIMIZE)
  438.         ulStyleFlags |= WS_MAXIMIZED;
  439.  
  440.     //
  441.     // Clear the visible flag, we always call show
  442.     //
  443.     ulStyleFlags &= (unsigned long)~WS_VISIBLE;
  444.     m_bIconized = FALSE;
  445.  
  446.     //
  447.     // Create the frame window:  We break ranks with other ports now
  448.     // and instead of calling down into the base wxWindow class' OS2Create
  449.     // we do all our own stuff here.  We will set the needed pieces
  450.     // of wxWindow manually, here.
  451.     //
  452.  
  453.      hFrame = ::WinCreateStdWindow( hParent
  454.                                    ,ulStyleFlags          // frame-window style
  455.                                    ,(PULONG)&lFlags       // window style
  456.                                    ,(PSZ)wxFrameClassName // class name
  457.                                    ,(PSZ)rsTitle.c_str()  // window title
  458.                                    ,0L                    // default client style
  459.                                    ,NULLHANDLE            // resource in executable file
  460.                                    ,0                     // resource id
  461.                                    ,&hClient              // receives client window handle
  462.                                   );
  463.     if (!hFrame)
  464.     {
  465.         vError = ::WinGetLastError(vHabmain);
  466.         sError = wxPMErrorToStr(vError);
  467.         wxLogError("Error creating frame. Error: %s\n", sError);
  468.         return FALSE;
  469.     }
  470.  
  471.     //
  472.     // wxWindow class' m_hWnd set here and needed associations
  473.     //
  474.     m_hFrame = hFrame;
  475.     m_hWnd   = hClient;
  476.     wxAssociateWinWithHandle(m_hWnd, this);
  477.     wxAssociateWinWithHandle(m_hFrame, this);
  478.  
  479.     m_backgroundColour.Set(wxString("MEDIUM GREY"));
  480.  
  481.     LONG                            lColor = (LONG)m_backgroundColour.GetPixel();
  482.  
  483.     if (!::WinSetPresParam( m_hWnd
  484.                            ,PP_BACKGROUNDCOLOR
  485.                            ,sizeof(LONG)
  486.                            ,(PVOID)&lColor
  487.                           ))
  488.     {
  489.         vError = ::WinGetLastError(vHabmain);
  490.         sError = wxPMErrorToStr(vError);
  491.         wxLogError("Error creating frame. Error: %s\n", sError);
  492.         return FALSE;
  493.     }
  494.  
  495.     //
  496.     // Now need to subclass window.  Instead of calling the SubClassWin in wxWindow
  497.     // we manually subclass here because we don't want to use the main wxWndProc
  498.     // by default
  499.     //
  500.     m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(m_hFrame, (PFNWP)wxFrameMainWndProc);
  501.  
  502.     //
  503.     // Now size everything.  If adding a menu the client will need to be resized.
  504.     //
  505.  
  506.     if (pParent)
  507.     {
  508.         nY = pParent->GetSize().y - (nY + nHeight);
  509.     }
  510.     else
  511.     {
  512.         RECTL                   vRect;
  513.  
  514.         ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
  515.         nY = vRect.yTop - (nY + nHeight);
  516.     }
  517.     if (!::WinSetWindowPos( m_hFrame
  518.                            ,HWND_TOP
  519.                            ,nX
  520.                            ,nY
  521.                            ,nWidth
  522.                            ,nHeight
  523.                            ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_ZORDER
  524.                           ))
  525.     {
  526.         vError = ::WinGetLastError(vHabmain);
  527.         sError = wxPMErrorToStr(vError);
  528.         wxLogError("Error sizing frame. Error: %s\n", sError);
  529.         return FALSE;
  530.     }
  531.     lStyle =  ::WinQueryWindowULong( m_hWnd
  532.                                     ,QWL_STYLE
  533.                                    );
  534.     lStyle |= WS_CLIPCHILDREN;
  535.     ::WinSetWindowULong( m_hWnd
  536.                         ,QWL_STYLE
  537.                         ,lStyle
  538.                        );
  539.     return TRUE;
  540. } // end of wxTopLevelWindowOS2::CreateFrame
  541.  
  542. bool wxTopLevelWindowOS2::Create(
  543.   wxWindow*                         pParent
  544. , wxWindowID                        vId
  545. , const wxString&                   rsTitle
  546. , const wxPoint&                    rPos
  547. , const wxSize&                     rSize
  548. , long                              lStyle
  549. , const wxString&                   rsName
  550. )
  551. {
  552.     //
  553.     // Init our fields
  554.     //
  555.     Init();
  556.     m_windowStyle = lStyle;
  557.     SetName(rsName);
  558.     m_windowId = vId == -1 ? NewControlId() : vId;
  559.     wxTopLevelWindows.Append(this);
  560.     if (pParent)
  561.         pParent->AddChild(this);
  562.  
  563.     if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
  564.     {
  565.         //
  566.         // We have different dialog templates to allows creation of dialogs
  567.         // with & without captions under OS2indows, resizeable or not (but a
  568.         // resizeable dialog always has caption - otherwise it would look too
  569.         // strange)
  570.         //
  571.         ULONG                       ulDlgTemplate;
  572.  
  573.         if (lStyle & wxRESIZE_BORDER)
  574.             ulDlgTemplate = (ULONG)kResizeableDialog;
  575.         else if (lStyle & wxCAPTION)
  576.             ulDlgTemplate = (ULONG)kCaptionDialog;
  577.         else
  578.             ulDlgTemplate = (ULONG)kNoCaptionDialog;
  579.         return CreateDialog( ulDlgTemplate
  580.                             ,rsTitle
  581.                             ,rPos
  582.                             ,rSize
  583.                            );
  584.     }
  585.     else // !dialog
  586.     {
  587.         return CreateFrame( rsTitle
  588.                            ,rPos
  589.                            ,rSize
  590.                           );
  591.     }
  592. } // end of wxTopLevelWindowOS2::Create
  593.  
  594. wxTopLevelWindowOS2::~wxTopLevelWindowOS2()
  595. {
  596.     if (this == m_spHiddenParent)
  597.     {
  598.         //
  599.         // Stop [infinite] recursion which would otherwise happen when we do
  600.         // "delete ms_hiddenParent" below -- and we're not interested in doing
  601.         // anything of the rest below for that window because the rest of
  602.         // wxWindows doesn't even know about it
  603.         //
  604.         return;
  605.     }
  606.  
  607.     if (wxModelessWindows.Find(this))
  608.         wxModelessWindows.DeleteObject(this);
  609.  
  610.     //
  611.     // After destroying an owned window, Windows activates the next top level
  612.     // window in Z order but it may be different from our owner (to reproduce
  613.     // this simply Alt-TAB to another application and back before closing the
  614.     // owned frame) whereas we always want to yield activation to our parent
  615.     //
  616.     if (HasFlag(wxFRAME_FLOAT_ON_PARENT))
  617.     {
  618.         wxWindow*                   pParent = GetParent();
  619.  
  620.         if (pParent)
  621.         {
  622.             ::WinSetWindowPos( GetHwndOf(pParent)
  623.                               ,HWND_TOP
  624.                               ,0, 0, 0, 0
  625.                               ,SWP_ZORDER
  626.                              );
  627.         }
  628.     }
  629.  
  630.     //
  631.     // If this is the last top-level window, we're going to exit and we should
  632.     // delete ms_hiddenParent now to avoid leaking it
  633.     //
  634.     if (IsLastBeforeExit())
  635.     {
  636.         if (m_spHiddenParent)
  637.         {
  638.             delete m_spHiddenParent;
  639.             m_spHiddenParent = NULL;
  640.         }
  641.     }
  642. } // end of wxTopLevelWindowOS2::~wxTopLevelWindowOS2
  643.  
  644. // ----------------------------------------------------------------------------
  645. // wxTopLevelWindowOS2 client size
  646. // ----------------------------------------------------------------------------
  647.  
  648. void wxTopLevelWindowOS2::DoSetClientSize(
  649.   int                               nWidth
  650. , int                               nHeight
  651. )
  652. {
  653.     //
  654.     // Call GetClientAreaOrigin() to take the toolbar into account
  655.     //
  656.     wxPoint                         vPt = GetClientAreaOrigin();
  657.  
  658.     nWidth  += vPt.x;
  659.     nHeight += vPt.y;
  660.  
  661.     wxWindow::DoSetClientSize( nWidth
  662.                               ,nHeight
  663.                              );
  664. } // end of wxTopLevelWindowOS2::DoSetClientSize
  665.  
  666. void wxTopLevelWindowOS2::DoGetClientSize(
  667.   int*                              pnX
  668. , int*                              pnY
  669. ) const
  670. {
  671.     wxWindow::DoGetClientSize( pnX
  672.                               ,pnY
  673.                              );
  674.  
  675.     wxPoint                         vPt = GetClientAreaOrigin();
  676.  
  677.     if (pnX)
  678.         *pnX -= vPt.x;
  679.  
  680.     if (pnY)
  681.         *pnY += vPt.y;
  682. } // end of wxTopLevelWindowOS2::DoGetClientSize
  683.  
  684. // ----------------------------------------------------------------------------
  685. // wxTopLevelWindowOS2 showing
  686. // ----------------------------------------------------------------------------
  687.  
  688. void wxTopLevelWindowOS2::DoShowWindow(
  689.   int                               nShowCmd
  690. )
  691. {
  692.     ::WinShowWindow(m_hFrame, (BOOL)(nShowCmd & SWP_SHOW));
  693.  
  694.     //
  695.     // Need to artificially send a size event as wxApps often expect to do some
  696.     // final child control sizing
  697.     SendSizeEvent();
  698.     m_bIconized = nShowCmd == SWP_MINIMIZE;
  699. } // end of wxTopLevelWindowOS2::DoShowWindow
  700.  
  701. bool wxTopLevelWindowOS2::Show(
  702.   bool                              bShow
  703. )
  704. {
  705.     int                             nShowCmd;
  706.     SWP                             vSwp;
  707.     RECTL                           vRect;
  708.  
  709.     if (bShow)
  710.     {
  711.         if (m_bMaximizeOnShow)
  712.         {
  713.             nShowCmd = SWP_MAXIMIZE;
  714.             m_bMaximizeOnShow = FALSE;
  715.         }
  716.         else
  717.         {
  718.             nShowCmd = SWP_SHOW;
  719.         }
  720.     }
  721.     else // hide
  722.     {
  723.         nShowCmd = SWP_HIDE;
  724.     }
  725.     DoShowWindow(nShowCmd);
  726.  
  727.     if (bShow)
  728.     {
  729.         wxActivateEvent             vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
  730.  
  731.         ::WinQueryWindowPos(m_hFrame, &vSwp);
  732.         m_bIconized = vSwp.fl & SWP_MINIMIZE;
  733.         ::WinQueryWindowPos(m_hWnd, &m_vSwpClient);
  734.         ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
  735.         ::WinQueryWindowPos(m_hWnd, &vSwp);
  736.         ::WinEnableWindow(m_hFrame, TRUE);
  737.  
  738.         //
  739.         // Deal with children
  740.         //
  741.         MoveChildren(m_vSwpClient.cy - vSwp.cy);
  742.         vEvent.SetEventObject(this);
  743.         GetEventHandler()->ProcessEvent(vEvent);
  744.     }
  745.     else
  746.     {
  747.         //
  748.         // Try to highlight the correct window (the parent)
  749.         //
  750.         if (GetParent())
  751.         {
  752.             HWND                    hWndParent = GetHwndOf(GetParent());
  753.  
  754.             ::WinQueryWindowPos(hWndParent, &vSwp);
  755.             m_bIconized = vSwp.fl & SWP_MINIMIZE;
  756.             ::WinEnableWindow(hWndParent, TRUE);
  757.         }
  758.     }
  759.     return TRUE;
  760. } // end of wxTopLevelWindowOS2::Show
  761.  
  762. // ----------------------------------------------------------------------------
  763. // wxTopLevelWindowOS2 maximize/minimize
  764. // ----------------------------------------------------------------------------
  765.  
  766. void wxTopLevelWindowOS2::Maximize(
  767.   bool                              bMaximize
  768. )
  769. {
  770.     if (IsShown())
  771.     {
  772.         //
  773.         // Just maximize it directly
  774.         //
  775.         DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
  776.     }
  777.     else // hidden
  778.     {
  779.         //
  780.         // We can't maximize the hidden frame because it shows it as well, so
  781.         // just remember that we should do it later in this case
  782.         //
  783.         m_bMaximizeOnShow = TRUE;
  784.     }
  785. } // end of wxTopLevelWindowOS2::Maximize
  786.  
  787. bool wxTopLevelWindowOS2::IsMaximized() const
  788. {
  789.     bool                            bIconic;
  790.  
  791.     ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
  792.     return (m_vSwp.fl & SWP_MAXIMIZE);
  793. } // end of wxTopLevelWindowOS2::IsMaximized
  794.  
  795. void wxTopLevelWindowOS2::Iconize(
  796.   bool                              bIconize
  797. )
  798. {
  799.     DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
  800. } // end of wxTopLevelWindowOS2::Iconize
  801.  
  802. bool wxTopLevelWindowOS2::IsIconized() const
  803. {
  804.     // also update the current state
  805.     ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
  806.     if (m_vSwp.fl & SWP_MINIMIZE)
  807.         ((wxTopLevelWindow*)this)->m_bIconized = TRUE;
  808.     else
  809.         ((wxTopLevelWindow*)this)->m_bIconized = FALSE;
  810.     return m_bIconized;
  811. } // end of wxTopLevelWindowOS2::IsIconized
  812.  
  813. void wxTopLevelWindowOS2::Restore()
  814. {
  815.     DoShowWindow(SWP_RESTORE);
  816. } // end of wxTopLevelWindowOS2::Restore
  817.  
  818. // generate an artificial resize event
  819. void wxTopLevelWindowOS2::SendSizeEvent()
  820. {
  821.     if (!m_bIconized)
  822.     {
  823.         RECTL                       vRect = wxGetWindowRect(GetHwnd());
  824.  
  825.         (void)::WinPostMsg( m_hFrame
  826.                            ,WM_SIZE
  827.                            ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
  828.                            ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
  829.                           );
  830.     }
  831. } // end of wxTopLevelWindowOS2::SendSizeEvent
  832.  
  833. // ----------------------------------------------------------------------------
  834. // wxTopLevelWindowOS2 fullscreen
  835. // ----------------------------------------------------------------------------
  836.  
  837. bool wxTopLevelWindowOS2::ShowFullScreen(
  838.   bool                              bShow
  839. , long                              lStyle
  840. )
  841. {
  842.     if (bShow)
  843.     {
  844.         if (IsFullScreen())
  845.             return FALSE;
  846.  
  847.         m_bFsIsShowing = TRUE;
  848.         m_lFsStyle = lStyle;
  849.  
  850.         //
  851.         // Zap the frame borders
  852.         //
  853.  
  854.         //
  855.         // Save the 'normal' window lStyle
  856.         //
  857.         m_lFsOldWindowStyle = ::WinQueryWindowULong( (HWND)GetHWND()
  858.                                                     ,QWL_STYLE
  859.                                                    );
  860.  
  861.         //
  862.         // Save the old position, width & height, maximize state
  863.         //
  864.         m_vFsOldSize = GetRect();
  865.         m_bFsIsMaximized = IsMaximized();
  866.  
  867.         //
  868.         // Decide which window lStyle flags to turn off
  869.         //
  870.         LONG                        lNewStyle = m_lFsOldWindowStyle;
  871.         LONG                        lOffFlags = 0;
  872.  
  873.         if (lStyle & wxFULLSCREEN_NOBORDER)
  874.             lOffFlags |= FCF_BORDER;
  875.         if (lStyle & wxFULLSCREEN_NOCAPTION)
  876.             lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
  877.  
  878.         lNewStyle &= (~lOffFlags);
  879.  
  880.         //
  881.         // Change our window style to be compatible with full-screen mode
  882.         //
  883.         ::WinSetWindowULong( (HWND)GetHWND()
  884.                             ,QWL_STYLE
  885.                             ,lNewStyle
  886.                            );
  887.  
  888.         //
  889.         // Resize to the size of the desktop
  890.         //
  891.         int                         nWidth;
  892.         int                         nHeight;
  893.         RECTL                       vRect = wxGetWindowRect(HWND_DESKTOP);
  894.  
  895.         nWidth = vRect.xRight - vRect.xLeft;
  896.         nHeight = vRect.yTop - vRect.yBottom;
  897.  
  898.         SetSize( nWidth
  899.                 ,nHeight
  900.                );
  901.  
  902.         //
  903.         // Now flush the window style cache and actually go full-screen
  904.         //
  905.         ::WinSetWindowPos( m_hFrame
  906.                           ,HWND_TOP
  907.                           ,0
  908.                           ,0
  909.                           ,nWidth
  910.                           ,nHeight
  911.                           ,SWP_SIZE | SWP_MOVE
  912.                          );
  913.  
  914.         wxSizeEvent                 vEvent( wxSize( nWidth
  915.                                                    ,nHeight
  916.                                                   )
  917.                                            ,GetId()
  918.                                           );
  919.  
  920.         GetEventHandler()->ProcessEvent(vEvent);
  921.         return TRUE;
  922.     }
  923.     else
  924.     {
  925.         if (!IsFullScreen())
  926.             return FALSE;
  927.  
  928.         m_bFsIsShowing = FALSE;
  929.         Maximize(m_bFsIsMaximized);
  930.         ::WinSetWindowULong( (HWND)GetHWND()
  931.                             ,QWL_STYLE
  932.                             ,m_lFsOldWindowStyle
  933.                            );
  934.         ::WinSetWindowPos( m_hFrame
  935.                           ,HWND_TOP
  936.                           ,m_vFsOldSize.x
  937.                           ,m_vFsOldSize.y
  938.                           ,m_vFsOldSize.width
  939.                           ,m_vFsOldSize.height
  940.                           ,SWP_SIZE | SWP_MOVE
  941.                          );
  942.         return TRUE;
  943.     }
  944. } // end of wxTopLevelWindowOS2::ShowFullScreen
  945.  
  946. // ----------------------------------------------------------------------------
  947. // wxTopLevelWindowOS2 misc
  948. // ----------------------------------------------------------------------------
  949.  
  950. void wxTopLevelWindowOS2::SetIcon(
  951.   const wxIcon&                     rIcon
  952. )
  953. {
  954.     SetIcons(wxIconBundle(rIcon));
  955. } // end of wxTopLevelWindowOS2::SetIcon
  956.  
  957. void wxTopLevelWindowOS2::SetIcons(
  958.   const wxIconBundle&               rIcons
  959. )
  960. {
  961.     //
  962.     // This sets m_icon
  963.     //
  964.     wxTopLevelWindowBase::SetIcons(rIcons);
  965.  
  966.     const wxIcon&                   vIcon = rIcons.GetIcon(wxSize(32, 32));
  967.  
  968.     if (vIcon.Ok() && vIcon.GetWidth() == 32 && vIcon.GetHeight() == 32)
  969.     {
  970.         ::WinSendMsg( m_hFrame
  971.                      ,WM_SETICON
  972.                      ,(MPARAM)((HPOINTER)vIcon.GetHICON())
  973.                      ,NULL
  974.                     );
  975.         ::WinSendMsg( m_hFrame
  976.                      ,WM_UPDATEFRAME
  977.                      ,(MPARAM)FCF_ICON
  978.                      ,(MPARAM)0
  979.                     );
  980.     }
  981. } // end of wxTopLevelWindowOS2::SetIcon
  982.  
  983. bool wxTopLevelWindowOS2::EnableCloseButton(
  984.   bool                              bEnable
  985. )
  986. {
  987.     //
  988.     // Get system (a.k.a. window) menu
  989.     //
  990.     HMENU                           hMenu = ::WinWindowFromID(m_hFrame, FID_SYSMENU);
  991.  
  992.     if (!hMenu)
  993.     {
  994.         wxLogLastError(_T("GetSystemMenu"));
  995.         return FALSE;
  996.     }
  997.  
  998.     //
  999.     // Enabling/disabling the close item from it also automatically
  1000.     // disables/enables the close title bar button
  1001.     //
  1002.     if (bEnable)
  1003.         (void)::WinSendMsg( hMenu
  1004.                            ,MM_SETITEMATTR
  1005.                            ,MPFROM2SHORT(SC_CLOSE, FALSE)
  1006.                            ,MPFROM2SHORT(MIA_DISABLED, FALSE)
  1007.                           );
  1008.     else
  1009.         (void)::WinSendMsg( hMenu
  1010.                            ,MM_SETITEMATTR
  1011.                            ,MPFROM2SHORT(SC_CLOSE, FALSE)
  1012.                            ,MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)
  1013.                           );
  1014.  
  1015.     //
  1016.     // Update appearance immediately
  1017.     //
  1018.     ::WinSendMsg( m_hFrame
  1019.                  ,WM_UPDATEFRAME
  1020.                  ,(MPARAM)FCF_MENU
  1021.                  ,(MPARAM)0
  1022.                 );
  1023.     return TRUE;
  1024. } // end of wxTopLevelWindowOS2::EnableCloseButton
  1025.  
  1026.