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