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