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 / notebook.cpp < prev    next >
C/C++ Source or Header  |  2002-09-08  |  28KB  |  947 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name:        notebook.cpp
  3. // Purpose:     implementation of wxNotebook
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/12/99
  7. // RCS-ID:      $Id: NOTEBOOK.CPP,v 1.12 2002/09/08 10:51:49 SN Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. // For compilers that support precompilation, includes "wx.h".
  13. #include "wx/wxprec.h"
  14.  
  15. #if wxUSE_NOTEBOOK
  16.  
  17. // wxWindows
  18. #ifndef WX_PRECOMP
  19.   #include "wx/app.h"
  20.   #include "wx/string.h"
  21.   #include "wx/settings.h"
  22. #endif  // WX_PRECOMP
  23.  
  24. #include  "wx/log.h"
  25. #include  "wx/imaglist.h"
  26. #include  "wx/event.h"
  27. #include  "wx/control.h"
  28. #include  "wx/notebook.h"
  29.  
  30. #include  "wx/os2/private.h"
  31.  
  32. // ----------------------------------------------------------------------------
  33. // macros
  34. // ----------------------------------------------------------------------------
  35.  
  36. // check that the page index is valid
  37. #define IS_VALID_PAGE(nPage) (((nPage) >= 0) && ((nPage) < GetPageCount()))
  38.  
  39. // hide the ugly cast
  40. #define m_hWnd    (HWND)GetHWND()
  41.  
  42. // ----------------------------------------------------------------------------
  43. // constants
  44. // ----------------------------------------------------------------------------
  45.  
  46. // ----------------------------------------------------------------------------
  47. // event table
  48. // ----------------------------------------------------------------------------
  49.  
  50. DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
  51. DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
  52.  
  53. BEGIN_EVENT_TABLE(wxNotebook, wxControl)
  54.     EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
  55.     EVT_SIZE(wxNotebook::OnSize)
  56.     EVT_SET_FOCUS(wxNotebook::OnSetFocus)
  57.     EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
  58. END_EVENT_TABLE()
  59.  
  60. IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
  61. IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
  62.  
  63. // ============================================================================
  64. // implementation
  65. // ============================================================================
  66.  
  67. // ----------------------------------------------------------------------------
  68. // wxNotebook construction
  69. // ----------------------------------------------------------------------------
  70.  
  71. //
  72. // Common part of all ctors
  73. //
  74. void wxNotebook::Init()
  75. {
  76.     m_imageList  = NULL;
  77.     m_nSelection = -1;
  78.     m_nTabSize   = 0;
  79. } // end of wxNotebook::Init
  80.  
  81. //
  82. // Default for dynamic class
  83. //
  84. wxNotebook::wxNotebook()
  85. {
  86.     Init();
  87. } // end of wxNotebook::wxNotebook
  88.  
  89. //
  90. // The same arguments as for wxControl
  91. //
  92. wxNotebook::wxNotebook(
  93.   wxWindow*                         pParent
  94. , wxWindowID                        vId
  95. , const wxPoint&                    rPos
  96. , const wxSize&                     rSize
  97. , long                              lStyle
  98. , const wxString&                   rsName
  99. )
  100. {
  101.     Init();
  102.     Create( pParent
  103.            ,vId
  104.            ,rPos
  105.            ,rSize
  106.            ,lStyle
  107.            ,rsName
  108.           );
  109. } // end of wxNotebook::wxNotebook
  110.  
  111. //
  112. // Create() function
  113. //
  114. bool wxNotebook::Create(
  115.   wxWindow*                         pParent
  116. , wxWindowID                        vId
  117. , const wxPoint&                    rPos
  118. , const wxSize&                     rSize
  119. , long                              lStyle
  120. , const wxString&                   rsName
  121. )
  122. {
  123.     //
  124.     // Base init
  125.     //
  126.     if (!CreateControl( pParent
  127.                        ,vId
  128.                        ,rPos
  129.                        ,rSize
  130.                        ,lStyle
  131.                        ,wxDefaultValidator
  132.                        ,rsName
  133.                       ))
  134.         return FALSE;
  135.  
  136.     //
  137.     // Notebook, so explicitly specify 0 as last parameter
  138.     //
  139.     if (!OS2CreateControl( "NOTEBOOK"
  140.                           ,_T("")
  141.                           ,rPos
  142.                           ,rSize
  143.                           ,lStyle | wxTAB_TRAVERSAL
  144.                          ))
  145.         return FALSE;
  146.  
  147.     SetBackgroundColour(wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
  148.     return TRUE;
  149. } // end of wxNotebook::Create
  150.  
  151. WXDWORD wxNotebook::OS2GetStyle (
  152.   long                              lStyle
  153. , WXDWORD*                          pdwExstyle
  154. ) const
  155. {
  156.     WXDWORD                         dwTabStyle = wxControl::OS2GetStyle( lStyle
  157.                                                                         ,pdwExstyle
  158.                                                                        );
  159.  
  160.     dwTabStyle |= WS_TABSTOP | BKS_SOLIDBIND | BKS_ROUNDEDTABS | BKS_TABTEXTCENTER;
  161.  
  162.     if (lStyle & wxNB_BOTTOM)
  163.         dwTabStyle |= BKS_MAJORTABBOTTOM | BKS_BACKPAGESBL;
  164.     else if (lStyle & wxNB_RIGHT)
  165.         dwTabStyle |= BKS_MAJORTABRIGHT | BKS_BACKPAGESBR;
  166.     else if (lStyle & wxNB_LEFT)
  167.         dwTabStyle |= BKS_MAJORTABLEFT | BKS_BACKPAGESTL;
  168.     else // default to top
  169.         dwTabStyle |= BKS_MAJORTABTOP | BKS_BACKPAGESTR;
  170.  
  171.     //
  172.     // Ex style
  173.     //
  174.     if (pdwExstyle )
  175.     {
  176.         //
  177.         // Note that we never want to have the default WS_EX_CLIENTEDGE style
  178.         // as it looks too ugly for the notebooks
  179.         //
  180.         *pdwExstyle = 0;
  181.     }
  182.     return dwTabStyle;
  183. } // end of wxNotebook::OS2GetStyle
  184.  
  185. // ----------------------------------------------------------------------------
  186. // wxNotebook accessors
  187. // ----------------------------------------------------------------------------
  188.  
  189. int wxNotebook::GetPageCount() const
  190. {
  191.     int                             nPageInternal = m_pages.Count();
  192.     int                             nPageAPI = (int)::WinSendMsg(GetHWND(), BKM_QUERYPAGECOUNT, (MPARAM)0, (MPARAM)BKA_END);
  193.  
  194.     //
  195.     // Consistency check
  196.     //
  197.     wxASSERT((int)m_pages.Count() == (int)::WinSendMsg(GetHWND(), BKM_QUERYPAGECOUNT, (MPARAM)0, (MPARAM)BKA_END));
  198.     return m_pages.Count();
  199. } // end of wxNotebook::GetPageCount
  200.  
  201. int wxNotebook::GetRowCount() const
  202. {
  203.     return (int)::WinSendMsg( GetHWND()
  204.                              ,BKM_QUERYPAGECOUNT
  205.                              ,(MPARAM)0
  206.                              ,(MPARAM)BKA_MAJOR
  207.                             );
  208. } // end of wxNotebook::GetRowCount
  209.  
  210. int wxNotebook::SetSelection(
  211.   int                               nPage
  212. )
  213. {
  214.     wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
  215.     int                             nOldPage = GetSelection();
  216.  
  217.     ChangePage( m_nSelection
  218.                ,nPage
  219.               );
  220.  
  221.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  222.  
  223.     ::WinSendMsg( GetHWND()
  224.                  ,BKM_TURNTOPAGE
  225.                  ,MPFROMLONG((ULONG)m_alPageId[nPage])
  226.                  ,(MPARAM)0
  227.                 );
  228.     m_nSelection = nPage;
  229.     return nPage;
  230. } // end of wxNotebook::SetSelection
  231.  
  232. bool wxNotebook::SetPageText(
  233.   int                               nPage
  234. , const wxString&                   rsStrText
  235. )
  236. {
  237.     wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
  238.  
  239.  
  240.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  241.  
  242.     return (bool)::WinSendMsg( m_hWnd
  243.                               ,BKM_SETTABTEXT
  244.                               ,MPFROMLONG((ULONG)m_alPageId[nPage])
  245.                               ,MPFROMP((PSZ)rsStrText.c_str())
  246.                              );
  247. } // end of wxNotebook::SetPageText
  248.  
  249. wxString wxNotebook::GetPageText (
  250.   int                               nPage
  251. ) const
  252. {
  253.     BOOKTEXT                        vBookText;
  254.     wxChar                          zBuf[256];
  255.     wxString                        sStr;
  256.     ULONG                           ulRc;
  257.  
  258.     wxCHECK_MSG( IS_VALID_PAGE(nPage), wxT(""), wxT("notebook page out of range") );
  259.  
  260.  
  261.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  262.  
  263.     memset(&vBookText, '\0', sizeof(BOOKTEXT));
  264.     vBookText.textLen = 0; // This will get the length
  265.     ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
  266.                                    ,BKM_QUERYTABTEXT
  267.                                    ,MPFROMLONG((ULONG)m_alPageId[nPage])
  268.                                    ,MPFROMP(&vBookText)
  269.                                   ));
  270.     if (ulRc == BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
  271.     {
  272.         if (ulRc == BOOKERR_INVALID_PARAMETERS)
  273.         {
  274.             wxLogError(wxT("Invalid Page Id for page text querry."));
  275.         }
  276.         return wxEmptyString;
  277.     }
  278.     vBookText.textLen = ulRc + 1; // To get the null terminator
  279.     vBookText.pString = zBuf;
  280.  
  281.     //
  282.     // Now get the actual text
  283.     //
  284.     ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
  285.                                    ,BKM_QUERYTABTEXT
  286.                                    ,MPFROMLONG((ULONG)m_alPageId[nPage])
  287.                                    ,MPFROMP(&vBookText)
  288.                                   ));
  289.     if (ulRc == BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
  290.     {
  291.         return wxEmptyString;
  292.     }
  293.     if (ulRc > 255L)
  294.         ulRc = 255L;
  295.  
  296.     vBookText.pString[ulRc] = '\0';
  297.     sStr = vBookText.pString;
  298.     return sStr;
  299. } // end of wxNotebook::GetPageText
  300.  
  301. int wxNotebook::GetPageImage (
  302.   int                               nPage
  303. ) const
  304. {
  305.     wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
  306.  
  307.     //
  308.     // For OS/2 just return the page
  309.     //
  310.     return nPage;
  311. } // end of wxNotebook::GetPageImage
  312.  
  313. bool wxNotebook::SetPageImage (
  314.   int                               nPage
  315. , int                               nImage
  316. )
  317. {
  318.     wxBitmap*                       pBitmap = (wxBitmap*)m_imageList->GetBitmap(nImage);
  319.  
  320.  
  321.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  322.  
  323.     return (bool)::WinSendMsg( GetHWND()
  324.                               ,BKM_SETTABBITMAP
  325.                               ,MPFROMLONG((ULONG)m_alPageId[nPage])
  326.                               ,(MPARAM)pBitmap->GetHBITMAP()
  327.                              );
  328. } // end of wxNotebook::SetPageImage
  329.  
  330. void wxNotebook::SetImageList (
  331.   wxImageList*                      WXUNUSED(pImageList)
  332. )
  333. {
  334.     //
  335.     // Does nothing under OS/2
  336.     //
  337. } // end of wxNotebook::SetImageList
  338.  
  339. // ----------------------------------------------------------------------------
  340. // wxNotebook size settings
  341. // ----------------------------------------------------------------------------
  342. void wxNotebook::SetPageSize (
  343.   const wxSize&                     rSize
  344. )
  345. {
  346.     RECTL                           vRect;
  347.  
  348.     //
  349.     // Transform the page size into the notebook size
  350.     //
  351.     vRect.xLeft   = vRect.yTop = 0;
  352.     vRect.xRight  = rSize.x;
  353.     vRect.yBottom = rSize.y;
  354.  
  355.  
  356.     //
  357.     // And now set it
  358.     //
  359.     SetSize( vRect.xRight - vRect.xLeft
  360.             ,vRect.yBottom - vRect.yTop
  361.            );
  362. } // end of wxNotebook::SetPageSize
  363.  
  364. void wxNotebook::SetPadding (
  365.   const wxSize&                     WXUNUSED(rPadding)
  366. )
  367. {
  368.     //
  369.     // No padding in OS/2
  370.     //
  371. } // end of wxNotebook::SetPadding
  372.  
  373. void wxNotebook::SetTabSize (
  374.   const wxSize&                     rSize
  375. )
  376. {
  377.     ::WinSendMsg( GetHWND()
  378.                  ,BKM_SETDIMENSIONS
  379.                  ,MPFROM2SHORT( (USHORT)rSize.x
  380.                                ,(USHORT)rSize.y
  381.                               )
  382.                  ,(MPARAM)BKA_MAJORTAB
  383.                 );
  384. } // end of wxNotebook::SetTabSize
  385.  
  386. // ----------------------------------------------------------------------------
  387. // wxNotebook operations
  388. // ----------------------------------------------------------------------------
  389.  
  390. //
  391. // Remove one page from the notebook, without deleting
  392. //
  393. wxNotebookPage* wxNotebook::DoRemovePage (
  394.   int                               nPage
  395. )
  396. {
  397.     wxNotebookPage*                 pPageRemoved = wxNotebookBase::DoRemovePage(nPage);
  398.  
  399.     if (!pPageRemoved)
  400.         return NULL;
  401.  
  402.  
  403.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  404.  
  405.     ::WinSendMsg( GetHWND()
  406.                  ,BKM_DELETEPAGE
  407.                  ,MPFROMLONG((ULONG)m_alPageId[nPage])
  408.                  ,(MPARAM)BKA_TAB
  409.                 );
  410.     if (m_pages.IsEmpty())
  411.     {
  412.         //
  413.         // No selection any more, the notebook becamse empty
  414.         //
  415.         m_nSelection = -1;
  416.     }
  417.     else // notebook still not empty
  418.     {
  419.         //
  420.         // Change the selected page if it was deleted or became invalid
  421.         //
  422.         int                         nSelNew;
  423.  
  424.         if (m_nSelection == GetPageCount())
  425.         {
  426.             //
  427.             // Last page deleted, make the new last page the new selection
  428.             //
  429.             nSelNew = m_nSelection - 1;
  430.         }
  431.         else if (nPage <= m_nSelection)
  432.         {
  433.             //
  434.             // We must show another page, even if it has the same index
  435.             //
  436.             nSelNew = m_nSelection;
  437.         }
  438.         else // nothing changes for the currently selected page
  439.         {
  440.             nSelNew = -1;
  441.  
  442.             //
  443.             // We still must refresh the current page: this needs to be done
  444.             // for some unknown reason if the tab control shows the up-down
  445.             // control (i.e. when there are too many pages) -- otherwise after
  446.             // deleting a page nothing at all is shown
  447.             //
  448.             m_pages[m_nSelection]->Refresh();
  449.         }
  450.  
  451.         if (nSelNew != -1)
  452.         {
  453.             //
  454.             // m_nSelection must be always valid so reset it before calling
  455.             // SetSelection()
  456.             //
  457.             m_nSelection = -1;
  458.             SetSelection(nSelNew);
  459.         }
  460.     }
  461.     return pPageRemoved;
  462. } // end of wxNotebook::DoRemovePage
  463.  
  464. //
  465. // Remove all pages
  466. //
  467. bool wxNotebook::DeleteAllPages()
  468. {
  469.     int                             nPageCount = GetPageCount();
  470.     int                             nPage;
  471.  
  472.     for (nPage = 0; nPage < nPageCount; nPage++)
  473.         delete m_pages[nPage];
  474.     m_pages.Clear();
  475.     ::WinSendMsg( GetHWND()
  476.                  ,BKM_DELETEPAGE
  477.                  ,(MPARAM)0
  478.                  ,(MPARAM)BKA_ALL
  479.                 );
  480.     m_nSelection = -1;
  481.     return TRUE;
  482. } // end of wxNotebook::DeleteAllPages
  483.  
  484. //
  485. // Add a page to the notebook
  486. //
  487. bool wxNotebook::AddPage (
  488.   wxNotebookPage*                   pPage
  489. , const wxString&                   rStrText
  490. , bool                              bSelect
  491. , int                               nImageId
  492. )
  493. {
  494.     return InsertPage( GetPageCount()
  495.                       ,pPage
  496.                       ,rStrText
  497.                       ,bSelect
  498.                       ,nImageId
  499.                      );
  500. } // end of wxNotebook::AddPage
  501.  
  502. //
  503. // Same as AddPage() but does it at given position
  504. //
  505. bool wxNotebook::InsertPage (
  506.   int                               nPage
  507. , wxNotebookPage*                   pPage
  508. , const wxString&                   rsStrText
  509. , bool                              bSelect
  510. , int                               nImageId
  511. )
  512. {
  513.     ULONG                           ulApiPage;
  514.  
  515.     wxASSERT( pPage != NULL );
  516.     wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE );
  517.  
  518.     //
  519.     // Under OS/2 we can only insert FIRST, LAST, NEXT or PREV.  Requires
  520.     // two different calls to the API.  Page 1 uses the BKA_FIRST.  Subsequent
  521.     // pages use the previous page ID coupled with a BKA_NEXT call.  Unlike
  522.     // Windows, OS/2 uses an internal Page ID to ID the pages.
  523.     //
  524.     // OS/2 also has a nice auto-size feature that automatically sizes the
  525.     // the attached window so we don't have to worry about the size of the
  526.     // window on the page.
  527.     //
  528.     if (nPage == 0)
  529.     {
  530.         ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
  531.                                             ,BKM_INSERTPAGE
  532.                                             ,(MPARAM)0
  533.                                             ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_FIRST)
  534.                                            ));
  535.         if (ulApiPage == 0L)
  536.         {
  537.             ERRORID                 vError;
  538.             wxString                sError;
  539.  
  540.             vError = ::WinGetLastError(vHabmain);
  541.             sError = wxPMErrorToStr(vError);
  542.             return FALSE;
  543.         }
  544.         m_alPageId.Insert((long)ulApiPage, nPage);
  545.     }
  546.     else
  547.     {
  548.         ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
  549.                                             ,BKM_INSERTPAGE
  550.                                             ,MPFROMLONG((ULONG)m_alPageId[nPage - 1])
  551.                                             ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_NEXT)
  552.                                            ));
  553.         if (ulApiPage == 0L)
  554.         {
  555.             ERRORID                     vError;
  556.             wxString                    sError;
  557.  
  558.             vError = ::WinGetLastError(vHabmain);
  559.             sError = wxPMErrorToStr(vError);
  560.             return FALSE;
  561.         }
  562.         m_alPageId.Insert((long)ulApiPage, nPage);
  563.     }
  564.  
  565.     //
  566.     // Associate a window handle with the page
  567.     //
  568.     if (pPage)
  569.     {
  570.         if (!::WinSendMsg( GetHWND()
  571.                           ,BKM_SETPAGEWINDOWHWND
  572.                           ,MPFROMLONG((ULONG)m_alPageId[nPage])
  573.                           ,MPFROMHWND(pPage->GetHWND())
  574.                          ))
  575.             return FALSE;
  576.     }
  577.     //
  578.     // If the inserted page is before the selected one, we must update the
  579.     // index of the selected page
  580.     //
  581.     if (nPage <= m_nSelection)
  582.     {
  583.         //
  584.         // One extra page added
  585.         //
  586.         m_nSelection++;
  587.     }
  588.  
  589.     if (pPage)
  590.     {
  591.         //
  592.         // Save the pointer to the page
  593.         //
  594.         m_pages.Insert( pPage
  595.                        ,nPage
  596.                       );
  597.     }
  598.  
  599.     //
  600.     // Now set TAB dimenstions
  601.     //
  602.  
  603.     wxWindowDC                      vDC(this);
  604.     wxCoord                         nTextX;
  605.     wxCoord                         nTextY;
  606.  
  607.     vDC.GetTextExtent(rsStrText, &nTextX, &nTextY);
  608.     nTextY *= 2;
  609.     nTextX *= 1.3;
  610.     if (nTextX > m_nTabSize)
  611.     {
  612.         m_nTabSize = nTextX;
  613.         ::WinSendMsg( GetHWND()
  614.                      ,BKM_SETDIMENSIONS
  615.                      ,MPFROM2SHORT((USHORT)m_nTabSize, (USHORT)nTextY)
  616.                      ,(MPARAM)BKA_MAJORTAB
  617.                     );
  618.     }
  619.     //
  620.     // Now set any TAB text
  621.     //
  622.     if (!rsStrText.IsEmpty())
  623.     {
  624.         if (!SetPageText( nPage
  625.                          ,rsStrText
  626.                         ))
  627.             return FALSE;
  628.     }
  629.  
  630.     //
  631.     // Now set any TAB bitmap image
  632.     //
  633.     if (nImageId != -1)
  634.     {
  635.         if (!SetPageImage( nPage
  636.                           ,nImageId
  637.                          ))
  638.             return FALSE;
  639.     }
  640.  
  641.     if (pPage)
  642.     {
  643.         //
  644.         // Don't show pages by default (we'll need to adjust their size first)
  645.         //
  646.         HWND                        hWnd = GetWinHwnd(pPage);
  647.  
  648.         WinSetWindowULong( hWnd
  649.                           ,QWL_STYLE
  650.                           ,WinQueryWindowULong( hWnd
  651.                                                ,QWL_STYLE
  652.                                               ) & ~WS_VISIBLE
  653.                          );
  654.  
  655.         //
  656.         // This updates internal flag too - otherwise it will get out of sync
  657.         //
  658.         pPage->Show(FALSE);
  659.     }
  660.  
  661.     //
  662.     // Some page should be selected: either this one or the first one if there is
  663.     // still no selection
  664.     //
  665.     int                             nSelNew = -1;
  666.  
  667.     if (bSelect)
  668.         nSelNew = nPage;
  669.     else if ( m_nSelection == -1 )
  670.         nSelNew = 0;
  671.  
  672.     if (nSelNew != -1)
  673.         SetSelection(nSelNew);
  674.     return TRUE;
  675. } // end of wxNotebook::InsertPage
  676.  
  677. // ----------------------------------------------------------------------------
  678. // wxNotebook callbacks
  679. // ----------------------------------------------------------------------------
  680. void wxNotebook::OnSize(
  681.   wxSizeEvent&                      rEvent
  682. )
  683. {
  684.     int                             nPage;
  685.     int                             nCount = (int)m_pages.Count();
  686.  
  687.     for (nPage = 0; nPage < nCount; nPage++)
  688.     {
  689.         if (m_nSelection == nPage)
  690.             m_pages[nPage]->Refresh();
  691.         else
  692.             ::WinSetWindowPos(m_pages[nPage]->GetHWND()
  693.                               ,NULLHANDLE
  694.                               ,0,0,0,0
  695.                               ,SWP_HIDE
  696.                              );
  697.     }
  698.     rEvent.Skip();
  699. } // end of wxNotebook::OnSize
  700.  
  701. void wxNotebook::OnSelChange (
  702.   wxNotebookEvent&                  rEvent
  703. )
  704. {
  705.     //
  706.     // Is it our tab control?
  707.     //
  708.     if (rEvent.GetEventObject() == this)
  709.     {
  710.         int                         nPageCount = GetPageCount();
  711.         int                         nSel;
  712.         ULONG                       ulOS2Sel = (ULONG)rEvent.GetOldSelection();
  713.         bool                        bFound = FALSE;
  714.  
  715.         for (nSel = 0; nSel < nPageCount; nSel++)
  716.         {
  717.             if (ulOS2Sel == m_alPageId[nSel])
  718.             {
  719.                 bFound = TRUE;
  720.                 break;
  721.             }
  722.         }
  723.  
  724.         if (!bFound)
  725.             return;
  726.  
  727.         m_pages[nSel]->Show(FALSE);
  728.  
  729.         ulOS2Sel = (ULONG)rEvent.GetSelection();
  730.  
  731.         bFound = FALSE;
  732.  
  733.         for (nSel = 0; nSel < nPageCount; nSel++)
  734.         {
  735.             if (ulOS2Sel == m_alPageId[nSel])
  736.             {
  737.                 bFound = TRUE;
  738.                 break;
  739.             }
  740.         }
  741.  
  742.         if (!bFound)
  743.             return;
  744.  
  745.         wxNotebookPage*         pPage = m_pages[nSel];
  746.  
  747.         pPage->Show(TRUE);
  748.         m_nSelection = nSel;
  749.     }
  750.  
  751.     //
  752.     // We want to give others a chance to process this message as well
  753.     //
  754.     rEvent.Skip();
  755. } // end of wxNotebook::OnSelChange
  756.  
  757. void wxNotebook::OnSetFocus (
  758.   wxFocusEvent&                     rEvent
  759. )
  760. {
  761.     //
  762.     // This function is only called when the focus is explicitly set (i.e. from
  763.     // the program) to the notebook - in this case we don't need the
  764.     // complicated OnNavigationKey() logic because the programmer knows better
  765.     // what [s]he wants
  766.     //
  767.     // set focus to the currently selected page if any
  768.     //
  769.     if (m_nSelection != -1)
  770.         m_pages[m_nSelection]->SetFocus();
  771.     rEvent.Skip();
  772. } // end of wxNotebook::OnSetFocus
  773.  
  774. void wxNotebook::OnNavigationKey (
  775.   wxNavigationKeyEvent&             rEvent
  776. )
  777. {
  778.     if (rEvent.IsWindowChange())
  779.     {
  780.         //
  781.         // Change pages
  782.         //
  783.         AdvanceSelection(rEvent.GetDirection());
  784.     }
  785.     else
  786.     {
  787.         //
  788.         // We get this event in 2 cases
  789.         //
  790.         // a) one of our pages might have generated it because the user TABbed
  791.         // out from it in which case we should propagate the event upwards and
  792.         // our parent will take care of setting the focus to prev/next sibling
  793.         //
  794.         // or
  795.         //
  796.         // b) the parent panel wants to give the focus to us so that we
  797.         // forward it to our selected page. We can't deal with this in
  798.         // OnSetFocus() because we don't know which direction the focus came
  799.         // from in this case and so can't choose between setting the focus to
  800.         // first or last panel child
  801.         //
  802.         wxWindow*                   pParent = GetParent();
  803.  
  804.         if (rEvent.GetEventObject() == pParent)
  805.         {
  806.             //
  807.             // No, it doesn't come from child, case (b): forward to a page
  808.             //
  809.             if (m_nSelection != -1)
  810.             {
  811.                 //
  812.                 // So that the page knows that the event comes from it's parent
  813.                 // and is being propagated downwards
  814.                 //
  815.                 rEvent.SetEventObject(this);
  816.  
  817.                 wxWindow*           pPage = m_pages[m_nSelection];
  818.  
  819.                 if (!pPage->GetEventHandler()->ProcessEvent(rEvent))
  820.                 {
  821.                     pPage->SetFocus();
  822.                 }
  823.                 //else: page manages focus inside it itself
  824.             }
  825.             else
  826.             {
  827.                 //
  828.                 // We have no pages - still have to give focus to _something_
  829.                 //
  830.                 SetFocus();
  831.             }
  832.         }
  833.         else
  834.         {
  835.             //
  836.             // It comes from our child, case (a), pass to the parent
  837.             //
  838.             if (pParent)
  839.             {
  840.                 rEvent.SetCurrentFocus(this);
  841.                 pParent->GetEventHandler()->ProcessEvent(rEvent);
  842.             }
  843.         }
  844.     }
  845. } // end of wxNotebook::OnNavigationKey
  846.  
  847. // ----------------------------------------------------------------------------
  848. // wxNotebook base class virtuals
  849. // ----------------------------------------------------------------------------
  850.  
  851. //
  852. // Override these 2 functions to do nothing: everything is done in OnSize
  853. //
  854. void wxNotebook::SetConstraintSizes(
  855.   bool                              WXUNUSED(bRecurse)
  856. )
  857. {
  858.     //
  859.     // Don't set the sizes of the pages - their correct size is not yet known
  860.     //
  861.     wxControl::SetConstraintSizes(FALSE);
  862. } // end of wxNotebook::SetConstraintSizes
  863.  
  864. bool wxNotebook::DoPhase (
  865.   int                               WXUNUSED(nPhase)
  866. )
  867. {
  868.     return TRUE;
  869. } // end of wxNotebook::DoPhase
  870.  
  871. // ----------------------------------------------------------------------------
  872. // wxNotebook Windows message handlers
  873. // ----------------------------------------------------------------------------
  874. bool wxNotebook::OS2OnScroll (
  875.   int                               nOrientation
  876. , WXWORD                            wSBCode
  877. , WXWORD                            wPos
  878. , WXHWND                            wControl
  879. )
  880. {
  881.     //
  882.     // Don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the
  883.     // up-down control
  884.     //
  885.     if (wControl)
  886.         return FALSE;
  887.     return wxNotebookBase::OS2OnScroll( nOrientation
  888.                                        ,wSBCode
  889.                                        ,wPos
  890.                                        ,wControl
  891.                                       );
  892. } // end of wxNotebook::OS2OnScroll
  893.  
  894. // ----------------------------------------------------------------------------
  895. // wxNotebook helper functions
  896. // ----------------------------------------------------------------------------
  897.  
  898. //
  899. // Generate the page changing and changed events, hide the currently active
  900. // panel and show the new one
  901. //
  902. void wxNotebook::ChangePage (
  903.   int                               nOldSel
  904. , int                               nSel
  905. )
  906. {
  907.     static bool                     sbInsideChangePage = FALSE;
  908.  
  909.     //
  910.     // When we call ProcessEvent(), our own OnSelChange() is called which calls
  911.     // this function - break the infinite loop
  912.     //
  913.     if (sbInsideChangePage)
  914.         return;
  915.  
  916.     //
  917.     // It's not an error (the message may be generated by the tab control itself)
  918.     // and it may happen - just do nothing
  919.     //
  920.     if (nSel == nOldSel)
  921.         return;
  922.  
  923.     sbInsideChangePage = TRUE;
  924.  
  925.     wxNotebookEvent                 rEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING
  926.                                            ,m_windowId
  927.                                           );
  928.  
  929.     rEvent.SetSelection(nSel);
  930.     rEvent.SetOldSelection(nOldSel);
  931.     rEvent.SetEventObject(this);
  932.     if (GetEventHandler()->ProcessEvent(rEvent) && !rEvent.IsAllowed())
  933.     {
  934.         //
  935.         // Program doesn't allow the page change
  936.         //
  937.         sbInsideChangePage = FALSE;
  938.         return;
  939.     }
  940.     rEvent.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
  941.     GetEventHandler()->ProcessEvent(rEvent);
  942.     sbInsideChangePage = FALSE;
  943. } // end of wxNotebook::ChangePage
  944.  
  945. #endif // wxUSE_NOTEBOOK
  946.  
  947.