1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: MDI classes
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
21 #pragma implementation "mdi.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
37 #include "wx/dialog.h"
38 #include "wx/statusbr.h"
39 #include "wx/settings.h"
43 #include "wx/msw/private.h"
45 #if wxUSE_NATIVE_STATUSBAR
46 #include <wx/msw/statbr95.h>
51 // ---------------------------------------------------------------------------
53 // ---------------------------------------------------------------------------
55 extern wxWindowList wxModelessWindows
; // from dialog.cpp
56 extern wxMenu
*wxCurrentPopupMenu
;
58 extern char wxMDIFrameClassName
[];
59 extern char wxMDIChildFrameClassName
[];
60 extern wxWindow
*wxWndHook
; // from window.cpp
62 extern wxList
*wxWinHandleList
;
64 // ---------------------------------------------------------------------------
66 // ---------------------------------------------------------------------------
68 static const int IDM_WINDOWTILE
= 4001;
69 static const int IDM_WINDOWCASCADE
= 4002;
70 static const int IDM_WINDOWICONS
= 4003;
71 static const int IDM_WINDOWNEXT
= 4004;
73 // This range gives a maximum of 500 MDI children. Should be enough :-)
74 static const int wxFIRST_MDI_CHILD
= 4100;
75 static const int wxLAST_MDI_CHILD
= 4600;
77 // Status border dimensions
78 static const int wxTHICK_LINE_BORDER
= 3;
79 static const int wxTHICK_LINE_WIDTH
= 1;
81 // ===========================================================================
83 // ===========================================================================
85 // ---------------------------------------------------------------------------
87 // ---------------------------------------------------------------------------
89 #if !USE_SHARED_LIBRARY
90 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
, wxFrame
)
91 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
, wxFrame
)
92 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
, wxWindow
)
93 #endif // USE_SHARED_LIBRARY
95 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
)
96 EVT_SIZE(wxMDIParentFrame::OnSize
)
97 EVT_ACTIVATE(wxMDIParentFrame::OnActivate
)
98 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged
)
101 BEGIN_EVENT_TABLE(wxMDIClientWindow
, wxWindow
)
102 EVT_SCROLL(wxMDIClientWindow::OnScroll
)
105 // ---------------------------------------------------------------------------
107 // ---------------------------------------------------------------------------
109 wxMDIParentFrame::wxMDIParentFrame()
111 m_clientWindow
= NULL
;
112 m_currentChild
= NULL
;
114 m_parentFrameActive
= TRUE
;
117 bool wxMDIParentFrame::Create(wxWindow
*parent
,
119 const wxString
& title
,
123 const wxString
& name
)
125 m_defaultIcon
= (WXHICON
) (wxSTD_MDIPARENTFRAME_ICON
? wxSTD_MDIPARENTFRAME_ICON
: wxDEFAULT_MDIPARENTFRAME_ICON
);
127 m_clientWindow
= NULL
;
128 m_currentChild
= NULL
;
130 m_parentFrameActive
= TRUE
;
133 wxTopLevelWindows
.Append(this);
136 m_windowStyle
= style
;
138 if (parent
) parent
->AddChild(this);
143 m_windowId
= (int)NewControlId();
150 m_windowMenu
= (WXHMENU
) ::LoadMenu(wxGetInstance(), "wxWindowMenu");
152 DWORD msflags
= WS_OVERLAPPED
;
153 if (style
& wxMINIMIZE_BOX
)
154 msflags
|= WS_MINIMIZEBOX
;
155 if (style
& wxMAXIMIZE_BOX
)
156 msflags
|= WS_MAXIMIZEBOX
;
157 if (style
& wxTHICK_FRAME
)
158 msflags
|= WS_THICKFRAME
;
159 if (style
& wxSYSTEM_MENU
)
160 msflags
|= WS_SYSMENU
;
161 if ((style
& wxMINIMIZE
) || (style
& wxICONIZE
))
162 msflags
|= WS_MINIMIZE
;
163 if (style
& wxMAXIMIZE
)
164 msflags
|= WS_MAXIMIZE
;
165 if (style
& wxCAPTION
)
166 msflags
|= WS_CAPTION
;
168 // Adding WS_CLIPCHILDREN causes children not to be properly
169 // drawn when first displaying them.
170 // if (style & wxCLIP_CHILDREN)
171 // msflags |= WS_CLIPCHILDREN;
173 wxWindow::MSWCreate(m_windowId
, parent
, wxMDIFrameClassName
, this, title
, x
, y
, width
, height
,
176 wxModelessWindows
.Append(this);
181 wxMDIParentFrame::~wxMDIParentFrame()
185 DestroyMenu((HMENU
) m_windowMenu
); // Destroy dummy "Window" menu
188 if (m_clientWindow
->MSWGetOldWndProc())
189 m_clientWindow
->UnsubclassWin();
191 m_clientWindow
->SetHWND(0);
192 delete m_clientWindow
;
195 void wxMDIParentFrame::SetMenuBar(wxMenuBar
*menu_bar
)
199 m_frameMenuBar
= NULL
;
203 if ( menu_bar
->IsAttached() )
206 m_hMenu
= menu_bar
->Create();
209 delete m_frameMenuBar
;
211 // MDI parent-specific code follows
213 HMENU subMenu
= GetSubMenu((HMENU
) m_windowMenu
, 0);
215 // Try to insert Window menu in front of Help, otherwise append it.
216 HMENU menu
= (HMENU
)m_hMenu
;
217 int N
= GetMenuItemCount(menu
);
218 bool success
= FALSE
;
219 for (int i
= 0; i
< N
; i
++)
222 int chars
= GetMenuString(menu
, i
, buf
, 100, MF_BYPOSITION
);
223 if ((chars
> 0) && (strcmp(buf
, "&Help") == 0 ||
224 strcmp(buf
, "Help") == 0))
227 InsertMenu(menu
, i
, MF_BYPOSITION
| MF_POPUP
| MF_STRING
,
228 (UINT
)subMenu
, "&Window");
233 AppendMenu(menu
, MF_POPUP
,
236 m_parentFrameActive
= TRUE
;
238 SendMessage((HWND
) GetClientWindow()->GetHWND(), WM_MDISETMENU
,
242 SendMessage((HWND
) GetClientWindow()->GetHWND(), WM_MDISETMENU
, 0,
243 MAKELPARAM(menu
, subMenu
));
245 DrawMenuBar((HWND
) GetHWND());
247 m_frameMenuBar
= menu_bar
;
248 menu_bar
->Attach(this);
251 void wxMDIParentFrame::OnSize(wxSizeEvent
& event
)
253 #if wxUSE_CONSTRAINTS
254 if ( GetAutoLayout() )
259 #endif // wxUSE_CONSTRAINTS
264 GetClientSize(&width
, &height
);
266 if ( GetClientWindow() )
267 GetClientWindow()->SetSize(x
, y
, width
, height
);
270 void wxMDIParentFrame::OnActivate(wxActivateEvent
& event
)
275 // Returns the active MDI child window
276 wxMDIChildFrame
*wxMDIParentFrame::GetActiveChild() const
278 HWND hWnd
= (HWND
)::SendMessage(GetWinHwnd(GetClientWindow()),
279 WM_MDIGETACTIVE
, 0, 0L);
283 return (wxMDIChildFrame
*)wxFindWinFromHandle((WXHWND
) hWnd
);
286 // Create the client window class (don't Create the window, just return a new
288 wxMDIClientWindow
*wxMDIParentFrame::OnCreateClient()
290 return new wxMDIClientWindow
;
293 // Responds to colour changes, and passes event on to children.
294 void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
)
296 if ( m_clientWindow
)
298 m_clientWindow
->SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
299 m_clientWindow
->Refresh();
302 if ( m_frameToolBar )
304 wxSysColourChangedEvent event2;
305 event2.eventObject = m_frameToolBar;
306 m_frameToolBar->GetEventHandler()->ProcessEvent(event2);
310 // Propagate the event to the non-top-level children
311 wxFrame::OnSysColourChanged(event
);
315 void wxMDIParentFrame::Cascade()
317 ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE
, 0, 0);
320 void wxMDIParentFrame::Tile()
322 ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE
, MDITILE_HORIZONTAL
, 0);
325 void wxMDIParentFrame::ArrangeIcons()
327 ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDIICONARRANGE
, 0, 0);
330 void wxMDIParentFrame::ActivateNext()
332 ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT
, 0, 0);
335 void wxMDIParentFrame::ActivatePrevious()
337 ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT
, 0, 1);
340 // the MDI parent frame window proc
341 long wxMDIParentFrame::MSWWindowProc(WXUINT message
,
346 bool processed
= FALSE
;
351 m_clientWindow
= OnCreateClient();
352 // Uses own style for client style
353 if ( !m_clientWindow
->CreateClient(this, GetWindowStyleFlag()) )
355 wxLogMessage(_("Failed to create MDI parent frame."));
366 // we erase background ourselves
372 WORD item
= (WORD
)wParam
;
374 WORD flags
= HIWORD(wParam
);
375 HMENU menu
= (HMENU
)lParam
;
377 WORD flags
= LOWORD(lParam
);
378 HMENU menu
= (HMENU
)HIWORD(lParam
);
380 if ( m_parentFrameActive
)
382 processed
= HandleMenuSelect(item
, flags
, (WXHMENU
)menu
);
384 else if (m_currentChild
)
386 processed
= m_currentChild
->
387 HandleMenuSelect(item
, flags
, (WXHMENU
)menu
);
394 rc
= wxFrame::MSWWindowProc(message
, wParam
, lParam
);
399 bool wxMDIParentFrame::MSWOnActivate(int state
, bool minimized
, WXHWND activate
)
401 bool processed
= FALSE
;
403 if ( wxWindow::MSWOnActivate(state
, minimized
, activate
) )
409 // If this window is an MDI parent, we must also send an OnActivate message
410 // to the current child.
411 if ( (m_currentChild
!= NULL
) &&
412 ((state
== WA_ACTIVE
) || (state
== WA_CLICKACTIVE
)) )
414 wxActivateEvent
event(wxEVT_ACTIVATE
, TRUE
, m_currentChild
->GetId());
415 event
.SetEventObject( m_currentChild
);
416 if ( m_currentChild
->GetEventHandler()->ProcessEvent(event
) )
423 bool wxMDIParentFrame::MSWOnCommand(WXWORD id
, WXWORD cmd
, WXHWND control
)
425 // if (cmd == 0) // Why did I do this test?
427 // In case it's e.g. a toolbar.
428 wxWindow
*win
= wxFindWinFromHandle(control
);
430 return win
->MSWCommand(cmd
, id
);
433 if (wxCurrentPopupMenu)
435 wxMenu *popupMenu = wxCurrentPopupMenu;
436 wxCurrentPopupMenu = NULL;
437 if (!popupMenu->MSWCommand(cmd, id))
444 case IDM_WINDOWCASCADE
:
445 SendMessage((HWND
) GetClientWindow()->GetHWND(), WM_MDICASCADE
, MDITILE_SKIPDISABLED
, 0);
448 SendMessage((HWND
) GetClientWindow()->GetHWND(), WM_MDITILE
, MDITILE_HORIZONTAL
, 0);
450 case IDM_WINDOWICONS
:
451 SendMessage((HWND
) GetClientWindow()->GetHWND(), WM_MDIICONARRANGE
, 0, 0);
454 SendMessage((HWND
) GetClientWindow()->GetHWND(), WM_MDINEXT
, 0, 0);
461 return FALSE
; // Get WndProc to call default proc
464 if (m_parentFrameActive
&& (id
< wxFIRST_MDI_CHILD
|| id
> wxLAST_MDI_CHILD
))
469 else if (m_currentChild
&& (id
< wxFIRST_MDI_CHILD
|| id
> wxLAST_MDI_CHILD
))
471 return m_currentChild
->MSWOnCommand(id
, cmd
, control
);
474 if (id
>= wxFIRST_MDI_CHILD
&& id
<= wxLAST_MDI_CHILD
)
476 wxNode
* node
= GetChildren().First();
479 wxWindow
* child
= (wxWindow
*) node
->Data();
480 if (child
->GetHWND())
483 long childId
= GetWindowLong((HWND
) child
->GetHWND(), GWL_ID
);
485 long childId
= GetWindowWord((HWND
) child
->GetHWND(), GWW_ID
);
489 ::SendMessage( (HWND
) GetClientWindow()->GetHWND(), WM_MDIACTIVATE
, (WPARAM
) (HWND
) child
->GetHWND(), 0);
496 wxWindow* child = FindItem(id);
499 ::SendMessage( (HWND) GetClientWindow()->GetHWND(), WM_MDIACTIVATE, (WPARAM) (HWND) child->GetHWND(), 0);
505 return wxWindow::MSWOnCommand(id
, cmd
, control
);
508 long wxMDIParentFrame::MSWDefWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
)
511 if ( GetClientWindow() )
512 clientWnd
= GetClientWindow()->GetHWND();
516 return DefFrameProc(GetHwnd(), (HWND
)clientWnd
, message
, wParam
, lParam
);
519 bool wxMDIParentFrame::MSWProcessMessage(WXMSG
* msg
)
521 return m_currentChild
&& m_currentChild
->GetHWND() &&
522 m_currentChild
->MSWProcessMessage(msg
);
525 bool wxMDIParentFrame::MSWTranslateMessage(WXMSG
* msg
)
527 MSG
*pMsg
= (MSG
*)msg
;
529 if ( m_currentChild
&& m_currentChild
->GetHWND() &&
530 m_currentChild
->MSWTranslateMessage(msg
) )
535 if ( m_acceleratorTable
.Ok() &&
536 ::TranslateAccelerator(GetHwnd(),
537 GetTableHaccel(&m_acceleratorTable
),
543 if ( pMsg
->message
== WM_KEYDOWN
|| pMsg
->message
== WM_SYSKEYDOWN
)
545 if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg
))
552 // ---------------------------------------------------------------------------
554 // ---------------------------------------------------------------------------
556 wxMDIChildFrame::wxMDIChildFrame()
561 bool wxMDIChildFrame::Create(wxMDIParentFrame
*parent
,
563 const wxString
& title
,
567 const wxString
& name
)
569 m_defaultIcon
= (WXHICON
) (wxSTD_MDICHILDFRAME_ICON
? wxSTD_MDICHILDFRAME_ICON
: wxDEFAULT_MDICHILDFRAME_ICON
);
576 m_windowId
= (int)NewControlId();
578 if (parent
) parent
->AddChild(this);
589 mcs
.szClass
= wxMDIChildFrameClassName
;
591 mcs
.hOwner
= wxGetInstance();
592 if (x
> -1) mcs
.x
= x
;
593 else mcs
.x
= CW_USEDEFAULT
;
595 if (y
> -1) mcs
.y
= y
;
596 else mcs
.y
= CW_USEDEFAULT
;
598 if (width
> -1) mcs
.cx
= width
;
599 else mcs
.cx
= CW_USEDEFAULT
;
601 if (height
> -1) mcs
.cy
= height
;
602 else mcs
.cy
= CW_USEDEFAULT
;
604 DWORD msflags
= WS_OVERLAPPED
| WS_CLIPCHILDREN
;
605 if (style
& wxMINIMIZE_BOX
)
606 msflags
|= WS_MINIMIZEBOX
;
607 if (style
& wxMAXIMIZE_BOX
)
608 msflags
|= WS_MAXIMIZEBOX
;
609 if (style
& wxTHICK_FRAME
)
610 msflags
|= WS_THICKFRAME
;
611 if (style
& wxSYSTEM_MENU
)
612 msflags
|= WS_SYSMENU
;
613 if ((style
& wxMINIMIZE
) || (style
& wxICONIZE
))
614 msflags
|= WS_MINIMIZE
;
615 if (style
& wxMAXIMIZE
)
616 msflags
|= WS_MAXIMIZE
;
617 if (style
& wxCAPTION
)
618 msflags
|= WS_CAPTION
;
624 DWORD Return
= SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(),
625 WM_MDICREATE
, 0, (LONG
)(LPSTR
)&mcs
);
627 //handle = (HWND)LOWORD(Return);
628 // Must be the DWORRD for WIN32. And in 16 bits, HIWORD=0 (says Microsoft)
629 m_hWnd
= (WXHWND
)Return
;
631 // This gets reassigned so can't be stored
632 // m_windowId = GetWindowLong((HWND) m_hWnd, GWL_ID);
635 wxWinHandleList
->Append((long)GetHWND(), this);
637 SetWindowLong((HWND
) GetHWND(), 0, (long)this);
639 wxModelessWindows
.Append(this);
643 wxMDIChildFrame::~wxMDIChildFrame()
647 ResetWindowStyle(NULL
);
650 // Set the client size (i.e. leave the calculation of borders etc.
652 void wxMDIChildFrame::DoSetClientSize(int width
, int height
)
654 HWND hWnd
= (HWND
) GetHWND();
657 ::GetClientRect(hWnd
, &rect
);
660 GetWindowRect(hWnd
, &rect2
);
662 // Find the difference between the entire window (title bar and all)
663 // and the client area; add this to the new client size to move the
665 int actual_width
= rect2
.right
- rect2
.left
- rect
.right
+ width
;
666 int actual_height
= rect2
.bottom
- rect2
.top
- rect
.bottom
+ height
;
671 GetStatusBar()->GetSize(&sx
, &sy
);
676 point
.x
= rect2
.left
;
679 // If there's an MDI parent, must subtract the parent's top left corner
680 // since MoveWindow moves relative to the parent
681 wxMDIParentFrame
*mdiParent
= (wxMDIParentFrame
*)GetParent();
682 ::ScreenToClient((HWND
) mdiParent
->GetClientWindow()->GetHWND(), &point
);
684 MoveWindow(hWnd
, point
.x
, point
.y
, actual_width
, actual_height
, (BOOL
)TRUE
);
686 wxSizeEvent
event(wxSize(width
, height
), m_windowId
);
687 event
.SetEventObject( this );
688 GetEventHandler()->ProcessEvent(event
);
691 void wxMDIChildFrame::DoGetPosition(int *x
, int *y
) const
694 GetWindowRect((HWND
) GetHWND(), &rect
);
699 // Since we now have the absolute screen coords,
700 // if there's a parent we must subtract its top left corner
701 wxMDIParentFrame
*mdiParent
= (wxMDIParentFrame
*)GetParent();
702 ::ScreenToClient((HWND
) mdiParent
->GetClientWindow()->GetHWND(), &point
);
708 void wxMDIChildFrame::SetMenuBar(wxMenuBar
*menu_bar
)
712 m_frameMenuBar
= NULL
;
716 if ( menu_bar
->IsAttached() )
719 m_hMenu
= menu_bar
->Create();
722 delete m_frameMenuBar
;
724 wxMDIParentFrame
*parent
= (wxMDIParentFrame
*)GetParent();
726 parent
->m_parentFrameActive
= FALSE
;
727 HMENU subMenu
= GetSubMenu((HMENU
) parent
->GetWindowMenu(), 0);
729 // Try to insert Window menu in front of Help, otherwise append it.
730 HMENU menu
= (HMENU
)m_hMenu
;
731 int N
= GetMenuItemCount(menu
);
732 bool success
= FALSE
;
733 for (int i
= 0; i
< N
; i
++)
736 int chars
= GetMenuString(menu
, i
, buf
, 100, MF_BYPOSITION
);
737 if ((chars
> 0) && (strcmp(buf
, "&Help") == 0 ||
738 strcmp(buf
, "Help") == 0))
741 InsertMenu(menu
, i
, MF_BYPOSITION
| MF_POPUP
| MF_STRING
,
742 (UINT
)subMenu
, "&Window");
747 AppendMenu(menu
, MF_POPUP
,
751 SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDISETMENU
,
755 SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDISETMENU
, 0,
756 MAKELPARAM(menu
, subMenu
));
759 DrawMenuBar((HWND
) parent
->GetHWND());
760 m_frameMenuBar
= menu_bar
;
761 menu_bar
->Attach(this);
765 void wxMDIChildFrame::Maximize()
767 wxMDIParentFrame
*parent
= (wxMDIParentFrame
*)GetParent();
768 if ( parent
&& parent
->GetClientWindow() )
769 ::SendMessage( (HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDIMAXIMIZE
, (WPARAM
) (HWND
) GetHWND(), 0);
772 void wxMDIChildFrame::Restore()
774 wxMDIParentFrame
*parent
= (wxMDIParentFrame
*)GetParent();
775 if ( parent
&& parent
->GetClientWindow() )
776 ::SendMessage( (HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDIRESTORE
, (WPARAM
) (HWND
) GetHWND(), 0);
779 void wxMDIChildFrame::Activate()
781 wxMDIParentFrame
*parent
= (wxMDIParentFrame
*)GetParent();
782 if ( parent
&& parent
->GetClientWindow() )
783 ::SendMessage( (HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDIACTIVATE
, (WPARAM
) (HWND
) GetHWND(), 0);
786 static HWND invalidHandle
= 0;
787 bool wxMDIChildFrame::MSWOnSize(int x
, int y
, WXUINT id
)
789 HWND hwnd
= GetHwnd();
791 if ( !hwnd
|| hwnd
== invalidHandle
)
810 // forward WM_SIZE to status bar control
811 #if wxUSE_NATIVE_STATUSBAR
812 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
814 wxSizeEvent
event(wxSize(x
, y
), m_frameStatusBar
->GetId());
815 event
.SetEventObject( m_frameStatusBar
);
817 ((wxStatusBar95
*)m_frameStatusBar
)->OnSize(event
);
824 return wxWindow::MSWOnSize(x
, y
, id
);
832 bool wxMDIChildFrame::MSWOnCommand(WXWORD id
, WXWORD cmd
, WXHWND control
)
834 // if ((cmd == 0) && GetHWND())
837 // In case it's e.g. a toolbar.
838 wxWindow
*win
= wxFindWinFromHandle(control
);
840 return win
->MSWCommand(cmd
, id
);
842 if (wxCurrentPopupMenu
)
844 wxMenu
*popupMenu
= wxCurrentPopupMenu
;
845 wxCurrentPopupMenu
= NULL
;
846 if (popupMenu
->MSWCommand(cmd
, id
))
850 if (GetMenuBar() && GetMenuBar()->FindItemForId(id
))
860 return wxWindow::MSWOnCommand(id
, cmd
, control
);
863 long wxMDIChildFrame::MSWDefWindowProc(WXUINT message
, WXUINT wParam
, WXLPARAM lParam
)
866 return DefMDIChildProc((HWND
) GetHWND(), (UINT
) message
, (WPARAM
) wParam
, (LPARAM
) lParam
);
870 bool wxMDIChildFrame::MSWProcessMessage(WXMSG
*msg
)
875 bool wxMDIChildFrame::MSWTranslateMessage(WXMSG
* msg
)
877 MSG
*pMsg
= (MSG
*)msg
;
878 if (m_acceleratorTable
.Ok())
880 wxFrame
*parent
= (wxFrame
*)GetParent();
881 HWND parent_hwnd
= (HWND
) parent
->GetHWND();
882 return (::TranslateAccelerator(parent_hwnd
, (HACCEL
) m_acceleratorTable
.GetHACCEL(), pMsg
) != 0);
888 bool wxMDIChildFrame::MSWOnMDIActivate(long activate
, WXHWND
WXUNUSED(one
), WXHWND
WXUNUSED(two
))
890 wxMDIParentFrame
*parent
= (wxMDIParentFrame
*)GetParent();
891 HMENU parent_menu
= (HMENU
) parent
->GetWinMenu();
892 HMENU child_menu
= (HMENU
) GetWinMenu();
897 parent
->m_currentChild
= this;
900 parent
->m_parentFrameActive
= FALSE
;
901 HMENU subMenu
= GetSubMenu((HMENU
) parent
->GetWindowMenu(), 0);
903 ::SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDISETMENU
,
907 ::SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDISETMENU
, 0,
908 MAKELONG(child_menu
, subMenu
));
911 ::DrawMenuBar((HWND
) parent
->GetHWND());
913 wxActivateEvent
event(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
914 event
.SetEventObject( this );
915 return GetEventHandler()->ProcessEvent(event
);
919 if (parent
->m_currentChild
== this)
920 parent
->m_currentChild
= NULL
;
922 wxActivateEvent
event(wxEVT_ACTIVATE
, FALSE
, m_windowId
);
923 event
.SetEventObject( this );
924 if ( GetEventHandler()->ProcessEvent(event
) )
930 parent
->m_parentFrameActive
= TRUE
;
931 HMENU subMenu
= GetSubMenu((HMENU
) parent
->GetWindowMenu(), 0);
933 ::SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDISETMENU
,
937 ::SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDISETMENU
, 0,
938 MAKELONG(parent_menu
, subMenu
));
941 ::DrawMenuBar((HWND
) parent
->GetHWND());
944 bool flag
= (activate
!= 0);
945 wxActivateEvent
event(wxEVT_ACTIVATE
, flag
, m_windowId
);
946 event
.SetEventObject( this );
947 return GetEventHandler()->ProcessEvent(event
);
950 void wxMDIChildFrame::MSWDestroyWindow()
952 MSWDetachWindowMenu();
953 invalidHandle
= (HWND
) GetHWND();
955 wxMDIParentFrame
*parent
= (wxMDIParentFrame
*)GetParent();
957 // Must make sure this handle is invalidated (set to NULL)
958 // since all sorts of things could happen after the
959 // child client is destroyed, but before the wxFrame is
962 HWND oldHandle
= (HWND
)GetHWND();
964 SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDIDESTROY
, (WPARAM
)oldHandle
, (LPARAM
)0);
966 SendMessage((HWND
) parent
->GetClientWindow()->GetHWND(), WM_MDIDESTROY
, (HWND
)oldHandle
, 0);
972 ::DestroyMenu((HMENU
) m_hMenu
);
978 // Change the client window's extended style so we don't
979 // get a client edge style when a child is maximised (a double
980 // border looks silly.)
981 bool wxMDIChildFrame::ResetWindowStyle(void *vrect
)
983 #if defined(__WIN95__)
984 RECT
*rect
= (RECT
*)vrect
;
985 wxMDIParentFrame
* pFrameWnd
= (wxMDIParentFrame
*)GetParent();
986 wxMDIChildFrame
* pChild
= pFrameWnd
->GetActiveChild();
987 if (!pChild
|| (pChild
== this))
989 DWORD dwStyle
= ::GetWindowLong((HWND
) pFrameWnd
->GetClientWindow()->GetHWND(), GWL_EXSTYLE
);
990 DWORD dwThisStyle
= ::GetWindowLong((HWND
) GetHWND(), GWL_STYLE
);
991 DWORD dwNewStyle
= dwStyle
;
992 if (pChild
!= NULL
&& (dwThisStyle
& WS_MAXIMIZE
))
993 dwNewStyle
&= ~(WS_EX_CLIENTEDGE
);
995 dwNewStyle
|= WS_EX_CLIENTEDGE
;
997 if (dwStyle
!= dwNewStyle
)
999 ::RedrawWindow((HWND
) pFrameWnd
->GetClientWindow()->GetHWND(), NULL
, NULL
, RDW_INVALIDATE
| RDW_ALLCHILDREN
);
1000 ::SetWindowLong((HWND
) pFrameWnd
->GetClientWindow()->GetHWND(), GWL_EXSTYLE
, dwNewStyle
);
1001 ::SetWindowPos((HWND
) pFrameWnd
->GetClientWindow()->GetHWND(), NULL
, 0, 0, 0, 0,
1002 SWP_FRAMECHANGED
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOCOPYBITS
);
1004 ::GetClientRect((HWND
) pFrameWnd
->GetClientWindow()->GetHWND(), rect
);
1014 bool wxMDIChildFrame::MSWOnWindowPosChanging(void *pos
)
1016 WINDOWPOS
*lpPos
= (WINDOWPOS
*)pos
;
1017 #if defined(__WIN95__)
1018 if (!(lpPos
->flags
& SWP_NOSIZE
))
1021 DWORD dwExStyle
= ::GetWindowLong((HWND
) GetHWND(), GWL_EXSTYLE
);
1022 DWORD dwStyle
= ::GetWindowLong((HWND
) GetHWND(), GWL_STYLE
);
1023 if (ResetWindowStyle((void *) & rectClient
) && (dwStyle
& WS_MAXIMIZE
))
1025 ::AdjustWindowRectEx(&rectClient
, dwStyle
, FALSE
, dwExStyle
);
1026 lpPos
->x
= rectClient
.left
;
1027 lpPos
->y
= rectClient
.top
;
1028 lpPos
->cx
= rectClient
.right
- rectClient
.left
;
1029 lpPos
->cy
= rectClient
.bottom
- rectClient
.top
;
1031 wxMDIParentFrame
* pFrameWnd
= (wxMDIParentFrame
*)GetParent();
1032 if (pFrameWnd
&& pFrameWnd
->GetToolBar())
1034 pFrameWnd
->GetToolBar()->Refresh();
1043 wxMDIClientWindow::wxMDIClientWindow()
1049 wxMDIClientWindow::~wxMDIClientWindow()
1053 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame
*parent
, long style
)
1055 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
);
1057 CLIENTCREATESTRUCT ccs
;
1058 m_windowStyle
= style
;
1061 ccs
.hWindowMenu
= (HMENU
) parent
->GetWindowMenu();
1062 ccs
.idFirstChild
= wxFIRST_MDI_CHILD
;
1064 DWORD msStyle
= WS_VISIBLE
| WS_CHILD
| WS_CLIPCHILDREN
;
1065 if ( parent
->GetWindowStyleFlag() & wxHSCROLL
)
1066 msStyle
|= WS_HSCROLL
;
1067 if ( parent
->GetWindowStyleFlag() & wxVSCROLL
)
1068 msStyle
|= WS_VSCROLL
;
1070 #if defined(__WIN95__)
1071 DWORD exStyle
= WS_EX_CLIENTEDGE
;
1077 m_hWnd
= (WXHWND
) ::CreateWindowEx(exStyle
, "mdiclient", NULL
,
1078 msStyle
, 0, 0, 0, 0, (HWND
) parent
->GetHWND(), NULL
,
1079 wxGetInstance(), (LPSTR
)(LPCLIENTCREATESTRUCT
)&ccs
);
1080 SubclassWin(m_hWnd
);
1083 return (m_hWnd
!= 0) ;
1086 // Window procedure: here for debugging purposes
1087 long wxMDIClientWindow::MSWWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
1089 return wxWindow::MSWWindowProc(nMsg
, wParam
, lParam
);
1090 // return MSWDefWindowProc(nMsg, wParam, lParam);
1093 long wxMDIClientWindow::MSWDefWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
1095 if ( MSWGetOldWndProc() != 0)
1096 return ::CallWindowProc(CASTWNDPROC
MSWGetOldWndProc(), (HWND
) GetHWND(), (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
);
1098 return ::DefWindowProc((HWND
) m_hWnd
, (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
);
1101 // Explicitly call default scroll behaviour
1102 void wxMDIClientWindow::OnScroll(wxScrollEvent
& event
)
1104 // Note: for client windows, the scroll position is not set in
1105 // WM_HSCROLL, WM_VSCROLL, so we can't easily determine what
1106 // scroll position we're at.
1107 // This makes it hard to paint patterns or bitmaps in the background,
1108 // and have the client area scrollable as well.
1110 if ( event
.GetOrientation() == wxHORIZONTAL
)
1111 m_scrollX
= event
.GetPosition(); // Always returns zero!
1113 m_scrollY
= event
.GetPosition(); // Always returns zero!