]> git.saurik.com Git - wxWidgets.git/blob - src/generic/mdig.cpp
Applied patch [ 642157 ] [MSW] HMENU resource leak from wxMenuBar
[wxWidgets.git] / src / generic / mdig.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/mdig.cpp
3 // Purpose: Generic MDI (Multiple Document Interface) classes
4 // Author: Hans Van Leemputten
5 // Modified by:
6 // Created: 29/07/2002
7 // RCS-ID: $Id$
8 // Copyright: (c) Hans Van Leemputten
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "mdig.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/panel.h"
33 #include "wx/menu.h"
34 #include "wx/intl.h"
35 #endif //WX_PRECOMP
36
37 #include "wx/generic/mdig.h"
38
39 enum MDI_MENU_ID
40 {
41 wxWINDOWCLOSE = 4001,
42 wxWINDOWCLOSEALL,
43 wxWINDOWNEXT,
44 wxWINDOWPREV
45 };
46
47 //-----------------------------------------------------------------------------
48 // wxGenericMDIParentFrame
49 //-----------------------------------------------------------------------------
50
51 IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)
52
53 BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
54 EVT_MENU (-1, wxGenericMDIParentFrame::DoHandleMenu)
55 END_EVENT_TABLE()
56
57 wxGenericMDIParentFrame::wxGenericMDIParentFrame()
58 {
59 Init();
60 }
61
62 wxGenericMDIParentFrame::wxGenericMDIParentFrame(wxWindow *parent,
63 wxWindowID id,
64 const wxString& title,
65 const wxPoint& pos,
66 const wxSize& size,
67 long style,
68 const wxString& name)
69 {
70 Init();
71
72 (void)Create(parent, id, title, pos, size, style, name);
73 }
74
75 wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
76 {
77 // Make sure the client window is destructed before the menu bars are!
78 wxDELETE(m_pClientWindow);
79
80 #if wxUSE_MENUS
81 if (m_pMyMenuBar)
82 {
83 delete m_pMyMenuBar;
84 m_pMyMenuBar = (wxMenuBar *) NULL;
85 }
86
87 RemoveWindowMenu(GetMenuBar());
88
89 if (m_pWindowMenu)
90 {
91 delete m_pWindowMenu;
92 m_pWindowMenu = (wxMenu*) NULL;
93 }
94 #endif // wxUSE_MENUS
95 }
96
97 bool wxGenericMDIParentFrame::Create(wxWindow *parent,
98 wxWindowID id,
99 const wxString& title,
100 const wxPoint& pos,
101 const wxSize& size,
102 long style,
103 const wxString& name)
104 {
105 // this style can be used to prevent a window from having the standard MDI
106 // "Window" menu
107 if ( !(style & wxFRAME_NO_WINDOW_MENU) )
108 {
109 #if wxUSE_MENUS
110 m_pWindowMenu = new wxMenu;
111
112 m_pWindowMenu->Append(wxWINDOWCLOSE, _("Cl&ose"));
113 m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
114 m_pWindowMenu->AppendSeparator();
115 m_pWindowMenu->Append(wxWINDOWNEXT, _("&Next"));
116 m_pWindowMenu->Append(wxWINDOWPREV, _("&Previous"));
117 #endif // wxUSE_MENUS
118 }
119
120 wxFrame::Create( parent, id, title, pos, size, style, name );
121
122 OnCreateClient();
123
124 return TRUE;
125 }
126
127 #if wxUSE_MENUS
128 void wxGenericMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
129 {
130 // Replace the window menu from the currently loaded menu bar.
131 wxMenuBar *pMenuBar = GetMenuBar();
132
133 if (m_pWindowMenu)
134 {
135 RemoveWindowMenu(pMenuBar);
136
137 wxDELETE(m_pWindowMenu);
138 }
139
140 if (pMenu)
141 {
142 m_pWindowMenu = pMenu;
143
144 AddWindowMenu(pMenuBar);
145 }
146 }
147
148 void wxGenericMDIParentFrame::SetMenuBar(wxMenuBar *pMenuBar)
149 {
150 // Remove the Window menu from the old menu bar
151 RemoveWindowMenu(GetMenuBar());
152 // Add the Window menu to the new menu bar.
153 AddWindowMenu(pMenuBar);
154
155 wxFrame::SetMenuBar(pMenuBar);
156 }
157 #endif // wxUSE_MENUS
158
159 void wxGenericMDIParentFrame::SetChildMenuBar(wxGenericMDIChildFrame *pChild)
160 {
161 #if wxUSE_MENUS
162 if (pChild == (wxGenericMDIChildFrame *) NULL)
163 {
164 // No Child, set Our menu bar back.
165 SetMenuBar(m_pMyMenuBar);
166
167 // Make sure we know our menu bar is in use
168 m_pMyMenuBar = (wxMenuBar*) NULL;
169 }
170 else
171 {
172 if (pChild->GetMenuBar() == (wxMenuBar*) NULL)
173 return;
174
175 // Do we need to save the current bar?
176 if (m_pMyMenuBar == NULL)
177 m_pMyMenuBar = GetMenuBar();
178
179 SetMenuBar(pChild->GetMenuBar());
180 }
181 #endif // wxUSE_MENUS
182 }
183
184 bool wxGenericMDIParentFrame::ProcessEvent(wxEvent& event)
185 {
186 /*
187 * Redirect events to active child first.
188 */
189
190 // Stops the same event being processed repeatedly
191 static wxEventType inEvent = wxEVT_NULL;
192 if (inEvent == event.GetEventType())
193 return FALSE;
194
195 inEvent = event.GetEventType();
196
197 // Let the active child (if any) process the event first.
198 bool res = FALSE;
199 if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
200 #if 0
201 /* This is sure to not give problems... */
202 && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
203 event.GetEventType() == wxEVT_UPDATE_UI )
204 #else
205 /* This was tested on wxMSW and worked... */
206 && event.GetEventObject() != m_pClientWindow
207 && !(event.GetEventType() == wxEVT_ACTIVATE ||
208 event.GetEventType() == wxEVT_SET_FOCUS ||
209 event.GetEventType() == wxEVT_KILL_FOCUS ||
210 event.GetEventType() == wxEVT_CHILD_FOCUS ||
211 event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
212 event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
213 #endif
214 )
215 {
216 res = m_pActiveChild->GetEventHandler()->ProcessEvent(event);
217 }
218
219 // If the event was not handled this frame will handle it!
220 if (!res)
221 {
222 res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
223 }
224
225 inEvent = wxEVT_NULL;
226
227 return res;
228 }
229
230 wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
231 {
232 return m_pActiveChild;
233 }
234
235 void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
236 {
237 m_pActiveChild = pChildFrame;
238 }
239
240 wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
241 {
242 return m_pClientWindow;
243 }
244
245 wxGenericMDIClientWindow *wxGenericMDIParentFrame::OnCreateClient()
246 {
247 #if wxUSE_GENERIC_MDI_AS_NATIVE
248 m_pClientWindow = new wxMDIClientWindow( this );
249 #else
250 m_pClientWindow = new wxGenericMDIClientWindow( this );
251 #endif
252 return m_pClientWindow;
253 }
254
255 void wxGenericMDIParentFrame::ActivateNext()
256 {
257 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
258 {
259 int active = m_pClientWindow->GetSelection() + 1;
260 if (active >= m_pClientWindow->GetPageCount())
261 active = 0;
262
263 m_pClientWindow->SetSelection(active);
264 }
265 }
266
267 void wxGenericMDIParentFrame::ActivatePrevious()
268 {
269 if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
270 {
271 int active = m_pClientWindow->GetSelection() - 1;
272 if (active < 0)
273 active = m_pClientWindow->GetPageCount() - 1;
274
275 m_pClientWindow->SetSelection(active);
276 }
277 }
278
279 void wxGenericMDIParentFrame::Init()
280 {
281 m_pClientWindow = (wxGenericMDIClientWindow *) NULL;
282 m_pActiveChild = (wxGenericMDIChildFrame *) NULL;
283 #if wxUSE_MENUS
284 m_pWindowMenu = (wxMenu *) NULL;
285 m_pMyMenuBar = (wxMenuBar*) NULL;
286 #endif // wxUSE_MENUS
287 }
288
289 #if wxUSE_MENUS
290 void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
291 {
292 if (pMenuBar && m_pWindowMenu)
293 {
294 // Remove old window menu
295 int pos = pMenuBar->FindMenu(_("&Window"));
296 if (pos != wxNOT_FOUND)
297 {
298 wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos)); // DBG:: We're going to delete the wrong menu!!!
299 pMenuBar->Remove(pos);
300 }
301 }
302 }
303
304 void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
305 {
306 if (pMenuBar && m_pWindowMenu)
307 {
308 int pos = pMenuBar->FindMenu(_("Help"));
309 if (pos == wxNOT_FOUND)
310 {
311 pMenuBar->Append(m_pWindowMenu, _("&Window"));
312 }
313 else
314 {
315 pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
316 }
317 }
318 }
319
320 void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
321 {
322 switch (event.GetId())
323 {
324 case wxWINDOWCLOSE:
325 if (m_pActiveChild)
326 {
327 m_pActiveChild->Close();
328 }
329 break;
330 case wxWINDOWCLOSEALL:
331 {
332 #if 0 // code is only needed if next #if is set to 0!
333 wxGenericMDIChildFrame *pFirstActiveChild = m_pActiveChild;
334 #endif
335 while (m_pActiveChild)
336 {
337 if (!m_pActiveChild->Close())
338 {
339 return; // We failed...
340 }
341 else
342 {
343 #if 1 // What's best? Delayed deleting or immediate deleting?
344 delete m_pActiveChild;
345 #else
346 ActivateNext();
347
348 if (pFirstActiveChild == m_pActiveChild)
349 return; // We've called Close on all items, no need to continue.
350 #endif
351 }
352 }
353 }
354 break;
355 case wxWINDOWNEXT:
356 ActivateNext();
357 break;
358 case wxWINDOWPREV:
359 ActivatePrevious();
360 break;
361 default :
362 event.Skip();
363 }
364 }
365 #endif // wxUSE_MENUS
366
367 void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
368 {
369 wxFrame::DoGetClientSize( width, height );
370 }
371
372
373 //-----------------------------------------------------------------------------
374 // wxGenericMDIChildFrame
375 //-----------------------------------------------------------------------------
376
377 IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)
378
379 BEGIN_EVENT_TABLE(wxGenericMDIChildFrame, wxPanel)
380 EVT_MENU_HIGHLIGHT_ALL(wxGenericMDIChildFrame::OnMenuHighlight)
381 EVT_ACTIVATE(wxGenericMDIChildFrame::OnActivate)
382
383 EVT_CLOSE(wxGenericMDIChildFrame::OnCloseWindow)
384 EVT_SIZE(wxGenericMDIChildFrame::OnSize)
385 END_EVENT_TABLE()
386
387 wxGenericMDIChildFrame::wxGenericMDIChildFrame()
388 {
389 Init();
390 }
391
392 wxGenericMDIChildFrame::wxGenericMDIChildFrame( wxGenericMDIParentFrame *parent,
393 wxWindowID id, const wxString& title,
394 const wxPoint& WXUNUSED(pos), const wxSize& size,
395 long style, const wxString& name )
396 {
397 Init();
398
399 Create( parent, id, title, wxDefaultPosition, size, style, name );
400 }
401
402 #include "wx/log.h"
403 wxGenericMDIChildFrame::~wxGenericMDIChildFrame()
404 {
405 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
406
407 if (pParentFrame != NULL)
408 {
409 bool bActive = FALSE;
410 if (pParentFrame->GetActiveChild() == this)
411 {
412 pParentFrame->SetActiveChild((wxGenericMDIChildFrame*) NULL);
413 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
414 bActive = TRUE;
415 }
416
417 wxGenericMDIClientWindow *pClientWindow = pParentFrame->GetClientWindow();
418
419 // Remove page if still there
420 int pos;
421 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
422 {
423 if (pClientWindow->GetPage(pos) == this)
424 {
425 if (pClientWindow->RemovePage(pos))
426 pClientWindow->Refresh();
427 break;
428 }
429 }
430
431 if (bActive)
432 {
433 // Set the new selection to the a remaining page
434 if (pClientWindow->GetPageCount() > pos)
435 {
436 pClientWindow->SetSelection(pos);
437 }
438 else
439 {
440 if (pClientWindow->GetPageCount() - 1 >= 0)
441 pClientWindow->SetSelection(pClientWindow->GetPageCount() - 1);
442 }
443 }
444 }
445
446 #if wxUSE_MENUS
447 wxDELETE(m_pMenuBar);
448 #endif // wxUSE_MENUS
449 }
450
451 bool wxGenericMDIChildFrame::Create( wxGenericMDIParentFrame *parent,
452 wxWindowID id, const wxString& title,
453 const wxPoint& WXUNUSED(pos), const wxSize& size,
454 long style, const wxString& name )
455 {
456 wxGenericMDIClientWindow* pClientWindow = parent->GetClientWindow();
457
458 wxASSERT_MSG((pClientWindow != (wxWindow*) NULL), wxT("Missing MDI client window.") );
459
460 wxPanel::Create(pClientWindow, id, wxDefaultPosition, size, style, name);
461
462 SetMDIParentFrame(parent);
463
464 // This is the currently active child
465 parent->SetActiveChild(this);
466
467 m_Title = title;
468
469 pClientWindow->AddPage(this, title, TRUE);
470 ApplyMDIChildFrameRect(); // Ok confirme the size change!
471 pClientWindow->Refresh();
472
473 return TRUE;
474 }
475
476 #if wxUSE_MENUS
477 void wxGenericMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar )
478 {
479 wxMenuBar *pOldMenuBar = m_pMenuBar;
480 m_pMenuBar = menu_bar;
481
482 if (m_pMenuBar)
483 {
484 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
485
486 if (pParentFrame != NULL)
487 {
488 m_pMenuBar->SetParent(pParentFrame);
489
490 if (pParentFrame->GetActiveChild() == this)
491 {
492 // Replace current menu bars
493 if (pOldMenuBar)
494 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) NULL);
495 pParentFrame->SetChildMenuBar((wxGenericMDIChildFrame*) this);
496 }
497 }
498 }
499 }
500
501 wxMenuBar *wxGenericMDIChildFrame::GetMenuBar() const
502 {
503 return m_pMenuBar;
504 }
505 #endif // wxUSE_MENUS
506
507 void wxGenericMDIChildFrame::SetTitle(const wxString& title)
508 {
509 m_Title = title;
510
511 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
512
513 if (pParentFrame != NULL)
514 {
515 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
516
517 if (pClientWindow != NULL)
518 {
519 int pos;
520 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
521 {
522 if (pClientWindow->GetPage(pos) == this)
523 {
524 pClientWindow->SetPageText(pos, m_Title);
525 break;
526 }
527 }
528 }
529 }
530 }
531
532 wxString wxGenericMDIChildFrame::GetTitle() const
533 {
534 return m_Title;
535 }
536
537 void wxGenericMDIChildFrame::Activate()
538 {
539 wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();
540
541 if (pParentFrame != NULL)
542 {
543 wxGenericMDIClientWindow * pClientWindow = pParentFrame->GetClientWindow();
544
545 if (pClientWindow != NULL)
546 {
547 int pos;
548 for (pos = 0; pos < pClientWindow->GetPageCount(); pos++)
549 {
550 if (pClientWindow->GetPage(pos) == this)
551 {
552 pClientWindow->SetSelection(pos);
553 break;
554 }
555 }
556 }
557 }
558 }
559
560 void wxGenericMDIChildFrame::OnMenuHighlight(wxMenuEvent& event)
561 {
562 #if wxUSE_STATUSBAR
563 if ( m_pMDIParentFrame)
564 {
565 // we don't have any help text for this item,
566 // but may be the MDI frame does?
567 m_pMDIParentFrame->OnMenuHighlight(event);
568 }
569 #endif // wxUSE_STATUSBAR
570 }
571
572 void wxGenericMDIChildFrame::OnActivate(wxActivateEvent& event)
573 {
574 // Do mothing.
575 }
576
577 /*** Copied from top level..! ***/
578 // default resizing behaviour - if only ONE subwindow, resize to fill the
579 // whole client area
580 void wxGenericMDIChildFrame::OnSize(wxSizeEvent& WXUNUSED(event))
581 {
582 // if we're using constraints or sizers - do use them
583 if ( GetAutoLayout() )
584 {
585 Layout();
586 }
587 else
588 {
589 // do we have _exactly_ one child?
590 wxWindow *child = (wxWindow *)NULL;
591 for ( wxWindowList::Node *node = GetChildren().GetFirst();
592 node;
593 node = node->GetNext() )
594 {
595 wxWindow *win = node->GetData();
596
597 // exclude top level and managed windows (status bar isn't
598 // currently in the children list except under wxMac anyhow, but
599 // it makes no harm to test for it)
600 if ( !win->IsTopLevel() /*&& !IsOneOfBars(win)*/ )
601 {
602 if ( child )
603 {
604 return; // it's our second subwindow - nothing to do
605 }
606
607 child = win;
608 }
609 }
610
611 // do we have any children at all?
612 if ( child )
613 {
614 // exactly one child - set it's size to fill the whole frame
615 int clientW, clientH;
616 DoGetClientSize(&clientW, &clientH);
617
618 // for whatever reasons, wxGTK wants to have a small offset - it
619 // probably looks better with it?
620 #ifdef __WXGTK__
621 static const int ofs = 1;
622 #else
623 static const int ofs = 0;
624 #endif
625
626 child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
627 }
628 }
629 }
630
631 /*** Copied from top level..! ***/
632 // The default implementation for the close window event.
633 void wxGenericMDIChildFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
634 {
635 Destroy();
636 }
637
638 void wxGenericMDIChildFrame::SetMDIParentFrame(wxGenericMDIParentFrame* parentFrame)
639 {
640 m_pMDIParentFrame = parentFrame;
641 }
642
643 wxGenericMDIParentFrame* wxGenericMDIChildFrame::GetMDIParentFrame() const
644 {
645 return m_pMDIParentFrame;
646 }
647
648 void wxGenericMDIChildFrame::Init()
649 {
650 m_pMDIParentFrame = (wxGenericMDIParentFrame *) NULL;
651 #if wxUSE_MENUS
652 m_pMenuBar = (wxMenuBar *) NULL;
653 #endif // wxUSE_MENUS
654 }
655
656 void wxGenericMDIChildFrame::DoMoveWindow(int x, int y, int width, int height)
657 {
658 m_MDIRect = wxRect(x, y, width, height);
659 }
660
661 void wxGenericMDIChildFrame::ApplyMDIChildFrameRect()
662 {
663 wxPanel::DoMoveWindow(m_MDIRect.x, m_MDIRect.y, m_MDIRect.width, m_MDIRect.height);
664 }
665
666 //-----------------------------------------------------------------------------
667 // wxGenericMDIClientWindow
668 //-----------------------------------------------------------------------------
669
670 #define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100
671
672 IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIClientWindow, wxNotebook)
673
674 BEGIN_EVENT_TABLE(wxGenericMDIClientWindow, wxNotebook)
675 EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxGenericMDIClientWindow::OnPageChanged)
676 EVT_SIZE(wxGenericMDIClientWindow::OnSize)
677 END_EVENT_TABLE()
678
679
680 wxGenericMDIClientWindow::wxGenericMDIClientWindow()
681 {
682 }
683
684 wxGenericMDIClientWindow::wxGenericMDIClientWindow( wxGenericMDIParentFrame *parent, long style )
685 {
686 CreateClient( parent, style );
687 }
688
689 wxGenericMDIClientWindow::~wxGenericMDIClientWindow()
690 {
691 DestroyChildren();
692 }
693
694 bool wxGenericMDIClientWindow::CreateClient( wxGenericMDIParentFrame *parent, long style )
695 {
696 SetWindowStyleFlag(style);
697
698 bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0);
699 if (success)
700 {
701 /*
702 wxFont font(10, wxSWISS, wxNORMAL, wxNORMAL);
703 wxFont selFont(10, wxSWISS, wxNORMAL, wxBOLD);
704 GetTabView()->SetTabFont(font);
705 GetTabView()->SetSelectedTabFont(selFont);
706 GetTabView()->SetTabSize(120, 18);
707 GetTabView()->SetTabSelectionHeight(20);
708 */
709 return TRUE;
710 }
711 else
712 return FALSE;
713 }
714
715 int wxGenericMDIClientWindow::SetSelection(int nPage)
716 {
717 int oldSelection = wxNotebook::SetSelection(nPage);
718
719 #if !defined(__WXMSW__) // No need to do this for wxMSW as wxNotebook::SetSelection()
720 // will already cause this to be done!
721 // Handle the page change.
722 PageChanged(oldSelection, nPage);
723 #endif
724
725 return oldSelection;
726 }
727
728 void wxGenericMDIClientWindow::PageChanged(int OldSelection, int newSelection)
729 {
730 // Don't do to much work, only when something realy should change!
731 if (OldSelection == newSelection)
732 return;
733 // Again check if we realy need to do this...
734 if (newSelection != -1)
735 {
736 wxGenericMDIChildFrame* child = (wxGenericMDIChildFrame *)GetPage(newSelection);
737
738 if (child->GetMDIParentFrame()->GetActiveChild() == child)
739 return;
740 }
741
742 // Notify old active child that it has been deactivated
743 if (OldSelection != -1)
744 {
745 wxGenericMDIChildFrame* oldChild = (wxGenericMDIChildFrame *)GetPage(OldSelection);
746 if (oldChild)
747 {
748 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, oldChild->GetId());
749 event.SetEventObject( oldChild );
750 oldChild->GetEventHandler()->ProcessEvent(event);
751 }
752 }
753
754 // Notify new active child that it has been activated
755 if (newSelection != -1)
756 {
757 wxGenericMDIChildFrame* activeChild = (wxGenericMDIChildFrame *)GetPage(newSelection);
758 if (activeChild)
759 {
760 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, activeChild->GetId());
761 event.SetEventObject( activeChild );
762 activeChild->GetEventHandler()->ProcessEvent(event);
763
764 if (activeChild->GetMDIParentFrame())
765 {
766 activeChild->GetMDIParentFrame()->SetActiveChild(activeChild);
767 activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild);
768 }
769 }
770 }
771 }
772
773 void wxGenericMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
774 {
775 PageChanged(event.GetOldSelection(), event.GetSelection());
776
777 event.Skip();
778 }
779
780 void wxGenericMDIClientWindow::OnSize(wxSizeEvent& event)
781 {
782 wxNotebook::OnSize(event);
783
784 int pos;
785 for (pos = 0; pos < GetPageCount(); pos++)
786 {
787 ((wxGenericMDIChildFrame *)GetPage(pos))->ApplyMDIChildFrameRect();
788 }
789 }
790
791
792 /*
793 * Define normal wxMDI classes based on wxGenericMDI
794 */
795
796 #if wxUSE_GENERIC_MDI_AS_NATIVE
797
798 wxMDIChildFrame * wxMDIParentFrame::GetActiveChild() const
799 {
800 wxGenericMDIChildFrame *pGFrame = wxGenericMDIParentFrame::GetActiveChild();
801 wxMDIChildFrame *pFrame = wxDynamicCast(pGFrame, wxMDIChildFrame);
802
803 wxASSERT_MSG(!(pFrame == NULL && pGFrame != NULL), wxT("Active frame is class not derived from wxMDIChildFrame!"));
804
805 return pFrame;
806 }
807
808 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxGenericMDIParentFrame)
809 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxGenericMDIChildFrame)
810 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxGenericMDIClientWindow)
811
812 #endif
813