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