]> git.saurik.com Git - wxWidgets.git/blame - src/msw/notebook.cpp
Default border for a static box is wxBORDER_NONE
[wxWidgets.git] / src / msw / notebook.cpp
CommitLineData
88310e2e
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/notebook.cpp
3// Purpose: implementation of wxNotebook
4// Author: Vadim Zeitlin
907f37b3 5// Modified by:
88310e2e
VZ
6// Created: 11.06.98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// Licence: wxWindows licence
88310e2e
VZ
10///////////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
a3b46648 13#pragma implementation "notebook.h"
88310e2e
VZ
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
1e6feb95 20 #pragma hdrstop
88310e2e
VZ
21#endif
22
1e6feb95
VZ
23#if wxUSE_NOTEBOOK
24
77ffb593 25// wxWidgets
88310e2e 26#ifndef WX_PRECOMP
3096bd2f 27 #include "wx/string.h"
bb180f90 28 #include "wx/dc.h"
88310e2e
VZ
29#endif // WX_PRECOMP
30
3096bd2f
VZ
31#include "wx/log.h"
32#include "wx/imaglist.h"
33#include "wx/event.h"
34#include "wx/control.h"
35#include "wx/notebook.h"
04eb05b0 36#include "wx/app.h"
25057aba 37#include "wx/sysopt.h"
88310e2e 38
3096bd2f 39#include "wx/msw/private.h"
88310e2e 40
c1f3a149 41#include <windowsx.h>
aaab7c01 42
b39dbf34
JS
43#ifdef __GNUWIN32_OLD__
44 #include "wx/msw/gnuwin32/extra.h"
65fd5cb0 45#endif
57c208c5 46
c1f3a149 47#if !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
c42404a5 48 #include <commctrl.h>
88310e2e
VZ
49#endif
50
85b43fbf
JS
51#include "wx/msw/winundef.h"
52
53#if wxUSE_UXTHEME
caf95d2a 54 #include "wx/msw/uxtheme.h"
85b43fbf
JS
55#endif
56
88310e2e
VZ
57// ----------------------------------------------------------------------------
58// macros
59// ----------------------------------------------------------------------------
60
61// check that the page index is valid
8d34bf5c 62#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
88310e2e
VZ
63
64// hide the ugly cast
65#define m_hwnd (HWND)GetHWND()
66
74b31181
VZ
67// ----------------------------------------------------------------------------
68// constants
69// ----------------------------------------------------------------------------
70
71// This is a work-around for missing defines in gcc-2.95 headers
72#ifndef TCS_RIGHT
73 #define TCS_RIGHT 0x0002
74#endif
75
76#ifndef TCS_VERTICAL
77 #define TCS_VERTICAL 0x0080
78#endif
79
80#ifndef TCS_BOTTOM
81 #define TCS_BOTTOM TCS_RIGHT
82#endif
83
88310e2e
VZ
84// ----------------------------------------------------------------------------
85// event table
86// ----------------------------------------------------------------------------
87
51741307
SC
88#include <wx/listimpl.cpp>
89
90WX_DEFINE_LIST( wxNotebookPageInfoList ) ;
91
2e4df4bf
VZ
92DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
93DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
94
d9317fd4 95BEGIN_EVENT_TABLE(wxNotebook, wxControl)
88310e2e 96 EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
9026ad85 97 EVT_SIZE(wxNotebook::OnSize)
88310e2e 98 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
d9317fd4 99END_EVENT_TABLE()
88310e2e 100
51596bcb 101#if wxUSE_EXTENDED_RTTI
bc9fb572
JS
102WX_DEFINE_FLAGS( wxNotebookStyle )
103
3ff066a4 104wxBEGIN_FLAGS( wxNotebookStyle )
bc9fb572
JS
105 // new style border flags, we put them first to
106 // use them for streaming out
3ff066a4
SC
107 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
108 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
109 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
110 wxFLAGS_MEMBER(wxBORDER_RAISED)
111 wxFLAGS_MEMBER(wxBORDER_STATIC)
112 wxFLAGS_MEMBER(wxBORDER_NONE)
078cf5cb 113
bc9fb572 114 // old style border flags
3ff066a4
SC
115 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
116 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
117 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
118 wxFLAGS_MEMBER(wxRAISED_BORDER)
119 wxFLAGS_MEMBER(wxSTATIC_BORDER)
cb0afb26 120 wxFLAGS_MEMBER(wxBORDER)
bc9fb572
JS
121
122 // standard window styles
3ff066a4
SC
123 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
124 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
125 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
126 wxFLAGS_MEMBER(wxWANTS_CHARS)
cb0afb26 127 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
3ff066a4
SC
128 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
129 wxFLAGS_MEMBER(wxVSCROLL)
130 wxFLAGS_MEMBER(wxHSCROLL)
131
132 wxFLAGS_MEMBER(wxNB_FIXEDWIDTH)
133 wxFLAGS_MEMBER(wxNB_LEFT)
134 wxFLAGS_MEMBER(wxNB_RIGHT)
135 wxFLAGS_MEMBER(wxNB_BOTTOM)
b554cf63
JS
136 wxFLAGS_MEMBER(wxNB_NOPAGETHEME)
137 wxFLAGS_MEMBER(wxNB_FLAT)
3ff066a4
SC
138
139wxEND_FLAGS( wxNotebookStyle )
51741307 140
51596bcb 141IMPLEMENT_DYNAMIC_CLASS_XTI(wxNotebook, wxControl,"wx/notebook.h")
51741307
SC
142IMPLEMENT_DYNAMIC_CLASS_XTI(wxNotebookPageInfo, wxObject , "wx/notebook.h" )
143
3ff066a4 144wxCOLLECTION_TYPE_INFO( wxNotebookPageInfo * , wxNotebookPageInfoList ) ;
51596bcb 145
f0a126fe
SC
146template<> void wxCollectionToVariantArray( wxNotebookPageInfoList const &theList, wxxVariantArray &value)
147{
0c6b0084 148 wxListCollectionToVariantArray<wxNotebookPageInfoList::compatibility_iterator>( theList , value ) ;
f0a126fe
SC
149}
150
3ff066a4
SC
151wxBEGIN_PROPERTIES_TABLE(wxNotebook)
152 wxEVENT_PROPERTY( PageChanging , wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING , wxNotebookEvent )
153 wxEVENT_PROPERTY( PageChanged , wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED , wxNotebookEvent )
c5ca409b 154
3ff066a4 155 wxPROPERTY_COLLECTION( PageInfos , wxNotebookPageInfoList , wxNotebookPageInfo* , AddPageInfo , GetPageInfos , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
af498247 156 wxPROPERTY_FLAGS( WindowStyle , wxNotebookStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
3ff066a4 157wxEND_PROPERTIES_TABLE()
51596bcb 158
3ff066a4
SC
159wxBEGIN_HANDLERS_TABLE(wxNotebook)
160wxEND_HANDLERS_TABLE()
51596bcb 161
078cf5cb 162wxCONSTRUCTOR_5( wxNotebook , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle)
51596bcb 163
51741307 164
3ff066a4 165wxBEGIN_PROPERTIES_TABLE(wxNotebookPageInfo)
af498247 166 wxREADONLY_PROPERTY( Page , wxNotebookPage* , GetPage , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
3ff066a4
SC
167 wxREADONLY_PROPERTY( Text , wxString , GetText , wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
168 wxREADONLY_PROPERTY( Selected , bool , GetSelected , false, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
169 wxREADONLY_PROPERTY( ImageId , int , GetImageId , -1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
170wxEND_PROPERTIES_TABLE()
51741307 171
3ff066a4
SC
172wxBEGIN_HANDLERS_TABLE(wxNotebookPageInfo)
173wxEND_HANDLERS_TABLE()
51741307 174
078cf5cb 175wxCONSTRUCTOR_4( wxNotebookPageInfo , wxNotebookPage* , Page , wxString , Text , bool , Selected , int , ImageId )
51741307 176
51596bcb 177#else
d9317fd4 178IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
51741307 179IMPLEMENT_DYNAMIC_CLASS(wxNotebookPageInfo, wxObject )
51596bcb 180#endif
d9317fd4 181IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
88310e2e 182
de359565
VZ
183// ----------------------------------------------------------------------------
184// local functions
185// ----------------------------------------------------------------------------
186
848c5893 187#ifndef __WXWINCE__
de359565
VZ
188// apparently DrawThemeBackground() modifies the rect passed to it and if we
189// don't call this function there are some drawing artifacts which are only
190// visible with some non default themes; so modify the rect here so that it
191// still paints the correct area
192static void AdjustRectForThemeBg(RECT& rc)
193{
194 // magic numbers needed to compensate for DrawThemeBackground()
195 rc.left -= 2;
196 rc.top -= 2;
197 rc.right += 4;
198 rc.bottom += 5;
199}
848c5893 200#endif
de359565 201
88310e2e
VZ
202// ============================================================================
203// implementation
204// ============================================================================
205
206// ----------------------------------------------------------------------------
207// wxNotebook construction
208// ----------------------------------------------------------------------------
209
51741307
SC
210const wxNotebookPageInfoList& wxNotebook::GetPageInfos() const
211{
212 wxNotebookPageInfoList* list = const_cast< wxNotebookPageInfoList* >( &m_pageInfos ) ;
213 WX_CLEAR_LIST( wxNotebookPageInfoList , *list ) ;
34a0c9f4 214 for( size_t i = 0 ; i < GetPageCount() ; ++i )
51741307
SC
215 {
216 wxNotebookPageInfo *info = new wxNotebookPageInfo() ;
34a0c9f4 217 info->Create( const_cast<wxNotebook*>(this)->GetPage(i) , GetPageText(i) , GetSelection() == int(i) , GetPageImage(i) ) ;
51741307
SC
218 list->Append( info ) ;
219 }
220 return m_pageInfos ;
221}
222
88310e2e
VZ
223// common part of all ctors
224void wxNotebook::Init()
225{
1e6feb95 226 m_imageList = NULL;
88310e2e 227 m_nSelection = -1;
caf95d2a
VZ
228
229#if wxUSE_UXTHEME
230 m_hbrBackground = NULL;
231#endif // wxUSE_UXTHEME
88310e2e
VZ
232}
233
234// default for dynamic class
235wxNotebook::wxNotebook()
236{
237 Init();
238}
239
240// the same arguments as for wxControl
241wxNotebook::wxNotebook(wxWindow *parent,
8b9518ee 242 wxWindowID id,
88310e2e
VZ
243 const wxPoint& pos,
244 const wxSize& size,
8b9518ee 245 long style,
88310e2e
VZ
246 const wxString& name)
247{
248 Init();
249
250 Create(parent, id, pos, size, style, name);
251}
252
253// Create() function
254bool wxNotebook::Create(wxWindow *parent,
8b9518ee 255 wxWindowID id,
88310e2e
VZ
256 const wxPoint& pos,
257 const wxSize& size,
8b9518ee 258 long style,
88310e2e
VZ
259 const wxString& name)
260{
df10208f
VZ
261 // comctl32.dll 6.0 doesn't support non-top tabs with visual styles (the
262 // control is simply not rendered correctly), so disable them in this case
263 const int verComCtl32 = wxApp::GetComCtl32Version();
264 if ( verComCtl32 == 600 )
04eb05b0 265 {
df10208f
VZ
266 // check if we use themes at all -- if we don't, we're still ok
267#if wxUSE_UXTHEME
268 if ( wxUxThemeEngine::GetIfActive() )
269#endif
270 {
271 style &= ~(wxNB_BOTTOM | wxNB_LEFT | wxNB_RIGHT);
272 }
04eb05b0 273 }
078cf5cb 274
c1637c89
VZ
275 LPCTSTR className = WC_TABCONTROL;
276
277 // SysTabCtl32 class has natively CS_HREDRAW and CS_VREDRAW enabled and it
278 // causes horrible flicker when resizing notebook, so get rid of it by
279 // using a class without these styles (but otherwise identical to it)
280 if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
281 {
282 static ClassRegistrar s_clsNotebook;
283 if ( !s_clsNotebook.IsInitialized() )
284 {
285 // get a copy of standard class and modify it
286 WNDCLASS wc;
287
288 if ( ::GetClassInfo(::GetModuleHandle(NULL), WC_TABCONTROL, &wc) )
289 {
290 wc.lpszClassName = wxT("_wx_SysTabCtl32");
291 wc.style &= ~(CS_HREDRAW | CS_VREDRAW);
292
293 s_clsNotebook.Register(wc);
294 }
295 else
296 {
297 wxLogLastError(_T("GetClassInfoEx(SysTabCtl32)"));
298 }
299 }
300
301 // use our custom class if available but fall back to the standard
302 // notebook if we failed to register it
303 if ( s_clsNotebook.IsRegistered() )
304 {
305 // it's ok to use c_str() here as the static s_clsNotebook object
306 // has sufficiently long lifetime
307 className = s_clsNotebook.GetName().c_str();
308 }
309 }
310
6dd16e4f
VZ
311 if ( !CreateControl(parent, id, pos, size, style | wxTAB_TRAVERSAL,
312 wxDefaultValidator, name) )
b8bdaa7c 313 return false;
88310e2e 314
c1637c89 315 if ( !MSWCreateControl(className, wxEmptyString, pos, size) )
b8bdaa7c 316 return false;
907f37b3 317
7dccdf81
VZ
318#if wxUSE_UXTHEME
319 if ( HasFlag(wxNB_NOPAGETHEME) ||
320 wxSystemOptions::IsFalse(wxT("msw.notebook.themed-background")) )
f2b7be7a 321 {
7dccdf81 322 SetBackgroundColour(GetThemeBackgroundColour());
f2b7be7a 323 }
7dccdf81 324#endif // wxUSE_UXTHEME
b554cf63
JS
325
326 // Undocumented hack to get flat notebook style
327 // In fact, we should probably only do this in some
328 // curcumstances, i.e. if we know we will have a border
329 // at the bottom (the tab control doesn't draw it itself)
330#if defined(__POCKETPC__) || defined(__SMARTPHONE__)
331 if (HasFlag(wxNB_FLAT))
332 {
333 SendMessage(m_hwnd, CCM_SETVERSION, COMCTL32_VERSION, 0);
334 if (!m_hasBgCol)
335 SetBackgroundColour(*wxWHITE);
336 }
337#endif
b8bdaa7c 338 return true;
0df3fbd7
VZ
339}
340
341WXDWORD wxNotebook::MSWGetStyle(long style, WXDWORD *exstyle) const
342{
343 WXDWORD tabStyle = wxControl::MSWGetStyle(style, exstyle);
344
345 tabStyle |= WS_TABSTOP | TCS_TABS;
346
2b5f62a0 347 if ( style & wxNB_MULTILINE )
0df3fbd7
VZ
348 tabStyle |= TCS_MULTILINE;
349 if ( style & wxNB_FIXEDWIDTH )
350 tabStyle |= TCS_FIXEDWIDTH;
351
352 if ( style & wxNB_BOTTOM )
353 tabStyle |= TCS_RIGHT;
354 else if ( style & wxNB_LEFT )
355 tabStyle |= TCS_VERTICAL;
356 else if ( style & wxNB_RIGHT )
b554cf63 357 tabStyle |= TCS_VERTICAL | TCS_RIGHT;
0df3fbd7
VZ
358
359 // ex style
360 if ( exstyle )
361 {
362 // note that we never want to have the default WS_EX_CLIENTEDGE style
363 // as it looks too ugly for the notebooks
364 *exstyle = 0;
365 }
366
367 return tabStyle;
88310e2e
VZ
368}
369
caf95d2a
VZ
370wxNotebook::~wxNotebook()
371{
372#if wxUSE_UXTHEME
373 if ( m_hbrBackground )
374 ::DeleteObject((HBRUSH)m_hbrBackground);
375#endif // wxUSE_UXTHEME
376}
377
88310e2e
VZ
378// ----------------------------------------------------------------------------
379// wxNotebook accessors
380// ----------------------------------------------------------------------------
07b8d7ec 381
8d34bf5c 382size_t wxNotebook::GetPageCount() const
88310e2e
VZ
383{
384 // consistency check
1e6feb95 385 wxASSERT( (int)m_pages.Count() == TabCtrl_GetItemCount(m_hwnd) );
88310e2e 386
1e6feb95 387 return m_pages.Count();
88310e2e
VZ
388}
389
390int wxNotebook::GetRowCount() const
391{
392 return TabCtrl_GetRowCount(m_hwnd);
393}
394
8d34bf5c 395int wxNotebook::SetSelection(size_t nPage)
88310e2e 396{
078cf5cb 397 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
88310e2e 398
34a0c9f4 399 if ( int(nPage) != m_nSelection )
2b5f62a0
VZ
400 {
401 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_windowId);
402 event.SetSelection(nPage);
403 event.SetOldSelection(m_nSelection);
404 event.SetEventObject(this);
405 if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
406 {
407 // program allows the page change
408 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
409 (void)GetEventHandler()->ProcessEvent(event);
410
411 TabCtrl_SetCurSel(m_hwnd, nPage);
412 }
413 }
88310e2e 414
2b5f62a0 415 return m_nSelection;
88310e2e
VZ
416}
417
8d34bf5c 418bool wxNotebook::SetPageText(size_t nPage, const wxString& strText)
88310e2e 419{
b8bdaa7c 420 wxCHECK_MSG( IS_VALID_PAGE(nPage), false, wxT("notebook page out of range") );
88310e2e
VZ
421
422 TC_ITEM tcItem;
423 tcItem.mask = TCIF_TEXT;
837e5743 424 tcItem.pszText = (wxChar *)strText.c_str();
88310e2e
VZ
425
426 return TabCtrl_SetItem(m_hwnd, nPage, &tcItem) != 0;
427}
428
8d34bf5c 429wxString wxNotebook::GetPageText(size_t nPage) const
88310e2e 430{
fda7962d 431 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxEmptyString, wxT("notebook page out of range") );
88310e2e 432
837e5743 433 wxChar buf[256];
88310e2e
VZ
434 TC_ITEM tcItem;
435 tcItem.mask = TCIF_TEXT;
436 tcItem.pszText = buf;
437 tcItem.cchTextMax = WXSIZEOF(buf);
438
439 wxString str;
440 if ( TabCtrl_GetItem(m_hwnd, nPage, &tcItem) )
441 str = tcItem.pszText;
442
443 return str;
444}
445
8d34bf5c 446int wxNotebook::GetPageImage(size_t nPage) const
88310e2e 447{
223d09f6 448 wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
88310e2e
VZ
449
450 TC_ITEM tcItem;
451 tcItem.mask = TCIF_IMAGE;
452
453 return TabCtrl_GetItem(m_hwnd, nPage, &tcItem) ? tcItem.iImage : -1;
454}
455
8d34bf5c 456bool wxNotebook::SetPageImage(size_t nPage, int nImage)
88310e2e 457{
b8bdaa7c 458 wxCHECK_MSG( IS_VALID_PAGE(nPage), false, wxT("notebook page out of range") );
88310e2e
VZ
459
460 TC_ITEM tcItem;
461 tcItem.mask = TCIF_IMAGE;
462 tcItem.iImage = nImage;
463
464 return TabCtrl_SetItem(m_hwnd, nPage, &tcItem) != 0;
465}
466
467void wxNotebook::SetImageList(wxImageList* imageList)
907f37b3 468{
07b8d7ec
VZ
469 wxNotebookBase::SetImageList(imageList);
470
471 if ( imageList )
1e6feb95 472 {
07b8d7ec 473 TabCtrl_SetImageList(m_hwnd, (HIMAGELIST)imageList->GetHIMAGELIST());
1e6feb95 474 }
b656febd
VS
475}
476
d9506e77
VZ
477// ----------------------------------------------------------------------------
478// wxNotebook size settings
479// ----------------------------------------------------------------------------
480
481void wxNotebook::SetPageSize(const wxSize& size)
482{
483 // transform the page size into the notebook size
484 RECT rc;
485 rc.left =
486 rc.top = 0;
487 rc.right = size.x;
488 rc.bottom = size.y;
489
b8bdaa7c 490 TabCtrl_AdjustRect(GetHwnd(), true, &rc);
d9506e77
VZ
491
492 // and now set it
493 SetSize(rc.right - rc.left, rc.bottom - rc.top);
494}
495
496void wxNotebook::SetPadding(const wxSize& padding)
497{
498 TabCtrl_SetPadding(GetHwnd(), padding.x, padding.y);
499}
42e69d6b
VZ
500
501// Windows-only at present. Also, you must use the wxNB_FIXEDWIDTH
502// style.
503void wxNotebook::SetTabSize(const wxSize& sz)
504{
505 ::SendMessage(GetHwnd(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y));
506}
507
2ce7af35
JS
508wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
509{
510 wxSize sizeTotal = sizePage;
078cf5cb 511
77ffb593 512 // We need to make getting tab size part of the wxWidgets API.
8b5d5223 513 wxSize tabSize;
2ce7af35
JS
514 if (GetPageCount() > 0)
515 {
516 RECT rect;
517 TabCtrl_GetItemRect((HWND) GetHWND(), 0, & rect);
518 tabSize.x = rect.right - rect.left;
519 tabSize.y = rect.bottom - rect.top;
520 }
521 if ( HasFlag(wxNB_LEFT) || HasFlag(wxNB_RIGHT) )
522 {
523 sizeTotal.x += tabSize.x + 7;
524 sizeTotal.y += 7;
525 }
526 else
527 {
528 sizeTotal.x += 7;
529 sizeTotal.y += tabSize.y + 7;
530 }
531
532 return sizeTotal;
533}
534
2015f2b3
VZ
535void wxNotebook::AdjustPageSize(wxNotebookPage *page)
536{
537 wxCHECK_RET( page, _T("NULL page in wxNotebook::AdjustPageSize") );
538
539 RECT rc;
540 rc.left =
541 rc.top = 0;
542
543 // get the page size from the notebook size
544 GetSize((int *)&rc.right, (int *)&rc.bottom);
2015f2b3 545
14a6b6e5
RD
546 // This check is to work around a bug in TabCtrl_AdjustRect which will
547 // cause a crash on win2k, or on XP with themes disabled, if the
548 // wxNB_MULTILINE style is used and the rectangle is very small, (such as
549 // when the notebook is first created.) The value of 20 is just
550 // arbitrarily chosen, if there is a better way to determine this value
551 // then please do so. --RD
552 if (rc.right > 20 && rc.bottom > 20)
553 {
554 TabCtrl_AdjustRect(m_hwnd, false, &rc);
555 page->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
556 }
2015f2b3
VZ
557}
558
88310e2e
VZ
559// ----------------------------------------------------------------------------
560// wxNotebook operations
561// ----------------------------------------------------------------------------
562
621793f4 563// remove one page from the notebook, without deleting
8d34bf5c 564wxNotebookPage *wxNotebook::DoRemovePage(size_t nPage)
621793f4 565{
df7145da
VZ
566 wxNotebookPage *pageRemoved = wxNotebookBase::DoRemovePage(nPage);
567 if ( !pageRemoved )
568 return NULL;
621793f4 569
df7145da 570 TabCtrl_DeleteItem(m_hwnd, nPage);
621793f4 571
df7145da
VZ
572 if ( m_pages.IsEmpty() )
573 {
574 // no selection any more, the notebook becamse empty
575 m_nSelection = -1;
576 }
577 else // notebook still not empty
578 {
623f5f70
JS
579 int selNew = TabCtrl_GetCurSel(m_hwnd);
580 if (selNew != -1)
df7145da 581 {
623f5f70 582 // No selection change, just refresh the current selection.
078cf5cb
WS
583 // Because it could be that the slection index changed
584 // we need to update it.
623f5f70
JS
585 // Note: this does not mean the selection it self changed.
586 m_nSelection = selNew;
587 m_pages[m_nSelection]->Refresh();
df7145da 588 }
623f5f70 589 else if (int(nPage) == m_nSelection)
43a997b6 590 {
623f5f70 591 // The selection was deleted.
078cf5cb 592
623f5f70
JS
593 // Determine new selection.
594 if (m_nSelection == int(GetPageCount()))
595 selNew = m_nSelection - 1;
596 else
597 selNew = m_nSelection;
078cf5cb 598
43a997b6
VZ
599 // m_nSelection must be always valid so reset it before calling
600 // SetSelection()
601 m_nSelection = -1;
602 SetSelection(selNew);
603 }
623f5f70
JS
604 else
605 {
606 wxFAIL; // Windows did not behave ok.
607 }
df7145da 608 }
47f12f58 609
df7145da 610 return pageRemoved;
621793f4
JS
611}
612
88310e2e
VZ
613// remove all pages
614bool wxNotebook::DeleteAllPages()
615{
8d34bf5c
VZ
616 size_t nPageCount = GetPageCount();
617 size_t nPage;
88310e2e 618 for ( nPage = 0; nPage < nPageCount; nPage++ )
1e6feb95 619 delete m_pages[nPage];
88310e2e 620
1e6feb95 621 m_pages.Clear();
88310e2e 622
907f37b3
VZ
623 TabCtrl_DeleteAllItems(m_hwnd);
624
47f12f58
JS
625 m_nSelection = -1;
626
37144cf0 627 InvalidateBestSize();
b8bdaa7c 628 return true;
88310e2e
VZ
629}
630
88310e2e 631// same as AddPage() but does it at given position
8d34bf5c 632bool wxNotebook::InsertPage(size_t nPage,
88310e2e
VZ
633 wxNotebookPage *pPage,
634 const wxString& strText,
635 bool bSelect,
636 int imageId)
637{
b8bdaa7c
VZ
638 wxCHECK_MSG( pPage != NULL, false, _T("NULL page in wxNotebook::InsertPage") );
639 wxCHECK_MSG( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), false,
22f3361e 640 _T("invalid index in wxNotebook::InsertPage") );
88310e2e 641
efa14cf2
VZ
642 wxASSERT_MSG( pPage->GetParent() == this,
643 _T("notebook pages must have notebook as parent") );
43427087 644
22f3361e
VZ
645 // add a new tab to the control
646 // ----------------------------
58a8ab88 647
22f3361e
VZ
648 // init all fields to 0
649 TC_ITEM tcItem;
650 wxZeroMemory(tcItem);
58a8ab88 651
22f3361e
VZ
652 // set the image, if any
653 if ( imageId != -1 )
654 {
655 tcItem.mask |= TCIF_IMAGE;
656 tcItem.iImage = imageId;
657 }
88310e2e 658
22f3361e 659 // and the text
8b5d5223 660 if ( !strText.empty() )
22f3361e
VZ
661 {
662 tcItem.mask |= TCIF_TEXT;
663 tcItem.pszText = (wxChar *)strText.c_str(); // const_cast
664 }
43427087 665
e830a6a6
RD
666 // hide the page: unless it is selected, it shouldn't be shown (and if it
667 // is selected it will be shown later)
668 HWND hwnd = GetWinHwnd(pPage);
669 SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_VISIBLE);
670
671 // this updates internal flag too -- otherwise it would get out of sync
672 // with the real state
673 pPage->Show(false);
674
675
22f3361e
VZ
676 // fit the notebook page to the tab control's display area: this should be
677 // done before adding it to the notebook or TabCtrl_InsertItem() will
678 // change the notebooks size itself!
2015f2b3 679 AdjustPageSize(pPage);
43427087 680
22f3361e 681 // finally do insert it
2015f2b3
VZ
682 if ( TabCtrl_InsertItem(m_hwnd, nPage, &tcItem) == -1 )
683 {
22f3361e 684 wxLogError(wxT("Can't create the notebook page '%s'."), strText.c_str());
88310e2e 685
b8bdaa7c 686 return false;
22f3361e 687 }
88310e2e 688
22f3361e
VZ
689 // succeeded: save the pointer to the page
690 m_pages.Insert(pPage, nPage);
42e69d6b 691
56b9925b
VZ
692 // we may need to adjust the size again if the notebook size changed:
693 // normally this only happens for the first page we add (the tabs which
694 // hadn't been there before are now shown) but for a multiline notebook it
695 // can happen for any page at all as a new row could have been started
696 if ( m_pages.GetCount() == 1 || HasFlag(wxNB_MULTILINE) )
2015f2b3
VZ
697 {
698 AdjustPageSize(pPage);
699 }
700
22f3361e
VZ
701 // now deal with the selection
702 // ---------------------------
703
704 // if the inserted page is before the selected one, we must update the
705 // index of the selected page
34a0c9f4 706 if ( int(nPage) <= m_nSelection )
22f3361e
VZ
707 {
708 // one extra page added
709 m_nSelection++;
710 }
711
712 // some page should be selected: either this one or the first one if there
713 // is still no selection
714 int selNew = -1;
715 if ( bSelect )
716 selNew = nPage;
717 else if ( m_nSelection == -1 )
718 selNew = 0;
719
720 if ( selNew != -1 )
721 SetSelection(selNew);
722
37144cf0 723 InvalidateBestSize();
25057aba 724
b8bdaa7c 725 return true;
88310e2e
VZ
726}
727
e450aa69 728int wxNotebook::HitTest(const wxPoint& pt, long *flags) const
ef094fa0
JS
729{
730 TC_HITTESTINFO hitTestInfo;
731 hitTestInfo.pt.x = pt.x;
732 hitTestInfo.pt.y = pt.y;
e450aa69 733 int item = TabCtrl_HitTest(GetHwnd(), &hitTestInfo);
ef094fa0 734
e450aa69
VZ
735 if ( flags )
736 {
737 *flags = 0;
738
739 if ((hitTestInfo.flags & TCHT_NOWHERE) == TCHT_NOWHERE)
740 *flags |= wxNB_HITTEST_NOWHERE;
741 if ((hitTestInfo.flags & TCHT_ONITEM) == TCHT_ONITEM)
742 *flags |= wxNB_HITTEST_ONITEM;
743 if ((hitTestInfo.flags & TCHT_ONITEMICON) == TCHT_ONITEMICON)
744 *flags |= wxNB_HITTEST_ONICON;
745 if ((hitTestInfo.flags & TCHT_ONITEMLABEL) == TCHT_ONITEMLABEL)
746 *flags |= wxNB_HITTEST_ONLABEL;
747 }
ef094fa0
JS
748
749 return item;
750}
751
e450aa69 752
88310e2e
VZ
753// ----------------------------------------------------------------------------
754// wxNotebook callbacks
755// ----------------------------------------------------------------------------
756
9026ad85 757void wxNotebook::OnSize(wxSizeEvent& event)
88310e2e 758{
de371316 759#if wxUSE_UXTHEME
7dccdf81 760 // background bitmap size has changed, update the brush using it too
c1637c89 761 UpdateBgBrush();
de371316
VZ
762#endif // wxUSE_UXTHEME
763
7dccdf81 764 if ( GetPageCount() == 0 )
f7eaa62f
JS
765 {
766 // Prevents droppings on resize, but does cause some flicker
767 // when there are no pages.
768 Refresh(false);
769 event.Skip();
770 return;
771 }
772
c1637c89 773 // fit all the notebook pages to the tab control's display area
56b9925b 774
c1637c89
VZ
775 RECT rc;
776 rc.left = rc.top = 0;
777 GetSize((int *)&rc.right, (int *)&rc.bottom);
56b9925b 778
c1637c89
VZ
779 // save the total size, we'll use it below
780 int widthNbook = rc.right - rc.left,
781 heightNbook = rc.bottom - rc.top;
782
783 // there seems to be a bug in the implementation of TabCtrl_AdjustRect(): it
784 // returns completely false values for multiline tab controls after the tabs
785 // are added but before getting the first WM_SIZE (off by ~50 pixels, see
786 //
787 // http://sf.net/tracker/index.php?func=detail&aid=645323&group_id=9863&atid=109863
788 //
789 // and the only work around I could find was this ugly hack... without it
790 // simply toggling the "multiline" checkbox in the notebook sample resulted
791 // in a noticeable page displacement
792 if ( HasFlag(wxNB_MULTILINE) )
793 {
794 // avoid an infinite recursion: we get another notification too!
795 static bool s_isInOnSize = false;
4b7f2165 796
c1637c89
VZ
797 if ( !s_isInOnSize )
798 {
799 s_isInOnSize = true;
800 SendMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED,
801 MAKELPARAM(rc.right, rc.bottom));
802 s_isInOnSize = false;
803 }
804 }
b5c3b538 805
c1637c89
VZ
806 TabCtrl_AdjustRect(m_hwnd, false, &rc);
807
808 int width = rc.right - rc.left,
809 height = rc.bottom - rc.top;
810 size_t nCount = m_pages.Count();
811 for ( size_t nPage = 0; nPage < nCount; nPage++ ) {
812 wxNotebookPage *pPage = m_pages[nPage];
813 pPage->SetSize(rc.left, rc.top, width, height);
814 }
815
816
817 // unless we had already repainted everything, we now need to refresh
818 if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
819 {
820 // invalidate areas not covered by pages
821 RefreshRect(wxRect(0, 0, widthNbook, rc.top), false);
822 RefreshRect(wxRect(0, rc.top, rc.left, height), false);
823 RefreshRect(wxRect(0, rc.bottom, widthNbook, heightNbook - rc.bottom),
824 false);
825 RefreshRect(wxRect(rc.right, rc.top, widthNbook - rc.bottom, height),
826 false);
827 }
828
829 event.Skip();
88310e2e
VZ
830}
831
832void wxNotebook::OnSelChange(wxNotebookEvent& event)
833{
834 // is it our tab control?
835 if ( event.GetEventObject() == this )
5d1d2d46 836 {
5d1d2d46
VZ
837 int sel = event.GetOldSelection();
838 if ( sel != -1 )
b8bdaa7c 839 m_pages[sel]->Show(false);
0398b1d6 840
5d1d2d46
VZ
841 sel = event.GetSelection();
842 if ( sel != -1 )
843 {
1e6feb95 844 wxNotebookPage *pPage = m_pages[sel];
b8bdaa7c 845 pPage->Show(true);
1d5b3bf0
VZ
846 pPage->SetFocus();
847
848 // If the newly focused window is not a child of the new page,
849 // SetFocus was not successful and the notebook itself should be
850 // focused
851 wxWindow *currentFocus = FindFocus();
852 wxWindow *startFocus = currentFocus;
853 while ( currentFocus && currentFocus != pPage && currentFocus != this )
854 currentFocus = currentFocus->GetParent();
855
856 if ( startFocus == pPage || currentFocus != pPage )
857 SetFocus();
858
859 }
860 else // no pages in the notebook, give the focus to itself
861 {
862 SetFocus();
5d1d2d46 863 }
0398b1d6 864
5d1d2d46
VZ
865 m_nSelection = sel;
866 }
88310e2e
VZ
867
868 // we want to give others a chance to process this message as well
869 event.Skip();
870}
871
b8bdaa7c 872bool wxNotebook::MSWTranslateMessage(WXMSG *wxmsg)
88310e2e 873{
b8bdaa7c 874 const MSG * const msg = (MSG *)wxmsg;
88310e2e 875
1d5b3bf0
VZ
876 // intercept TAB, CTRL+TAB and CTRL+SHIFT+TAB for processing by wxNotebook.
877 // TAB will be passed to the currently selected page, CTRL+TAB and
878 // CTRL+SHIFT+TAB will be processed by the notebook itself. do not
879 // intercept SHIFT+TAB. This goes to the parent of the notebook which will
880 // process it.
b8bdaa7c
VZ
881 if ( msg->message == WM_KEYDOWN && msg->wParam == VK_TAB &&
882 msg->hwnd == m_hwnd &&
1d5b3bf0 883 (wxIsCtrlDown() || !wxIsShiftDown()) )
b8bdaa7c
VZ
884 {
885 return MSWProcessMessage(wxmsg);
886 }
d9506e77 887
b8bdaa7c 888 return false;
88310e2e
VZ
889}
890
891void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
892{
d9506e77
VZ
893 if ( event.IsWindowChange() ) {
894 // change pages
895 AdvanceSelection(event.GetDirection());
896 }
897 else {
b8bdaa7c 898 // we get this event in 3 cases
d9506e77
VZ
899 //
900 // a) one of our pages might have generated it because the user TABbed
901 // out from it in which case we should propagate the event upwards and
902 // our parent will take care of setting the focus to prev/next sibling
903 //
904 // or
905 //
906 // b) the parent panel wants to give the focus to us so that we
907 // forward it to our selected page. We can't deal with this in
908 // OnSetFocus() because we don't know which direction the focus came
909 // from in this case and so can't choose between setting the focus to
910 // first or last panel child
b8bdaa7c
VZ
911 //
912 // or
913 //
914 // c) we ourselves (see MSWTranslateMessage) generated the event
915 //
916 wxWindow * const parent = GetParent();
917
918 const bool isFromParent = event.GetEventObject() == parent;
919 const bool isFromSelf = event.GetEventObject() == this;
920
921 if ( isFromParent || isFromSelf )
d9506e77 922 {
b8bdaa7c
VZ
923 // no, it doesn't come from child, case (b) or (c): forward to a
924 // page but only if direction is backwards (TAB) or from ourselves,
925 if ( m_nSelection != -1 &&
926 (!event.GetDirection() || isFromSelf) )
d9506e77
VZ
927 {
928 // so that the page knows that the event comes from it's parent
929 // and is being propagated downwards
930 event.SetEventObject(this);
931
1e6feb95 932 wxWindow *page = m_pages[m_nSelection];
d9506e77
VZ
933 if ( !page->GetEventHandler()->ProcessEvent(event) )
934 {
935 page->SetFocus();
936 }
937 //else: page manages focus inside it itself
938 }
b8bdaa7c 939 else // otherwise set the focus to the notebook itself
d9506e77 940 {
d9506e77
VZ
941 SetFocus();
942 }
943 }
944 else
945 {
b8bdaa7c
VZ
946 // it comes from our child, case (a), pass to the parent, but only
947 // if the direction is forwards. Otherwise set the focus to the
948 // notebook itself. The notebook is always the 'first' control of a
949 // page.
950 if ( !event.GetDirection() )
951 {
952 SetFocus();
953 }
954 else if ( parent )
955 {
d9506e77
VZ
956 event.SetCurrentFocus(this);
957 parent->GetEventHandler()->ProcessEvent(event);
958 }
959 }
88310e2e 960 }
88310e2e
VZ
961}
962
caf95d2a
VZ
963#if wxUSE_UXTHEME
964
de359565 965WXHBRUSH wxNotebook::QueryBgBitmap()
caf95d2a 966{
c4a95f6f 967 RECT rc;
de359565
VZ
968 ::GetClientRect(GetHwnd(), &rc);
969
970 // adjust position
971 TabCtrl_AdjustRect(GetHwnd(), false, &rc);
c4a95f6f
VZ
972
973 WindowHDC hDC(GetHwnd());
974 MemoryHDC hDCMem(hDC);
de359565 975 CompatibleBitmap hBmp(hDC, rc.right, rc.bottom);
c4a95f6f
VZ
976
977 SelectInHDC selectBmp(hDCMem, hBmp);
caf95d2a 978
de359565
VZ
979 wxUxThemeHandle theme(this, L"TAB");
980 if ( theme )
caf95d2a 981 {
de359565 982 AdjustRectForThemeBg(rc);
caf95d2a 983
de359565
VZ
984 wxUxThemeEngine::Get()->DrawThemeBackground
985 (
986 theme,
987 (WXHDC)hDCMem,
988 9 /* TABP_PANE */,
989 0,
990 &rc,
991 NULL
992 );
c4a95f6f 993 }
0f770734 994
de359565 995 return (WXHBRUSH)::CreatePatternBrush(hBmp);
c4a95f6f 996}
caf95d2a 997
c4a95f6f
VZ
998void wxNotebook::UpdateBgBrush()
999{
1000 if ( m_hbrBackground )
1001 ::DeleteObject((HBRUSH)m_hbrBackground);
caf95d2a 1002
c4a95f6f
VZ
1003 if ( !m_hasBgCol && wxUxThemeEngine::GetIfActive() )
1004 {
de359565 1005 m_hbrBackground = QueryBgBitmap();
caf95d2a
VZ
1006 }
1007 else // no themes
1008 {
1009 m_hbrBackground = NULL;
1010 }
1011}
1012
c4a95f6f 1013WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, wxWindow *win)
caf95d2a 1014{
caf95d2a
VZ
1015 if ( m_hbrBackground )
1016 {
1017 // before drawing with the background brush, we need to position it
1018 // correctly
caf95d2a
VZ
1019 RECT rc;
1020 ::GetWindowRect(GetHwndOf(win), &rc);
1021
1022 ::MapWindowPoints(NULL, GetHwnd(), (POINT *)&rc, 1);
1023
5c836c46 1024 if ( !::SetBrushOrgEx((HDC)hDC, -rc.left, -rc.top, NULL) )
caf95d2a
VZ
1025 {
1026 wxLogLastError(_T("SetBrushOrgEx(notebook bg brush)"));
1027 }
c4a95f6f
VZ
1028
1029 return m_hbrBackground;
5c836c46
VZ
1030 }
1031
c4a95f6f 1032 return wxNotebookBase::MSWGetBgBrushForChild(hDC, win);
5c836c46 1033}
caf95d2a 1034
de359565 1035wxColour wxNotebook::MSWGetBgColourForChild(wxWindow *WXUNUSED(win))
9b7d2b81 1036{
c4a95f6f
VZ
1037 if ( m_hasBgCol )
1038 return GetBackgroundColour();
9b7d2b81 1039
b554cf63
JS
1040 // Experimental: don't do this since we're doing it in wxPanel
1041#if 0 // defined(__POCKETPC__) || defined(__SMARTPHONE__)
1042 // For some reason, the pages will be grey by default.
1043 // Normally they should be white on these platforms.
1044 // (However the static control backgrounds are painted
1045 // in the correct colour, just not the rest of it.)
1046 // So let's give WinCE a hint.
1047 else if (!win->m_hasBgCol)
1048 return *wxWHITE;
1049#endif
1050
c4a95f6f
VZ
1051 if ( !wxUxThemeEngine::GetIfActive() )
1052 return wxNullColour;
1053
de359565 1054 return GetThemeBackgroundColour();
caf95d2a
VZ
1055}
1056
07c19327
VZ
1057bool
1058wxNotebook::MSWPrintChild(wxWindow *win,
1059 WXWPARAM wParam,
1060 WXLPARAM WXUNUSED(lParam))
1061{
de359565 1062 // Don't paint the theme for the child if we have a solid background
7dccdf81 1063 if ( m_hasBgCol )
3534fc20 1064 return false;
de359565
VZ
1065
1066
07c19327
VZ
1067 RECT rc;
1068 ::GetClientRect(GetHwnd(), &rc);
de359565
VZ
1069
1070 // adjust position
1071 TabCtrl_AdjustRect(GetHwnd(), false, &rc);
07c19327
VZ
1072
1073 wxUxThemeHandle theme(win, L"TAB");
1074 if ( theme )
1075 {
de359565
VZ
1076 // map from this client to win client coords
1077 ::MapWindowPoints(GetHwnd(), GetHwndOf(win), (POINT *)&rc, 2);
1078
1079 AdjustRectForThemeBg(rc);
07c19327
VZ
1080 wxUxThemeEngine::Get()->DrawThemeBackground
1081 (
1082 theme,
1083 (WXHDC)wParam,
1084 9 /* TABP_PANE */,
1085 0,
1086 &rc,
1087 NULL
1088 );
1089 }
1090
1091 return true;
1092}
1093
caf95d2a
VZ
1094#endif // wxUSE_UXTHEME
1095
25057aba
JS
1096// Windows only: attempts to get colour for UX theme page background
1097wxColour wxNotebook::GetThemeBackgroundColour() const
1098{
1099#if wxUSE_UXTHEME
1100 if (wxUxThemeEngine::Get())
1101 {
1102 wxUxThemeHandle hTheme((wxNotebook*) this, L"TAB");
1103 if (hTheme)
1104 {
1105 // This is total guesswork.
1106 // See PlatformSDK\Include\Tmschema.h for values
1107 COLORREF themeColor;
1108 wxUxThemeEngine::Get()->GetThemeColor(
1109 hTheme,
1110 10 /* TABP_BODY */,
1111 1 /* NORMAL */,
1112 3821 /* FILLCOLORHINT */,
1113 &themeColor);
1114
1115 /*
1116 [DS] Workaround for WindowBlinds:
1117 Some themes return a near black theme color using FILLCOLORHINT,
1118 this makes notebook pages have an ugly black background and makes
1119 text (usually black) unreadable. Retry again with FILLCOLOR.
1120
1121 This workaround potentially breaks appearance of some themes,
1122 but in practice it already fixes some themes.
1123 */
1124 if (themeColor == 1)
1125 {
1126 wxUxThemeEngine::Get()->GetThemeColor(
1127 hTheme,
1128 10 /* TABP_BODY */,
1129 1 /* NORMAL */,
1130 3802 /* FILLCOLOR */,
1131 &themeColor);
1132 }
1133
7dccdf81 1134 return wxRGBToColour(themeColor);
25057aba
JS
1135 }
1136 }
1137#endif // wxUSE_UXTHEME
1138
1139 return GetBackgroundColour();
1140}
1141
88310e2e
VZ
1142// ----------------------------------------------------------------------------
1143// wxNotebook base class virtuals
1144// ----------------------------------------------------------------------------
b5c3b538 1145
0b481c72
VZ
1146#if wxUSE_CONSTRAINTS
1147
b5c3b538
VZ
1148// override these 2 functions to do nothing: everything is done in OnSize
1149
4b7f2165 1150void wxNotebook::SetConstraintSizes(bool WXUNUSED(recurse))
b5c3b538
VZ
1151{
1152 // don't set the sizes of the pages - their correct size is not yet known
b8bdaa7c 1153 wxControl::SetConstraintSizes(false);
b5c3b538
VZ
1154}
1155
4b7f2165 1156bool wxNotebook::DoPhase(int WXUNUSED(nPhase))
b5c3b538 1157{
b8bdaa7c 1158 return true;
b5c3b538
VZ
1159}
1160
0b481c72
VZ
1161#endif // wxUSE_CONSTRAINTS
1162
0df3fbd7
VZ
1163// ----------------------------------------------------------------------------
1164// wxNotebook Windows message handlers
1165// ----------------------------------------------------------------------------
1166
1167bool wxNotebook::MSWOnScroll(int orientation, WXWORD nSBCode,
1168 WXWORD pos, WXHWND control)
1169{
1170 // don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the
1171 // up-down control
1172 if ( control )
b8bdaa7c 1173 return false;
0df3fbd7
VZ
1174
1175 return wxNotebookBase::MSWOnScroll(orientation, nSBCode, pos, control);
1176}
1177
a23fd0e1 1178bool wxNotebook::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result)
88310e2e 1179{
93a19f17 1180 wxNotebookEvent event(wxEVT_NULL, m_windowId);
88310e2e
VZ
1181
1182 NMHDR* hdr = (NMHDR *)lParam;
1183 switch ( hdr->code ) {
1184 case TCN_SELCHANGE:
1185 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
1186 break;
1187
1188 case TCN_SELCHANGING:
1189 event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING);
1190 break;
1191
fd3f686c 1192 default:
a23fd0e1 1193 return wxControl::MSWOnNotify(idCtrl, lParam, result);
88310e2e
VZ
1194 }
1195
93a19f17
VZ
1196 event.SetSelection(TabCtrl_GetCurSel(m_hwnd));
1197 event.SetOldSelection(m_nSelection);
88310e2e 1198 event.SetEventObject(this);
a23fd0e1 1199 event.SetInt(idCtrl);
88310e2e 1200
fd3f686c
VZ
1201 bool processed = GetEventHandler()->ProcessEvent(event);
1202 *result = !event.IsAllowed();
1203 return processed;
88310e2e
VZ
1204}
1205
1e6feb95 1206#endif // wxUSE_NOTEBOOK