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