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