]> git.saurik.com Git - wxWidgets.git/blob - src/os2/mdi.cpp
OnEnter/OnDragOver API update (compiles, links, somewhat runs under wxGTK)
[wxWidgets.git] / src / os2 / mdi.cpp
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
37 extern wxWindowList wxModelessWindows; // from dialog.cpp
38 extern wxMenu *wxCurrentPopupMenu;
39
40 extern wxChar wxMDIFrameClassName[];
41 extern wxChar wxMDIChildFrameClassName[];
42 extern wxWindow *wxWndHook; // from window.cpp
43
44 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
45
46 static HWND invalidHandle = 0;
47
48 // ---------------------------------------------------------------------------
49 // constants
50 // ---------------------------------------------------------------------------
51
52 static const int IDM_WINDOWTILE = 4001;
53 static const int IDM_WINDOWTILEHOR = 4001;
54 static const int IDM_WINDOWCASCADE = 4002;
55 static const int IDM_WINDOWICONS = 4003;
56 static const int IDM_WINDOWNEXT = 4004;
57 static const int IDM_WINDOWTILEVERT = 4005;
58
59 // This range gives a maximum of 500 MDI children. Should be enough :-)
60 static const int wxFIRST_MDI_CHILD = 4100;
61 static const int wxLAST_MDI_CHILD = 4600;
62
63 // Status border dimensions
64 static const int wxTHICK_LINE_BORDER = 3;
65 static 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)
73 static 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
77 static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu);
78
79 // is this an id of an MDI child?
80 inline bool IsMdiCommandId(int id)
81 {
82 return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD);
83 }
84
85 static 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
102 BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
103 EVT_SIZE(wxMDIParentFrame::OnSize)
104 EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
105 END_EVENT_TABLE()
106
107 BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
108 EVT_SCROLL(wxMDIClientWindow::OnScroll)
109 END_EVENT_TABLE()
110
111 // ===========================================================================
112 // wxMDIParentFrame: the frame which contains the client window which manages
113 // the children
114 // ===========================================================================
115
116 wxMDIParentFrame::wxMDIParentFrame()
117 {
118 m_clientWindow = NULL;
119 m_currentChild = NULL;
120 m_windowMenu = 0;
121 m_parentFrameActive = TRUE;
122 }
123
124 bool 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
186 wxMDIParentFrame::~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
203 void 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
215 void 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
230 wxMDIChildFrame *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)
242 wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
243 {
244 return new wxMDIClientWindow;
245 }
246
247 // Responds to colour changes, and passes event on to children.
248 void 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
263 void wxMDIParentFrame::Cascade()
264 {
265 // TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE, 0, 0);
266 }
267
268 // TODO: add a direction argument (hor/vert)
269 void wxMDIParentFrame::Tile()
270 {
271 // TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, MDITILE_HORIZONTAL, 0);
272 }
273
274 void wxMDIParentFrame::ArrangeIcons()
275 {
276 // TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDIICONARRANGE, 0, 0);
277 }
278
279 void wxMDIParentFrame::ActivateNext()
280 {
281 // TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 0);
282 }
283
284 void wxMDIParentFrame::ActivatePrevious()
285 {
286 // TODO: ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 1);
287 }
288
289 // ---------------------------------------------------------------------------
290 // the MDI parent frame window proc
291 // ---------------------------------------------------------------------------
292
293 MRESULT 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
385 bool 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
411 bool 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;
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
509 MRESULT 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
524 bool 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
552 wxMDIChildFrame::wxMDIChildFrame()
553 {
554 }
555
556 bool 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
647 wxMDIChildFrame::~wxMDIChildFrame()
648 {
649 OS2DestroyWindow();
650 }
651
652 // Set the client size (i.e. leave the calculation of borders etc.
653 // to wxWindows)
654 void 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
696 void 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
716 void 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
735 void 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
749 void 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
762 void 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
779 MRESULT 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
846 bool 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
895 bool 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()->FindItemForId(id))
914 {
915 ProcessCommand(id);
916 return TRUE;
917 }
918 else
919 return FALSE;
920
921 return TRUE;
922 }
923
924 bool 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
982 bool wxMDIChildFrame::HandleWindowPosChanging(void *pos)
983 {
984 // WINDOWPOS *lpPos = (WINDOWPOS *)pos;
985 return FALSE;
986 }
987
988 // ---------------------------------------------------------------------------
989 // MDI specific message translation/preprocessing
990 // ---------------------------------------------------------------------------
991
992 MRESULT 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
1002 bool wxMDIChildFrame::OS2TranslateMessage(WXMSG* msg)
1003 {
1004 return m_acceleratorTable.Translate(GetParent(), msg);
1005 }
1006
1007 // ---------------------------------------------------------------------------
1008 // misc
1009 // ---------------------------------------------------------------------------
1010
1011 void 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.)
1037 bool 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
1047 bool 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
1098 void 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
1118 static 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
1132 static 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
1167 static 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