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