]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/mdi.cpp
added default ctor for wxDirDialog
[wxWidgets.git] / src / os2 / mdi.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: mdi.cpp
3// Purpose: MDI classes
4// Author: David Webster
5// Modified by:
6// Created: 10/10/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include "wx/setup.h"
17 #include "wx/frame.h"
18 #include "wx/menu.h"
19 #include "wx/app.h"
20 #include "wx/utils.h"
21 #include "wx/dialog.h"
22 #include "wx/statusbr.h"
23 #include "wx/settings.h"
24 #include "wx/intl.h"
25 #include "wx/log.h"
26#endif
27
28#include "wx/mdi.h"
29#include "wx/os2/private.h"
30
31#include <string.h>
32
33// ---------------------------------------------------------------------------
34// global variables
35// ---------------------------------------------------------------------------
36
37extern wxWindowList wxModelessWindows; // from dialog.cpp
38extern wxMenu *wxCurrentPopupMenu;
39
40extern wxChar wxMDIFrameClassName[];
41extern wxChar wxMDIChildFrameClassName[];
42extern wxWindow *wxWndHook; // from window.cpp
43
44extern void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
45
46static HWND invalidHandle = 0;
47
48// ---------------------------------------------------------------------------
49// constants
50// ---------------------------------------------------------------------------
51
52static const int IDM_WINDOWTILE = 4001;
53static const int IDM_WINDOWTILEHOR = 4001;
54static const int IDM_WINDOWCASCADE = 4002;
55static const int IDM_WINDOWICONS = 4003;
56static const int IDM_WINDOWNEXT = 4004;
57static const int IDM_WINDOWTILEVERT = 4005;
58
59// This range gives a maximum of 500 MDI children. Should be enough :-)
60static const int wxFIRST_MDI_CHILD = 4100;
61static const int wxLAST_MDI_CHILD = 4600;
62
63// Status border dimensions
64static const int wxTHICK_LINE_BORDER = 3;
65static const int wxTHICK_LINE_WIDTH = 1;
66
67// ---------------------------------------------------------------------------
68// private functions
69// ---------------------------------------------------------------------------
70
71// set the MDI menus (by sending the WM_MDISETMENU message) and update the menu
72// of the parent of win (which is supposed to be the MDI client window)
73static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow);
74
75// insert the window menu (subMenu) into menu just before "Help" submenu or at
76// the very end if not found
77static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu);
78
79// is this an id of an MDI child?
80inline bool IsMdiCommandId(int id)
81{
82 return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD);
83}
84
85static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
86 WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
87
88// ===========================================================================
89// implementation
90// ===========================================================================
91
92// ---------------------------------------------------------------------------
93// wxWin macros
94// ---------------------------------------------------------------------------
95
96#if !USE_SHARED_LIBRARY
97 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
98 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
99 IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
100#endif // USE_SHARED_LIBRARY
101
102BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
103 EVT_SIZE(wxMDIParentFrame::OnSize)
104 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
105END_EVENT_TABLE()
106
107BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
108 EVT_SCROLL(wxMDIClientWindow::OnScroll)
109END_EVENT_TABLE()
110
111// ===========================================================================
112// wxMDIParentFrame: the frame which contains the client window which manages
113// the children
114// ===========================================================================
115
116wxMDIParentFrame::wxMDIParentFrame()
117{
118 m_clientWindow = NULL;
119 m_currentChild = NULL;
120 m_windowMenu = 0;
121 m_parentFrameActive = TRUE;
122}
123
124bool wxMDIParentFrame::Create(wxWindow *parent,
125 wxWindowID id,
126 const wxString& title,
127 const wxPoint& pos,
128 const wxSize& size,
129 long style,
130 const wxString& name)
131{
132 m_defaultIcon = (WXHICON) (wxSTD_MDIPARENTFRAME_ICON ? wxSTD_MDIPARENTFRAME_ICON : wxDEFAULT_MDIPARENTFRAME_ICON);
133
134 m_clientWindow = NULL;
135 m_currentChild = NULL;
136 m_windowMenu = 0;
137 m_parentFrameActive = TRUE;
138
139 if (!parent)
140 wxTopLevelWindows.Append(this);
141
142 SetName(name);
143 m_windowStyle = style;
144
145 if (parent) parent->AddChild(this);
146
147 if ( id > -1 )
148 m_windowId = id;
149 else
150 m_windowId = (int)NewControlId();
151
152 int x = pos.x;
153 int y = pos.y;
154 int width = size.x;
155 int height = size.y;
156
157// TODO: m_windowMenu = (WXHMENU) ::LoadMenu(wxGetInstance(), wxT("wxWindowMenu"));
158/*
159 DWORD msflags = WS_OVERLAPPED;
160 if (style & wxMINIMIZE_BOX)
161 msflags |= WS_MINIMIZEBOX;
162 if (style & wxMAXIMIZE_BOX)
163 msflags |= WS_MAXIMIZEBOX;
164 if (style & wxTHICK_FRAME)
165 msflags |= WS_THICKFRAME;
166 if (style & wxSYSTEM_MENU)
167 msflags |= WS_SYSMENU;
168 if ((style & wxMINIMIZE) || (style & wxICONIZE))
169 msflags |= WS_MINIMIZE;
170 if (style & wxMAXIMIZE)
171 msflags |= WS_MAXIMIZE;
172 if (style & wxCAPTION)
173 msflags |= WS_CAPTION;
174
175 if (style & wxCLIP_CHILDREN)
176 msflags |= WS_CLIPCHILDREN;
177
178 wxWindow::MSWCreate(m_windowId, parent, wxMDIFrameClassName, this, title, x, y, width, height,
179 msflags);
180*/
181 wxModelessWindows.Append(this);
182
183 return TRUE;
184}
185
186wxMDIParentFrame::~wxMDIParentFrame()
187{
188 DestroyChildren();
189
190// TODO: ::DestroyMenu((HMENU)m_windowMenu);
191 m_windowMenu = 0;
192
193 if ( m_clientWindow )
194 {
195 if ( m_clientWindow->OS2GetOldWndProc() )
196 m_clientWindow->UnsubclassWin();
197
198 m_clientWindow->SetHWND(0);
199 delete m_clientWindow;
200 }
201}
202
203void wxMDIParentFrame::InternalSetMenuBar()
204{
205 // TODO:
206/*
207 HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0);
208
209 m_parentFrameActive = TRUE;
210
211 InsertWindowMenu(GetClientWindow(), m_hMenu, subMenu);
212*/
213}
214
215void wxMDIParentFrame::OnSize(wxSizeEvent& event)
216{
217 // TODO:
218/*
219 if ( GetClientWindow() )
220 {
221 int width, height;
222 GetClientSize(&width, &height);
223
224 GetClientWindow()->SetSize(0, 0, width, height);
225 }
226*/
227}
228
229// Returns the active MDI child window
230wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
231{
232 HWND hWnd = 0; // TODO: (HWND)::SendMessage(GetWinHwnd(GetClientWindow()),
233// WM_MDIGETACTIVE, 0, 0L);
234 if ( hWnd == 0 )
235 return NULL;
236 else
237 return (wxMDIChildFrame *)wxFindWinFromHandle((WXHWND) hWnd);
238}
239
240// Create the client window class (don't Create the window, just return a new
241// class)
242wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
243{
244 return new wxMDIClientWindow;
245}
246
247// Responds to colour changes, and passes event on to children.
248void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
249{
250 if ( m_clientWindow )
251 {
252 m_clientWindow->SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
253 m_clientWindow->Refresh();
254 }
255
256 event.Skip();
257}
258
259// ---------------------------------------------------------------------------
260// MDI operations
261// ---------------------------------------------------------------------------
262
263void wxMDIParentFrame::Cascade()
264{
265// TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE, 0, 0);
266}
267
268// TODO: add a direction argument (hor/vert)
269void wxMDIParentFrame::Tile()
270{
271// TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, MDITILE_HORIZONTAL, 0);
272}
273
274void wxMDIParentFrame::ArrangeIcons()
275{
276// TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDIICONARRANGE, 0, 0);
277}
278
279void wxMDIParentFrame::ActivateNext()
280{
281// TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 0);
282}
283
284void wxMDIParentFrame::ActivatePrevious()
285{
286// TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 1);
287}
288
289// ---------------------------------------------------------------------------
290// the MDI parent frame window proc
291// ---------------------------------------------------------------------------
292
293MRESULT wxMDIParentFrame::OS2WindowProc(HWND hwnd,
294 WXUINT message,
295 WXWPARAM wParam,
296 WXLPARAM lParam)
297{
298 MRESULT rc = 0;
299 bool processed = FALSE;
300
301 // TODO:
302/*
303 switch ( message )
304 {
305 case WM_ACTIVATE:
306 {
307 WXWORD state, minimized;
308 WXHWND hwnd;
309 UnpackActivate(wParam, lParam, &state, &minimized, &hwnd);
310
311 processed = HandleActivate(state, minimized != 0, hwnd);
312 }
313 break;
314
315 case WM_COMMAND:
316 {
317 WXWORD id, cmd;
318 WXHWND hwnd;
319 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
320
321 (void)HandleCommand(id, cmd, hwnd);
322
323 // even if the frame didn't process it, there is no need to try it
324 // once again (i.e. call wxFrame::HandleCommand()) - we just dud it,
325 // so pretend we processed the message anyhow
326 processed = TRUE;
327 }
328
329 // always pass this message DefFrameProc(), otherwise MDI menu
330 // commands (and sys commands - more surprizingly!) won't work
331 MSWDefWindowProc(message, wParam, lParam);
332 break;
333
334 case WM_CREATE:
335 m_clientWindow = OnCreateClient();
336 // Uses own style for client style
337 if ( !m_clientWindow->CreateClient(this, GetWindowStyleFlag()) )
338 {
339 wxLogMessage(_("Failed to create MDI parent frame."));
340
341 rc = -1;
342 }
343
344 processed = TRUE;
345 break;
346
347 case WM_ERASEBKGND:
348 processed = TRUE;
349
350 // we erase background ourselves
351 rc = TRUE;
352 break;
353
354 case WM_MENUSELECT:
355 {
356 WXWORD item, flags;
357 WXHMENU hmenu;
358 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
359
360 if ( m_parentFrameActive )
361 {
362 processed = HandleMenuSelect(item, flags, hmenu);
363 }
364 else if (m_currentChild)
365 {
366 processed = m_currentChild->
367 HandleMenuSelect(item, flags, hmenu);
368 }
369 }
370 break;
371
372 case WM_SIZE:
373 // as we don't (usually) resize the MDI client to exactly fit the
374 // client area (we put it below the toolbar, above statusbar &c),
375 // we should not pass this one to DefFrameProc
376 break;
377 }
378*/
379 if ( !processed )
380 rc = wxFrame::OS2WindowProc(hwnd, message, wParam, lParam);
381
382 return rc;
383}
384
385bool wxMDIParentFrame::HandleActivate(int state, bool minimized, WXHWND activate)
386{
387 bool processed = FALSE;
388
389 // TODO:
390/*
391 if ( wxWindow::HandleActivate(state, minimized, activate) )
392 {
393 // already processed
394 processed = TRUE;
395 }
396
397 // If this window is an MDI parent, we must also send an OnActivate message
398 // to the current child.
399 if ( (m_currentChild != NULL) &&
400 ((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)) )
401 {
402 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_currentChild->GetId());
403 event.SetEventObject( m_currentChild );
404 if ( m_currentChild->GetEventHandler()->ProcessEvent(event) )
405 processed = TRUE;
406 }
407*/
408 return processed;
409}
410
411bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
412{
413 // In case it's e.g. a toolbar.
414 if ( hwnd )
415 {
416 wxWindow *win = wxFindWinFromHandle(hwnd);
417 if ( win )
418 return FALSE; // Need to get wxWindow for OS/2 up to date: win->OS2Command(cmd, id);
419 }
420
421 // is it one of standard MDI commands?
422 WXWPARAM wParam = 0;
423 int msg = 0;
424
425 // TODO:
426/*
427 switch ( id )
428 {
429 case IDM_WINDOWCASCADE:
430 msg = WM_MDICASCADE;
431 wParam = MDITILE_SKIPDISABLED;
432 break;
433
434 case IDM_WINDOWTILEHOR:
435 wParam |= MDITILE_HORIZONTAL;
436 // fall through
437
438 case IDM_WINDOWTILEVERT:
439 if ( !wParam )
440 wParam = MDITILE_VERTICAL;
441 msg = WM_MDITILE;
442 wParam |= MDITILE_SKIPDISABLED;
443 break;
444
445 case IDM_WINDOWICONS:
446 msg = WM_MDIICONARRANGE;
447 break;
448
449 case IDM_WINDOWNEXT:
450 msg = WM_MDINEXT;
451 break;
452
453 default:
454 msg = 0;
455 }
456*/
457 if ( msg )
458 {
459// TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, 0);
460
461 return TRUE;
462 }
463
464 // FIXME VZ: what does this test do??
465 if (id >= 0xF000)
466 {
467 return FALSE; // Get WndProc to call default proc
468 }
469
470 if ( IsMdiCommandId(id) )
471 {
472 wxWindowList::Node* node = GetChildren().GetFirst();
473 while ( node )
474 {
475 wxWindow* child = node->GetData();
476 if ( child->GetHWND() )
477 {
478 long childId = wxGetWindowId(child->GetHWND());
479 if (childId == (long)id)
480 {
481// TODO: ::SendMessage( GetWinHwnd(GetClientWindow()),
482// WM_MDIACTIVATE,
483// (WPARAM)child->GetHWND(), 0);
484 return TRUE;
485 }
486 }
487 node = node->GetNext();
488 }
489 }
490 else if ( m_parentFrameActive )
491 {
492 return ProcessCommand(id);
493 }
494 else if ( m_currentChild )
495 {
496 return m_currentChild->HandleCommand(id, cmd, hwnd);
497 }
498 else
499 {
500 // this shouldn't happen because it means that our messages are being
501 // lost (they're not sent to the parent frame nor to the children)
502 wxFAIL_MSG(wxT("MDI parent frame is not active, "
503 "yet there is no active MDI child?"));
504 }
505
506 return FALSE;
507}
508
509MRESULT wxMDIParentFrame::OS2DefWindowProc(HWND hwnd,
510 WXUINT message,
511 WXWPARAM wParam,
512 WXLPARAM lParam)
513{
514 WXHWND clientWnd;
515 if ( GetClientWindow() )
516 clientWnd = GetClientWindow()->GetHWND();
517 else
518 clientWnd = 0;
519
520// TODO: return DefFrameProc(GetHwnd(), (HWND)clientWnd, message, wParam, lParam);
521 return((MRESULT)0);
522}
523
524bool wxMDIParentFrame::OS2TranslateMessage(WXMSG* msg)
525{
526 // TODO:
527/*
528 if ( m_currentChild && m_currentChild->GetHWND() &&
529 m_currentChild->OS2TranslateMessage(msg) )
530 {
531 return TRUE;
532 }
533
534 if ( m_acceleratorTable.Translate(this, msg) )
535 {
536 return TRUE;
537 }
538
539 if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN )
540 {
541 if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg))
542 return TRUE;
543 }
544*/
545 return FALSE;
546}
547
548// ===========================================================================
549// wxMDIChildFrame
550// ===========================================================================
551
552wxMDIChildFrame::wxMDIChildFrame()
553{
554}
555
556bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
557 wxWindowID id,
558 const wxString& title,
559 const wxPoint& pos,
560 const wxSize& size,
561 long style,
562 const wxString& name)
563{
564 m_defaultIcon = (WXHICON)(wxSTD_MDICHILDFRAME_ICON ? wxSTD_MDICHILDFRAME_ICON
565 : wxDEFAULT_MDICHILDFRAME_ICON);
566
567 SetName(name);
568
569 if ( id > -1 )
570 m_windowId = id;
571 else
572 m_windowId = (int)NewControlId();
573
574 if ( parent )
575 {
576 parent->AddChild(this);
577 }
578
579 wxWndHook = this;
580
581 int x = pos.x;
582 int y = pos.y;
583 int width = size.x;
584 int height = size.y;
585
586 // TODO:
587/*
588 MDICREATESTRUCT mcs;
589
590 mcs.szClass = wxMDIChildFrameClassName;
591 mcs.szTitle = title;
592 mcs.hOwner = wxGetInstance();
593 if (x > -1)
594 mcs.x = x;
595 else
596 mcs.x = CW_USEDEFAULT;
597
598 if (y > -1)
599 mcs.y = y;
600 else
601 mcs.y = CW_USEDEFAULT;
602
603 if (width > -1)
604 mcs.cx = width;
605 else
606 mcs.cx = CW_USEDEFAULT;
607
608 if (height > -1)
609 mcs.cy = height;
610 else
611 mcs.cy = CW_USEDEFAULT;
612
613 DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN;
614 if (style & wxMINIMIZE_BOX)
615 msflags |= WS_MINIMIZEBOX;
616 if (style & wxMAXIMIZE_BOX)
617 msflags |= WS_MAXIMIZEBOX;
618 if (style & wxTHICK_FRAME)
619 msflags |= WS_THICKFRAME;
620 if (style & wxSYSTEM_MENU)
621 msflags |= WS_SYSMENU;
622 if ((style & wxMINIMIZE) || (style & wxICONIZE))
623 msflags |= WS_MINIMIZE;
624 if (style & wxMAXIMIZE)
625 msflags |= WS_MAXIMIZE;
626 if (style & wxCAPTION)
627 msflags |= WS_CAPTION;
628
629 mcs.style = msflags;
630
631 mcs.lParam = 0;
632*/
633 DWORD Return = 0; // SendMessage(GetWinHwnd(parent->GetClientWindow()),
634// WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
635 m_hWnd = (WXHWND)Return;
636
637 wxWndHook = NULL;
638 wxAssociateWinWithHandle((HWND) GetHWND(), this);
639
640 // VZ: what's this? an act of piracy?
641 //SetWindowLong(GetHwnd(), 0, (long)this);
642
643 wxModelessWindows.Append(this);
644 return TRUE;
645}
646
647wxMDIChildFrame::~wxMDIChildFrame()
648{
649 OS2DestroyWindow();
650}
651
652// Set the client size (i.e. leave the calculation of borders etc.
653// to wxWindows)
654void wxMDIChildFrame::DoSetClientSize(int width, int height)
655{
656 HWND hWnd = GetHwnd();
657
658 // TODO:
659/*
660 RECT rect;
661 ::GetClientRect(hWnd, &rect);
662
663 RECT rect2;
664 GetWindowRect(hWnd, &rect2);
665
666 // Find the difference between the entire window (title bar and all)
667 // and the client area; add this to the new client size to move the
668 // window
669 int actual_width = rect2.right - rect2.left - rect.right + width;
670 int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
671
672 if (GetStatusBar())
673 {
674 int sx, sy;
675 GetStatusBar()->GetSize(&sx, &sy);
676 actual_height += sy;
677 }
678
679 POINT point;
680 point.x = rect2.left;
681 point.y = rect2.top;
682
683 // If there's an MDI parent, must subtract the parent's top left corner
684 // since MoveWindow moves relative to the parent
685 wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
686 ::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
687
688 MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
689
690 wxSizeEvent event(wxSize(width, height), m_windowId);
691 event.SetEventObject( this );
692 GetEventHandler()->ProcessEvent(event);
693*/
694}
695
696void wxMDIChildFrame::DoGetPosition(int *x, int *y) const
697{
698 // TODO:
699/*
700 RECT rect;
701 GetWindowRect(GetHwnd(), &rect);
702 POINT point;
703 point.x = rect.left;
704 point.y = rect.top;
705
706 // Since we now have the absolute screen coords,
707 // if there's a parent we must subtract its top left corner
708 wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
709 ::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
710
711 *x = point.x;
712 *y = point.y;
713*/
714}
715
716void wxMDIChildFrame::InternalSetMenuBar()
717{
718 // TODO:
719/*
720
721 wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
722
723 HMENU subMenu = GetSubMenu((HMENU)parent->GetWindowMenu(), 0);
724
725 InsertWindowMenu(parent->GetClientWindow(), m_hMenu, subMenu);
726
727 parent->m_parentFrameActive = FALSE;
728*/
729}
730
731// ---------------------------------------------------------------------------
732// MDI operations
733// ---------------------------------------------------------------------------
734
735void wxMDIChildFrame::Maximize(bool maximize)
736{
737 wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
738 // TODO:
739/*
740 if ( parent && parent->GetClientWindow() )
741 {
742 ::SendMessage(GetWinHwnd(parent->GetClientWindow()),
743 maximize ? WM_MDIMAXIMIZE : WM_MDIRESTORE,
744 (WPARAM)GetHwnd(), 0);
745 }
746*/
747}
748
749void wxMDIChildFrame::Restore()
750{
751 // TODO:
752/*
753 wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
754 if ( parent && parent->GetClientWindow() )
755 {
756 ::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIRESTORE,
757 (WPARAM) GetHwnd(), 0);
758 }
759*/
760}
761
762void wxMDIChildFrame::Activate()
763{
764 // TODO:
765/*
766 wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
767 if ( parent && parent->GetClientWindow() )
768 {
769 ::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIACTIVATE,
770 (WPARAM) GetHwnd(), 0);
771 }
772*/
773}
774
775// ---------------------------------------------------------------------------
776// MDI window proc and message handlers
777// ---------------------------------------------------------------------------
778
779MRESULT wxMDIChildFrame::OS2WindowProc(HWND hwnd,
780 WXUINT message,
781 WXWPARAM wParam,
782 WXLPARAM lParam)
783{
784 MRESULT rc = 0;
785 bool processed = FALSE;
786
787 // TODO:
788/*
789 switch ( message )
790 {
791 case WM_COMMAND:
792 {
793 WORD id, cmd;
794 WXHWND hwnd;
795 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
796 &id, &hwnd, &cmd);
797
798 processed = HandleCommand(id, cmd, (WXHWND)hwnd);
799 }
800 break;
801
802 case WM_GETMINMAXINFO:
803 // let the default window proc calculate the size of MDI children
804 // frames because it is based on the size of the MDI client window,
805 // not on the values specified in wxWindow m_min/max variables
806 return MSWDefWindowProc(message, wParam, lParam);
807
808 case WM_MDIACTIVATE:
809 {
810 WXWORD act;
811 WXHWND hwndAct, hwndDeact;
812 UnpackMDIActivate(wParam, lParam, &act, &hwndAct, &hwndDeact);
813
814 processed = HandleMDIActivate(act, hwndAct, hwndDeact);
815 }
816 // fall through
817
818 case WM_MOVE:
819 // must pass WM_MOVE to DefMDIChildProc() to recalculate MDI client
820 // scrollbars if necessary
821
822 // fall through
823
824 case WM_SIZE:
825 // must pass WM_SIZE to DefMDIChildProc(), otherwise many weird
826 // things happen
827 MSWDefWindowProc(message, wParam, lParam);
828 break;
829
830 case WM_SYSCOMMAND:
831 // DefMDIChildProc handles SC_{NEXT/PREV}WINDOW here, so pass it
832 // the message (the base class version does not)
833 return MSWDefWindowProc(message, wParam, lParam);
834
835 case WM_WINDOWPOSCHANGING:
836 processed = HandleWindowPosChanging((LPWINDOWPOS)lParam);
837 break;
838 }
839*/
840 if ( !processed )
841 rc = wxFrame::OS2WindowProc(hwnd, message, wParam, lParam);
842
843 return rc;
844}
845
846bool wxMDIChildFrame::HandleSize(int x, int y, WXUINT id)
847{
848 HWND hwnd = GetHwnd();
849
850 if ( !hwnd || hwnd == invalidHandle )
851 {
852 return FALSE;
853 }
854
855 // TODO:
856/*
857 switch (id)
858 {
859 case SIZEFULLSCREEN:
860 case SIZENORMAL:
861 m_iconized = FALSE;
862 break;
863
864 case SIZEICONIC:
865 m_iconized = TRUE;
866 break;
867 }
868
869 if ( !m_iconized )
870 {
871 // forward WM_SIZE to status bar control
872#if wxUSE_NATIVE_STATUSBAR
873 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
874 {
875 wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
876 event.SetEventObject( m_frameStatusBar );
877
878 ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
879 }
880#endif // wxUSE_NATIVE_STATUSBAR
881
882 PositionStatusBar();
883 PositionToolBar();
884
885 return wxWindow::HandleSize(x, y, id);
886 }
887 else
888 {
889 return FALSE;
890 }
891*/
892 return TRUE;
893}
894
895bool wxMDIChildFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
896{
897 // In case it's e.g. a toolbar.
898 if ( hwnd )
899 {
900 wxWindow *win = wxFindWinFromHandle(hwnd);
901// if (win)
902// Fix dependent stuff return win->OS2Command(cmd, id);
903 }
904
905 if (wxCurrentPopupMenu)
906 {
907 wxMenu *popupMenu = wxCurrentPopupMenu;
908 wxCurrentPopupMenu = NULL;
909// Fix dependent stuff if (popupMenu->OS2Command(cmd, id))
910// return TRUE;
911 }
912
913 if (GetMenuBar() && GetMenuBar()->FindItem(id))
914 {
915 ProcessCommand(id);
916 return TRUE;
917 }
918 else
919 return FALSE;
920
921 return TRUE;
922}
923
924bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
925 WXHWND hwndAct,
926 WXHWND hwndDeact)
927{
928 wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
929
930 HMENU menuToSet = 0;
931
932 bool activated;
933
934 if ( m_hWnd == hwndAct )
935 {
936 activated = TRUE;
937 parent->m_currentChild = this;
938
939 HMENU child_menu = (HMENU)GetWinMenu();
940 if ( child_menu )
941 {
942 parent->m_parentFrameActive = FALSE;
943
944 menuToSet = child_menu;
945 }
946 }
947 else if ( m_hWnd == hwndDeact )
948 {
949 wxASSERT_MSG( parent->m_currentChild == this,
950 wxT("can't deactivate MDI child which wasn't active!") );
951
952 activated = FALSE;
953 parent->m_currentChild = NULL;
954
955 HMENU parent_menu = (HMENU)parent->GetWinMenu();
956 if ( parent_menu )
957 {
958 parent->m_parentFrameActive = TRUE;
959
960 menuToSet = parent_menu;
961 }
962 }
963 else
964 {
965 // we have nothing to with it
966 return FALSE;
967 }
968
969 if ( menuToSet )
970 {
971 HMENU subMenu = 0; // TODO: GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
972
973 MDISetMenu(parent->GetClientWindow(), menuToSet, subMenu);
974 }
975
976 wxActivateEvent event(wxEVT_ACTIVATE, activated, m_windowId);
977 event.SetEventObject( this );
978
979 return GetEventHandler()->ProcessEvent(event);
980}
981
982bool wxMDIChildFrame::HandleWindowPosChanging(void *pos)
983{
984// WINDOWPOS *lpPos = (WINDOWPOS *)pos;
985 return FALSE;
986}
987
988// ---------------------------------------------------------------------------
989// MDI specific message translation/preprocessing
990// ---------------------------------------------------------------------------
991
992MRESULT wxMDIChildFrame::OS2DefWindowProc(HWND hwnd, WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
993{
994 // TODO
995/*
996 return DefMDIChildProc(GetHwnd(),
997 (UINT)message, (WPARAM)wParam, (LPARAM)lParam);
998*/
999 return (MRESULT)0;
1000}
1001
1002bool wxMDIChildFrame::OS2TranslateMessage(WXMSG* msg)
1003{
1004 return m_acceleratorTable.Translate(GetParent(), msg);
1005}
1006
1007// ---------------------------------------------------------------------------
1008// misc
1009// ---------------------------------------------------------------------------
1010
1011void wxMDIChildFrame::OS2DestroyWindow()
1012{
1013// get wxWindow up to date OS2DetachWindowMenu();
1014 invalidHandle = GetHwnd();
1015
1016 wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
1017
1018 // Must make sure this handle is invalidated (set to NULL) since all sorts
1019 // of things could happen after the child client is destroyed, but before
1020 // the wxFrame is destroyed.
1021
1022 HWND oldHandle = (HWND)GetHWND();
1023// TODO: SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIDESTROY,
1024// (WPARAM)oldHandle, 0);
1025 invalidHandle = 0;
1026
1027 if (m_hMenu)
1028 {
1029// TODO: ::DestroyMenu((HMENU) m_hMenu);
1030 m_hMenu = 0;
1031 }
1032 m_hWnd = 0;
1033}
1034
1035// Change the client window's extended style so we don't get a client edge
1036// style when a child is maximised (a double border looks silly.)
1037bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
1038{
1039 return FALSE;
1040}
1041
1042// ===========================================================================
1043// wxMDIClientWindow: the window of predefined (by Windows) class which
1044// contains the child frames
1045// ===========================================================================
1046
1047bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
1048{
1049 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
1050
1051 // TODO:
1052/*
1053 CLIENTCREATESTRUCT ccs;
1054 m_windowStyle = style;
1055 m_parent = parent;
1056
1057 ccs.hWindowMenu = (HMENU)parent->GetWindowMenu();
1058 ccs.idFirstChild = wxFIRST_MDI_CHILD;
1059
1060 DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN;
1061 if ( style & wxHSCROLL )
1062 msStyle |= WS_HSCROLL;
1063 if ( style & wxVSCROLL )
1064 msStyle |= WS_VSCROLL;
1065
1066#if defined(__WIN95__)
1067 DWORD exStyle = WS_EX_CLIENTEDGE;
1068#else
1069 DWORD exStyle = 0;
1070#endif
1071
1072 wxWndHook = this;
1073 m_hWnd = (WXHWND)::CreateWindowEx
1074 (
1075 exStyle,
1076 wxT("MDICLIENT"),
1077 NULL,
1078 msStyle,
1079 0, 0, 0, 0,
1080 GetWinHwnd(parent),
1081 NULL,
1082 wxGetInstance(),
1083 (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
1084 if ( !m_hWnd )
1085 {
1086 wxLogLastError("CreateWindowEx(MDI client)");
1087
1088 return FALSE;
1089 }
1090
1091 SubclassWin(m_hWnd);
1092 wxWndHook = NULL;
1093*/
1094 return TRUE;
1095}
1096
1097// Explicitly call default scroll behaviour
1098void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
1099{
1100 // Note: for client windows, the scroll position is not set in
1101 // WM_HSCROLL, WM_VSCROLL, so we can't easily determine what
1102 // scroll position we're at.
1103 // This makes it hard to paint patterns or bitmaps in the background,
1104 // and have the client area scrollable as well.
1105
1106 if ( event.GetOrientation() == wxHORIZONTAL )
1107 m_scrollX = event.GetPosition(); // Always returns zero!
1108 else
1109 m_scrollY = event.GetPosition(); // Always returns zero!
1110
1111 event.Skip();
1112}
1113
1114// ---------------------------------------------------------------------------
1115// non member functions
1116// ---------------------------------------------------------------------------
1117
1118static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow)
1119{
1120 // TODO:
1121/*
1122 ::SendMessage(GetWinHwnd(win), WM_MDISETMENU,
1123 (WPARAM)hmenuFrame, (LPARAM)hmenuWindow);
1124 // update menu bar of the parent window
1125 wxWindow *parent = win->GetParent();
1126 wxCHECK_RET( parent, wxT("MDI client without parent frame? weird...") );
1127
1128 ::DrawMenuBar(GetWinHwnd(parent));
1129*/
1130}
1131
1132static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
1133{
1134/*
1135 // Try to insert Window menu in front of Help, otherwise append it.
1136 HMENU hmenu = (HMENU)menu;
1137 int N = GetMenuItemCount(hmenu);
1138 bool success = FALSE;
1139 for ( int i = 0; i < N; i++ )
1140 {
1141 wxChar buf[256];
1142 int chars = GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION);
1143 if ( chars == 0 )
1144 {
1145 wxLogLastError(wxT("GetMenuString"));
1146
1147 continue;
1148 }
1149
1150 if ( wxStripMenuCodes(wxString(buf)).IsSameAs(wxT("Help")) )
1151 {
1152 success = TRUE;
1153 ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
1154 (UINT)subMenu, wxT("&Window"));
1155 break;
1156 }
1157 }
1158
1159 if ( !success )
1160 {
1161 ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, wxT("&Window"));
1162 }
1163 MDISetMenu(win, hmenu, subMenu);
1164*/
1165}
1166
1167static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
1168 WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact)
1169{
1170 *activate = TRUE;
1171 *hwndAct = (WXHWND)lParam;
1172 *hwndDeact = (WXHWND)wParam;
1173}
1174