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