home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / os2 / notebook.cpp < prev    next >
C/C++ Source or Header  |  2002-12-04  |  27KB  |  911 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.2.2 2002/12/02 14:05:20 DW 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.  
  216.     if (nPage != m_nSelection)
  217.     {
  218.         wxNotebookEvent             vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING
  219.                                            ,m_windowId
  220.                                           );
  221.  
  222.         vEvent.SetSelection(nPage);
  223.         vEvent.SetOldSelection(m_nSelection);
  224.         vEvent.SetEventObject(this);
  225.         if (!GetEventHandler()->ProcessEvent(vEvent) || vEvent.IsAllowed())
  226.         {
  227.  
  228.             //
  229.             // Program allows the page change
  230.             //
  231.             vEvent.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
  232.             GetEventHandler()->ProcessEvent(vEvent);
  233.  
  234.             ULONG                   ulPageId = (ULONG)m_alPageId[nPage];
  235.  
  236.             ::WinSendMsg( GetHWND()
  237.                          ,BKM_TURNTOPAGE
  238.                          ,MPFROMLONG((ULONG)m_alPageId[nPage])
  239.                          ,(MPARAM)0
  240.                         );
  241.         }
  242.     }
  243.     m_nSelection = nPage;
  244.     return nPage;
  245. } // end of wxNotebook::SetSelection
  246.  
  247. bool wxNotebook::SetPageText(
  248.   int                               nPage
  249. , const wxString&                   rsStrText
  250. )
  251. {
  252.     wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, wxT("notebook page out of range") );
  253.  
  254.  
  255.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  256.  
  257.     return (bool)::WinSendMsg( m_hWnd
  258.                               ,BKM_SETTABTEXT
  259.                               ,MPFROMLONG((ULONG)m_alPageId[nPage])
  260.                               ,MPFROMP((PSZ)rsStrText.c_str())
  261.                              );
  262. } // end of wxNotebook::SetPageText
  263.  
  264. wxString wxNotebook::GetPageText (
  265.   int                               nPage
  266. ) const
  267. {
  268.     BOOKTEXT                        vBookText;
  269.     wxChar                          zBuf[256];
  270.     wxString                        sStr;
  271.     ULONG                           ulRc;
  272.  
  273.     wxCHECK_MSG( IS_VALID_PAGE(nPage), wxT(""), wxT("notebook page out of range") );
  274.  
  275.  
  276.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  277.  
  278.     memset(&vBookText, '\0', sizeof(BOOKTEXT));
  279.     vBookText.textLen = 0; // This will get the length
  280.     ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
  281.                                    ,BKM_QUERYTABTEXT
  282.                                    ,MPFROMLONG((ULONG)m_alPageId[nPage])
  283.                                    ,MPFROMP(&vBookText)
  284.                                   ));
  285.     if (ulRc == BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
  286.     {
  287.         if (ulRc == BOOKERR_INVALID_PARAMETERS)
  288.         {
  289.             wxLogError(wxT("Invalid Page Id for page text querry."));
  290.         }
  291.         return wxEmptyString;
  292.     }
  293.     vBookText.textLen = ulRc + 1; // To get the null terminator
  294.     vBookText.pString = zBuf;
  295.  
  296.     //
  297.     // Now get the actual text
  298.     //
  299.     ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
  300.                                    ,BKM_QUERYTABTEXT
  301.                                    ,MPFROMLONG((ULONG)m_alPageId[nPage])
  302.                                    ,MPFROMP(&vBookText)
  303.                                   ));
  304.     if (ulRc == BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
  305.     {
  306.         return wxEmptyString;
  307.     }
  308.     if (ulRc > 255L)
  309.         ulRc = 255L;
  310.  
  311.     vBookText.pString[ulRc] = '\0';
  312.     sStr = vBookText.pString;
  313.     return sStr;
  314. } // end of wxNotebook::GetPageText
  315.  
  316. int wxNotebook::GetPageImage (
  317.   int                               nPage
  318. ) const
  319. {
  320.     wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
  321.  
  322.     //
  323.     // For OS/2 just return the page
  324.     //
  325.     return nPage;
  326. } // end of wxNotebook::GetPageImage
  327.  
  328. bool wxNotebook::SetPageImage (
  329.   int                               nPage
  330. , int                               nImage
  331. )
  332. {
  333.     wxBitmap*                       pBitmap = (wxBitmap*)m_imageList->GetBitmap(nImage);
  334.  
  335.  
  336.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  337.  
  338.     return (bool)::WinSendMsg( GetHWND()
  339.                               ,BKM_SETTABBITMAP
  340.                               ,MPFROMLONG((ULONG)m_alPageId[nPage])
  341.                               ,(MPARAM)pBitmap->GetHBITMAP()
  342.                              );
  343. } // end of wxNotebook::SetPageImage
  344.  
  345. void wxNotebook::SetImageList (
  346.   wxImageList*                      WXUNUSED(pImageList)
  347. )
  348. {
  349.     //
  350.     // Does nothing under OS/2
  351.     //
  352. } // end of wxNotebook::SetImageList
  353.  
  354. // ----------------------------------------------------------------------------
  355. // wxNotebook size settings
  356. // ----------------------------------------------------------------------------
  357. void wxNotebook::SetPageSize (
  358.   const wxSize&                     rSize
  359. )
  360. {
  361.     RECTL                           vRect;
  362.  
  363.     //
  364.     // Transform the page size into the notebook size
  365.     //
  366.     vRect.xLeft   = vRect.yTop = 0;
  367.     vRect.xRight  = rSize.x;
  368.     vRect.yBottom = rSize.y;
  369.  
  370.  
  371.     //
  372.     // And now set it
  373.     //
  374.     SetSize( vRect.xRight - vRect.xLeft
  375.             ,vRect.yBottom - vRect.yTop
  376.            );
  377. } // end of wxNotebook::SetPageSize
  378.  
  379. void wxNotebook::SetPadding (
  380.   const wxSize&                     WXUNUSED(rPadding)
  381. )
  382. {
  383.     //
  384.     // No padding in OS/2
  385.     //
  386. } // end of wxNotebook::SetPadding
  387.  
  388. void wxNotebook::SetTabSize (
  389.   const wxSize&                     rSize
  390. )
  391. {
  392.     ::WinSendMsg( GetHWND()
  393.                  ,BKM_SETDIMENSIONS
  394.                  ,MPFROM2SHORT( (USHORT)rSize.x
  395.                                ,(USHORT)rSize.y
  396.                               )
  397.                  ,(MPARAM)BKA_MAJORTAB
  398.                 );
  399. } // end of wxNotebook::SetTabSize
  400.  
  401. // ----------------------------------------------------------------------------
  402. // wxNotebook operations
  403. // ----------------------------------------------------------------------------
  404.  
  405. //
  406. // Remove one page from the notebook, without deleting
  407. //
  408. wxNotebookPage* wxNotebook::DoRemovePage (
  409.   int                               nPage
  410. )
  411. {
  412.     wxNotebookPage*                 pPageRemoved = wxNotebookBase::DoRemovePage(nPage);
  413.  
  414.     if (!pPageRemoved)
  415.         return NULL;
  416.  
  417.  
  418.     ULONG                           ulPageId = (ULONG)m_alPageId[nPage];
  419.  
  420.     ::WinSendMsg( GetHWND()
  421.                  ,BKM_DELETEPAGE
  422.                  ,MPFROMLONG((ULONG)m_alPageId[nPage])
  423.                  ,(MPARAM)BKA_TAB
  424.                 );
  425.     if (m_pages.IsEmpty())
  426.     {
  427.         //
  428.         // No selection any more, the notebook becamse empty
  429.         //
  430.         m_nSelection = -1;
  431.     }
  432.     else // notebook still not empty
  433.     {
  434.         //
  435.         // Change the selected page if it was deleted or became invalid
  436.         //
  437.         int                         nSelNew;
  438.  
  439.         if (m_nSelection == GetPageCount())
  440.         {
  441.             //
  442.             // Last page deleted, make the new last page the new selection
  443.             //
  444.             nSelNew = m_nSelection - 1;
  445.         }
  446.         else if (nPage <= m_nSelection)
  447.         {
  448.             //
  449.             // We must show another page, even if it has the same index
  450.             //
  451.             nSelNew = m_nSelection;
  452.         }
  453.         else // nothing changes for the currently selected page
  454.         {
  455.             nSelNew = -1;
  456.  
  457.             //
  458.             // We still must refresh the current page: this needs to be done
  459.             // for some unknown reason if the tab control shows the up-down
  460.             // control (i.e. when there are too many pages) -- otherwise after
  461.             // deleting a page nothing at all is shown
  462.             //
  463.             m_pages[m_nSelection]->Refresh();
  464.         }
  465.  
  466.         if (nSelNew != -1)
  467.         {
  468.             //
  469.             // m_nSelection must be always valid so reset it before calling
  470.             // SetSelection()
  471.             //
  472.             m_nSelection = -1;
  473.             SetSelection(nSelNew);
  474.         }
  475.     }
  476.     return pPageRemoved;
  477. } // end of wxNotebook::DoRemovePage
  478.  
  479. //
  480. // Remove all pages
  481. //
  482. bool wxNotebook::DeleteAllPages()
  483. {
  484.     int                             nPageCount = GetPageCount();
  485.     int                             nPage;
  486.  
  487.     for (nPage = 0; nPage < nPageCount; nPage++)
  488.         delete m_pages[nPage];
  489.     m_pages.Clear();
  490.     ::WinSendMsg( GetHWND()
  491.                  ,BKM_DELETEPAGE
  492.                  ,(MPARAM)0
  493.                  ,(MPARAM)BKA_ALL
  494.                 );
  495.     m_nSelection = -1;
  496.     return TRUE;
  497. } // end of wxNotebook::DeleteAllPages
  498.  
  499. //
  500. // Add a page to the notebook
  501. //
  502. bool wxNotebook::AddPage (
  503.   wxNotebookPage*                   pPage
  504. , const wxString&                   rStrText
  505. , bool                              bSelect
  506. , int                               nImageId
  507. )
  508. {
  509.     return InsertPage( GetPageCount()
  510.                       ,pPage
  511.                       ,rStrText
  512.                       ,bSelect
  513.                       ,nImageId
  514.                      );
  515. } // end of wxNotebook::AddPage
  516.  
  517. //
  518. // Same as AddPage() but does it at given position
  519. //
  520. bool wxNotebook::InsertPage (
  521.   int                               nPage
  522. , wxNotebookPage*                   pPage
  523. , const wxString&                   rsStrText
  524. , bool                              bSelect
  525. , int                               nImageId
  526. )
  527. {
  528.     ULONG                           ulApiPage;
  529.  
  530.     wxASSERT( pPage != NULL );
  531.     wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE );
  532.  
  533.     //
  534.     // Under OS/2 we can only insert FIRST, LAST, NEXT or PREV.  Requires
  535.     // two different calls to the API.  Page 1 uses the BKA_FIRST.  Subsequent
  536.     // pages use the previous page ID coupled with a BKA_NEXT call.  Unlike
  537.     // Windows, OS/2 uses an internal Page ID to ID the pages.
  538.     //
  539.     // OS/2 also has a nice auto-size feature that automatically sizes the
  540.     // the attached window so we don't have to worry about the size of the
  541.     // window on the page.
  542.     //
  543.     if (nPage == 0)
  544.     {
  545.         ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
  546.                                             ,BKM_INSERTPAGE
  547.                                             ,(MPARAM)0
  548.                                             ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_FIRST)
  549.                                            ));
  550.         if (ulApiPage == 0L)
  551.         {
  552.             ERRORID                 vError;
  553.             wxString                sError;
  554.  
  555.             vError = ::WinGetLastError(vHabmain);
  556.             sError = wxPMErrorToStr(vError);
  557.             return FALSE;
  558.         }
  559.         m_alPageId.Insert((long)ulApiPage, nPage);
  560.     }
  561.     else
  562.     {
  563.         ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
  564.                                             ,BKM_INSERTPAGE
  565.                                             ,MPFROMLONG((ULONG)m_alPageId[nPage - 1])
  566.                                             ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_NEXT)
  567.                                            ));
  568.         if (ulApiPage == 0L)
  569.         {
  570.             ERRORID                     vError;
  571.             wxString                    sError;
  572.  
  573.             vError = ::WinGetLastError(vHabmain);
  574.             sError = wxPMErrorToStr(vError);
  575.             return FALSE;
  576.         }
  577.         m_alPageId.Insert((long)ulApiPage, nPage);
  578.     }
  579.  
  580.     //
  581.     // Associate a window handle with the page
  582.     //
  583.     if (pPage)
  584.     {
  585.         if (!::WinSendMsg( GetHWND()
  586.                           ,BKM_SETPAGEWINDOWHWND
  587.                           ,MPFROMLONG((ULONG)m_alPageId[nPage])
  588.                           ,MPFROMHWND(pPage->GetHWND())
  589.                          ))
  590.             return FALSE;
  591.     }
  592.     //
  593.     // If the inserted page is before the selected one, we must update the
  594.     // index of the selected page
  595.     //
  596.     if (nPage <= m_nSelection)
  597.     {
  598.         //
  599.         // One extra page added
  600.         //
  601.         m_nSelection++;
  602.     }
  603.  
  604.     if (pPage)
  605.     {
  606.         //
  607.         // Save the pointer to the page
  608.         //
  609.         m_pages.Insert( pPage
  610.                        ,nPage
  611.                       );
  612.     }
  613.  
  614.     //
  615.     // Now set TAB dimenstions
  616.     //
  617.  
  618.     wxWindowDC                      vDC(this);
  619.     wxCoord                         nTextX;
  620.     wxCoord                         nTextY;
  621.  
  622.     vDC.GetTextExtent(rsStrText, &nTextX, &nTextY);
  623.     nTextY *= 2;
  624.     nTextX *= 1.3;
  625.     if (nTextX > m_nTabSize)
  626.     {
  627.         m_nTabSize = nTextX;
  628.         ::WinSendMsg( GetHWND()
  629.                      ,BKM_SETDIMENSIONS
  630.                      ,MPFROM2SHORT((USHORT)m_nTabSize, (USHORT)nTextY)
  631.                      ,(MPARAM)BKA_MAJORTAB
  632.                     );
  633.     }
  634.     //
  635.     // Now set any TAB text
  636.     //
  637.     if (!rsStrText.IsEmpty())
  638.     {
  639.         if (!SetPageText( nPage
  640.                          ,rsStrText
  641.                         ))
  642.             return FALSE;
  643.     }
  644.  
  645.     //
  646.     // Now set any TAB bitmap image
  647.     //
  648.     if (nImageId != -1)
  649.     {
  650.         if (!SetPageImage( nPage
  651.                           ,nImageId
  652.                          ))
  653.             return FALSE;
  654.     }
  655.  
  656.     if (pPage)
  657.     {
  658.         //
  659.         // Don't show pages by default (we'll need to adjust their size first)
  660.         //
  661.         HWND                        hWnd = GetWinHwnd(pPage);
  662.  
  663.         WinSetWindowULong( hWnd
  664.                           ,QWL_STYLE
  665.                           ,WinQueryWindowULong( hWnd
  666.                                                ,QWL_STYLE
  667.                                               ) & ~WS_VISIBLE
  668.                          );
  669.  
  670.         //
  671.         // This updates internal flag too - otherwise it will get out of sync
  672.         //
  673.         pPage->Show(FALSE);
  674.     }
  675.  
  676.     //
  677.     // Some page should be selected: either this one or the first one if there is
  678.     // still no selection
  679.     //
  680.     int                             nSelNew = -1;
  681.  
  682.     if (bSelect)
  683.         nSelNew = nPage;
  684.     else if ( m_nSelection == -1 )
  685.         nSelNew = 0;
  686.  
  687.     if (nSelNew != -1)
  688.         SetSelection(nSelNew);
  689.     return TRUE;
  690. } // end of wxNotebook::InsertPage
  691.  
  692. // ----------------------------------------------------------------------------
  693. // wxNotebook callbacks
  694. // ----------------------------------------------------------------------------
  695. void wxNotebook::OnSize(
  696.   wxSizeEvent&                      rEvent
  697. )
  698. {
  699.     int                             nPage;
  700.     int                             nCount = (int)m_pages.Count();
  701.  
  702.     for (nPage = 0; nPage < nCount; nPage++)
  703.     {
  704.         if (m_nSelection == nPage)
  705.             m_pages[nPage]->Refresh();
  706.         else
  707.             ::WinSetWindowPos(m_pages[nPage]->GetHWND()
  708.                               ,NULLHANDLE
  709.                               ,0,0,0,0
  710.                               ,SWP_HIDE
  711.                              );
  712.     }
  713.     rEvent.Skip();
  714. } // end of wxNotebook::OnSize
  715.  
  716. void wxNotebook::OnSelChange (
  717.   wxNotebookEvent&                  rEvent
  718. )
  719. {
  720.     //
  721.     // Is it our tab control?
  722.     //
  723.     if (rEvent.GetEventObject() == this)
  724.     {
  725.         int                         nPageCount = GetPageCount();
  726.         int                         nSel;
  727.         ULONG                       ulOS2Sel = (ULONG)rEvent.GetOldSelection();
  728.         bool                        bFound = FALSE;
  729.  
  730.         for (nSel = 0; nSel < nPageCount; nSel++)
  731.         {
  732.             if (ulOS2Sel == m_alPageId[nSel])
  733.             {
  734.                 bFound = TRUE;
  735.                 break;
  736.             }
  737.         }
  738.  
  739.         if (!bFound)
  740.             return;
  741.  
  742.         m_pages[nSel]->Show(FALSE);
  743.  
  744.         ulOS2Sel = (ULONG)rEvent.GetSelection();
  745.  
  746.         bFound = FALSE;
  747.  
  748.         for (nSel = 0; nSel < nPageCount; nSel++)
  749.         {
  750.             if (ulOS2Sel == m_alPageId[nSel])
  751.             {
  752.                 bFound = TRUE;
  753.                 break;
  754.             }
  755.         }
  756.  
  757.         if (!bFound)
  758.             return;
  759.  
  760.         wxNotebookPage*         pPage = m_pages[nSel];
  761.  
  762.         pPage->Show(TRUE);
  763.         m_nSelection = nSel;
  764.     }
  765.  
  766.     //
  767.     // We want to give others a chance to process this message as well
  768.     //
  769.     rEvent.Skip();
  770. } // end of wxNotebook::OnSelChange
  771.  
  772. void wxNotebook::OnSetFocus (
  773.   wxFocusEvent&                     rEvent
  774. )
  775. {
  776.     //
  777.     // This function is only called when the focus is explicitly set (i.e. from
  778.     // the program) to the notebook - in this case we don't need the
  779.     // complicated OnNavigationKey() logic because the programmer knows better
  780.     // what [s]he wants
  781.     //
  782.     // set focus to the currently selected page if any
  783.     //
  784.     if (m_nSelection != -1)
  785.         m_pages[m_nSelection]->SetFocus();
  786.     rEvent.Skip();
  787. } // end of wxNotebook::OnSetFocus
  788.  
  789. void wxNotebook::OnNavigationKey (
  790.   wxNavigationKeyEvent&             rEvent
  791. )
  792. {
  793.     if (rEvent.IsWindowChange())
  794.     {
  795.         //
  796.         // Change pages
  797.         //
  798.         AdvanceSelection(rEvent.GetDirection());
  799.     }
  800.     else
  801.     {
  802.         //
  803.         // We get this event in 2 cases
  804.         //
  805.         // a) one of our pages might have generated it because the user TABbed
  806.         // out from it in which case we should propagate the event upwards and
  807.         // our parent will take care of setting the focus to prev/next sibling
  808.         //
  809.         // or
  810.         //
  811.         // b) the parent panel wants to give the focus to us so that we
  812.         // forward it to our selected page. We can't deal with this in
  813.         // OnSetFocus() because we don't know which direction the focus came
  814.         // from in this case and so can't choose between setting the focus to
  815.         // first or last panel child
  816.         //
  817.         wxWindow*                   pParent = GetParent();
  818.  
  819.         if (rEvent.GetEventObject() == pParent)
  820.         {
  821.             //
  822.             // No, it doesn't come from child, case (b): forward to a page
  823.             //
  824.             if (m_nSelection != -1)
  825.             {
  826.                 //
  827.                 // So that the page knows that the event comes from it's parent
  828.                 // and is being propagated downwards
  829.                 //
  830.                 rEvent.SetEventObject(this);
  831.  
  832.                 wxWindow*           pPage = m_pages[m_nSelection];
  833.  
  834.                 if (!pPage->GetEventHandler()->ProcessEvent(rEvent))
  835.                 {
  836.                     pPage->SetFocus();
  837.                 }
  838.                 //else: page manages focus inside it itself
  839.             }
  840.             else
  841.             {
  842.                 //
  843.                 // We have no pages - still have to give focus to _something_
  844.                 //
  845.                 SetFocus();
  846.             }
  847.         }
  848.         else
  849.         {
  850.             //
  851.             // It comes from our child, case (a), pass to the parent
  852.             //
  853.             if (pParent)
  854.             {
  855.                 rEvent.SetCurrentFocus(this);
  856.                 pParent->GetEventHandler()->ProcessEvent(rEvent);
  857.             }
  858.         }
  859.     }
  860. } // end of wxNotebook::OnNavigationKey
  861.  
  862. // ----------------------------------------------------------------------------
  863. // wxNotebook base class virtuals
  864. // ----------------------------------------------------------------------------
  865.  
  866. //
  867. // Override these 2 functions to do nothing: everything is done in OnSize
  868. //
  869. void wxNotebook::SetConstraintSizes(
  870.   bool                              WXUNUSED(bRecurse)
  871. )
  872. {
  873.     //
  874.     // Don't set the sizes of the pages - their correct size is not yet known
  875.     //
  876.     wxControl::SetConstraintSizes(FALSE);
  877. } // end of wxNotebook::SetConstraintSizes
  878.  
  879. bool wxNotebook::DoPhase (
  880.   int                               WXUNUSED(nPhase)
  881. )
  882. {
  883.     return TRUE;
  884. } // end of wxNotebook::DoPhase
  885.  
  886. // ----------------------------------------------------------------------------
  887. // wxNotebook Windows message handlers
  888. // ----------------------------------------------------------------------------
  889. bool wxNotebook::OS2OnScroll (
  890.   int                               nOrientation
  891. , WXWORD                            wSBCode
  892. , WXWORD                            wPos
  893. , WXHWND                            wControl
  894. )
  895. {
  896.     //
  897.     // Don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the
  898.     // up-down control
  899.     //
  900.     if (wControl)
  901.         return FALSE;
  902.     return wxNotebookBase::OS2OnScroll( nOrientation
  903.                                        ,wSBCode
  904.                                        ,wPos
  905.                                        ,wControl
  906.                                       );
  907. } // end of wxNotebook::OS2OnScroll
  908.  
  909. #endif // wxUSE_NOTEBOOK
  910.  
  911.