]> git.saurik.com Git - wxWidgets.git/blame - src/msw/frame.cpp
added missing -univ package control files.
[wxWidgets.git] / src / msw / frame.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
7c0ea335 2// Name: msw/frame.cpp
1e6feb95 3// Purpose: wxFrameMSW
2bda0e17
KB
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
7c0ea335
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17 20#ifdef __GNUG__
7c0ea335 21 #pragma implementation "frame.h"
2bda0e17
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
9f3362c4 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
9f3362c4 32 #include "wx/frame.h"
9f3362c4 33 #include "wx/app.h"
1e6feb95 34 #include "wx/menu.h"
9f3362c4
VZ
35 #include "wx/utils.h"
36 #include "wx/dialog.h"
37 #include "wx/settings.h"
38 #include "wx/dcclient.h"
d3cc7c65 39 #include "wx/mdi.h"
f6bcfd97 40 #include "wx/panel.h"
9f3362c4 41#endif // WX_PRECOMP
2bda0e17
KB
42
43#include "wx/msw/private.h"
7c0ea335
VZ
44
45#if wxUSE_STATUSBAR
46 #include "wx/statusbr.h"
ed791986 47 #include "wx/generic/statusbr.h"
7c0ea335
VZ
48#endif // wxUSE_STATUSBAR
49
50#if wxUSE_TOOLBAR
51 #include "wx/toolbar.h"
52#endif // wxUSE_TOOLBAR
53
2bda0e17 54#include "wx/menuitem.h"
6776a0b2 55#include "wx/log.h"
2bda0e17 56
1e6feb95
VZ
57#ifdef __WXUNIVERSAL__
58 #include "wx/univ/theme.h"
59 #include "wx/univ/colschem.h"
60#endif // __WXUNIVERSAL__
61
7c0ea335
VZ
62// ----------------------------------------------------------------------------
63// globals
64// ----------------------------------------------------------------------------
2bda0e17 65
2ffa221c 66extern const wxChar *wxFrameClassName;
1e6feb95
VZ
67
68#if wxUSE_MENUS_NATIVE
e1a6fc11 69extern wxMenu *wxCurrentPopupMenu;
1e6feb95 70#endif // wxUSE_MENUS_NATIVE
2bda0e17 71
7c0ea335
VZ
72// ----------------------------------------------------------------------------
73// event tables
74// ----------------------------------------------------------------------------
75
1e6feb95
VZ
76BEGIN_EVENT_TABLE(wxFrameMSW, wxFrameBase)
77 EVT_ACTIVATE(wxFrameMSW::OnActivate)
78 EVT_SYS_COLOUR_CHANGED(wxFrameMSW::OnSysColourChanged)
2bda0e17
KB
79END_EVENT_TABLE()
80
6e264973 81#ifndef __WXUNIVERSAL__
af8964c4 82 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
6e264973 83#endif
2bda0e17 84
7c0ea335
VZ
85// ============================================================================
86// implementation
87// ============================================================================
88
89// ----------------------------------------------------------------------------
90// static class members
91// ----------------------------------------------------------------------------
92
1e6feb95
VZ
93#if wxUSE_STATUSBAR
94 #if wxUSE_NATIVE_STATUSBAR
95 bool wxFrameMSW::m_useNativeStatusBar = TRUE;
96 #else
97 bool wxFrameMSW::m_useNativeStatusBar = FALSE;
98 #endif
99#endif // wxUSE_NATIVE_STATUSBAR
2bda0e17 100
7c0ea335
VZ
101// ----------------------------------------------------------------------------
102// creation/destruction
103// ----------------------------------------------------------------------------
2bda0e17 104
1e6feb95 105void wxFrameMSW::Init()
2bda0e17 106{
9f3362c4
VZ
107#if wxUSE_TOOLTIPS
108 m_hwndToolTip = 0;
109#endif
a2327a9f
JS
110
111 // Data to save/restore when calling ShowFullScreen
112 m_fsStyle = 0;
113 m_fsOldWindowStyle = 0;
114 m_fsStatusBarFields = 0;
115 m_fsStatusBarHeight = 0;
116 m_fsToolBarHeight = 0;
f6bcfd97 117// m_fsMenu = 0;
a2327a9f
JS
118 m_fsIsMaximized = FALSE;
119 m_fsIsShowing = FALSE;
f6bcfd97
BP
120
121 m_winLastFocused = (wxWindow *)NULL;
122
123 // unlike (almost?) all other windows, frames are created hidden
124 m_isShown = FALSE;
7c0ea335 125}
9f3362c4 126
1e6feb95 127bool wxFrameMSW::Create(wxWindow *parent,
7c0ea335
VZ
128 wxWindowID id,
129 const wxString& title,
130 const wxPoint& pos,
131 const wxSize& size,
132 long style,
133 const wxString& name)
134{
82c9f85c
VZ
135 if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) )
136 return FALSE;
d2aef312 137
82c9f85c
VZ
138 // the frame must have NULL parent HWND or it would be always on top of its
139 // parent which is not what we usually want (in fact, we only want it for
140 // frames with the special wxFRAME_TOOL_WINDOW style handled elsewhere)
141 if ( !MSWCreate(m_windowId, NULL, wxFrameClassName, this, title,
142 pos.x, pos.y, size.x, size.y, style) )
143 return FALSE;
319fefa9 144
82c9f85c 145 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
2bda0e17 146
82c9f85c 147 wxModelessWindows.Append(this);
f6bcfd97 148
82c9f85c 149 return TRUE;
2bda0e17
KB
150}
151
1e6feb95 152wxFrameMSW::~wxFrameMSW()
2bda0e17 153{
82c9f85c 154 m_isBeingDeleted = TRUE;
2bda0e17 155
82c9f85c 156 DeleteAllBars();
2bda0e17
KB
157}
158
81d66cf3 159// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
1e6feb95 160void wxFrameMSW::DoGetClientSize(int *x, int *y) const
2bda0e17
KB
161{
162 RECT rect;
42e69d6b 163 ::GetClientRect(GetHwnd(), &rect);
2bda0e17 164
7c0ea335 165#if wxUSE_STATUSBAR
a2327a9f 166 if ( GetStatusBar() && GetStatusBar()->IsShown() )
2bda0e17 167 {
81d66cf3
JS
168 int statusX, statusY;
169 GetStatusBar()->GetClientSize(&statusX, &statusY);
170 rect.bottom -= statusY;
2bda0e17 171 }
7c0ea335 172#endif // wxUSE_STATUSBAR
81d66cf3
JS
173
174 wxPoint pt(GetClientAreaOrigin());
175 rect.bottom -= pt.y;
176 rect.right -= pt.x;
177
0655ad29
VZ
178 if ( x )
179 *x = rect.right;
180 if ( y )
181 *y = rect.bottom;
2bda0e17
KB
182}
183
1e6feb95 184void wxFrameMSW::DoSetClientSize(int width, int height)
2bda0e17 185{
82c9f85c 186 // leave enough space for the status bar if we have (and show) it
7c0ea335 187#if wxUSE_STATUSBAR
8d8bd249
VZ
188 wxStatusBar *statbar = GetStatusBar();
189 if ( statbar && statbar->IsShown() )
190 {
8d8bd249
VZ
191 height += statbar->GetSize().y;
192 }
7c0ea335 193#endif // wxUSE_STATUSBAR
2bda0e17 194
82c9f85c 195 wxTopLevelWindow::DoSetClientSize(width, height);
2bda0e17
KB
196}
197
7c0ea335 198// ----------------------------------------------------------------------------
82c9f85c 199// wxFrameMSW: various geometry-related functions
7c0ea335
VZ
200// ----------------------------------------------------------------------------
201
c48926e1
VZ
202void wxFrameMSW::Raise()
203{
204#ifdef __WIN16__
205 // no SetForegroundWindow() in Win16
206 wxFrameBase::Raise();
207#else // Win32
208 ::SetForegroundWindow(GetHwnd());
209#endif // Win16/32
210}
211
67bd5bad 212// generate an artificial resize event
3a12b404 213void wxFrameMSW::SendSizeEvent()
67bd5bad 214{
67bd5bad
GT
215 if ( !m_iconized )
216 {
82c9f85c
VZ
217 RECT r = wxGetWindowRect(GetHwnd());
218
67bd5bad
GT
219 (void)::PostMessage(GetHwnd(), WM_SIZE,
220 IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
221 MAKELPARAM(r.right - r.left, r.bottom - r.top));
222 }
223}
224
d427503c 225#if wxUSE_STATUSBAR
1e6feb95 226wxStatusBar *wxFrameMSW::OnCreateStatusBar(int number,
7c0ea335
VZ
227 long style,
228 wxWindowID id,
229 const wxString& name)
2bda0e17
KB
230{
231 wxStatusBar *statusBar = NULL;
232
47d67540 233#if wxUSE_NATIVE_STATUSBAR
1f0500b3 234 if ( !UsesNativeStatusBar() )
2bda0e17 235 {
1f0500b3 236 statusBar = (wxStatusBar *)new wxStatusBarGeneric(this, id, style);
2bda0e17
KB
237 }
238 else
239#endif
240 {
1f0500b3
VZ
241 statusBar = new wxStatusBar(this, id, style, name);
242 }
ed791986 243
1f0500b3
VZ
244 // Set the height according to the font and the border size
245 wxClientDC dc(statusBar);
246 dc.SetFont(statusBar->GetFont());
ed791986 247
1f0500b3
VZ
248 wxCoord y;
249 dc.GetTextExtent(_T("X"), NULL, &y );
ed791986 250
1f0500b3 251 int height = (int)( (11*y)/10 + 2*statusBar->GetBorderY());
ed791986 252
1f0500b3 253 statusBar->SetSize(-1, -1, -1, height);
ed791986 254
1f0500b3 255 statusBar->SetFieldsCount(number);
2bda0e17 256
7c0ea335 257 return statusBar;
2bda0e17
KB
258}
259
1e6feb95 260void wxFrameMSW::PositionStatusBar()
2bda0e17 261{
ed791986
VZ
262 if ( !m_frameStatusBar )
263 return;
264
cbc66a27
VZ
265 int w, h;
266 GetClientSize(&w, &h);
267 int sw, sh;
268 m_frameStatusBar->GetSize(&sw, &sh);
269
270 // Since we wish the status bar to be directly under the client area,
271 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
272 m_frameStatusBar->SetSize(0, h, w, sh);
2bda0e17 273}
d427503c 274#endif // wxUSE_STATUSBAR
2bda0e17 275
6522713c 276#if wxUSE_MENUS_NATIVE
ea9a4296 277
6522713c 278void wxFrameMSW::AttachMenuBar(wxMenuBar *menubar)
2bda0e17 279{
f008af16 280 wxFrameBase::AttachMenuBar(menubar);
6beb85c0 281
f6bcfd97 282 if ( !menubar )
c2dcfdef 283 {
f6bcfd97
BP
284 // actually remove the menu from the frame
285 m_hMenu = (WXHMENU)0;
286 InternalSetMenuBar();
065de612 287 }
f6bcfd97 288 else // set new non NULL menu bar
065de612 289 {
f6bcfd97 290 // Can set a menubar several times.
f6bcfd97
BP
291 if ( menubar->GetHMenu() )
292 {
293 m_hMenu = menubar->GetHMenu();
294 }
f008af16 295 else // no HMENU yet
f6bcfd97 296 {
f6bcfd97 297 m_hMenu = menubar->Create();
065de612 298
f6bcfd97 299 if ( !m_hMenu )
f008af16
VZ
300 {
301 wxFAIL_MSG( _T("failed to create menu bar") );
f6bcfd97 302 return;
f008af16 303 }
f6bcfd97 304 }
065de612 305
f6bcfd97 306 InternalSetMenuBar();
1e6feb95 307 }
2bda0e17
KB
308}
309
1e6feb95 310void wxFrameMSW::InternalSetMenuBar()
2bda0e17 311{
04ef50df 312#ifndef __WXMICROWIN__
42e69d6b 313 if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) )
2bda0e17 314 {
f6bcfd97 315 wxLogLastError(wxT("SetMenu"));
2bda0e17 316 }
04ef50df 317#endif
2bda0e17
KB
318}
319
1e6feb95
VZ
320#endif // wxUSE_MENUS_NATIVE
321
2bda0e17 322// Responds to colour changes, and passes event on to children.
1e6feb95 323void wxFrameMSW::OnSysColourChanged(wxSysColourChangedEvent& event)
2bda0e17
KB
324{
325 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
326 Refresh();
327
1e6feb95 328#if wxUSE_STATUSBAR
2bda0e17
KB
329 if ( m_frameStatusBar )
330 {
331 wxSysColourChangedEvent event2;
332 event2.SetEventObject( m_frameStatusBar );
02800301 333 m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
2bda0e17 334 }
1e6feb95 335#endif // wxUSE_STATUSBAR
2bda0e17
KB
336
337 // Propagate the event to the non-top-level children
338 wxWindow::OnSysColourChanged(event);
339}
340
a2327a9f 341// Pass TRUE to show full screen, FALSE to restore.
1e6feb95 342bool wxFrameMSW::ShowFullScreen(bool show, long style)
a2327a9f
JS
343{
344 if (show)
345 {
346 if (IsFullScreen())
347 return FALSE;
348
349 m_fsIsShowing = TRUE;
350 m_fsStyle = style;
351
1e6feb95 352#if wxUSE_TOOLBAR
f6bcfd97 353 wxToolBar *theToolBar = GetToolBar();
a2327a9f 354 if (theToolBar)
1e6feb95 355 theToolBar->GetSize(NULL, &m_fsToolBarHeight);
a2327a9f
JS
356
357 // zap the toolbar, menubar, and statusbar
358
359 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
360 {
361 theToolBar->SetSize(-1,0);
362 theToolBar->Show(FALSE);
363 }
1e6feb95 364#endif // wxUSE_TOOLBAR
a2327a9f 365
04ef50df 366#ifndef __WXMICROWIN__
a2327a9f
JS
367 if (style & wxFULLSCREEN_NOMENUBAR)
368 SetMenu((HWND)GetHWND(), (HMENU) NULL);
04ef50df 369#endif
a2327a9f 370
1e6feb95
VZ
371#if wxUSE_STATUSBAR
372 wxStatusBar *theStatusBar = GetStatusBar();
373 if (theStatusBar)
374 theStatusBar->GetSize(NULL, &m_fsStatusBarHeight);
375
a2327a9f
JS
376 // Save the number of fields in the statusbar
377 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
378 {
579b10c2
JS
379 //m_fsStatusBarFields = theStatusBar->GetFieldsCount();
380 //SetStatusBar((wxStatusBar*) NULL);
381 //delete theStatusBar;
382 theStatusBar->Show(FALSE);
a2327a9f
JS
383 }
384 else
385 m_fsStatusBarFields = 0;
1e6feb95 386#endif // wxUSE_STATUSBAR
a2327a9f
JS
387
388 // zap the frame borders
389
390 // save the 'normal' window style
391 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
392
f6bcfd97 393 // save the old position, width & height, maximize state
a2327a9f 394 m_fsOldSize = GetRect();
f6bcfd97 395 m_fsIsMaximized = IsMaximized();
a2327a9f 396
f6bcfd97 397 // decide which window style flags to turn off
a2327a9f
JS
398 LONG newStyle = m_fsOldWindowStyle;
399 LONG offFlags = 0;
400
401 if (style & wxFULLSCREEN_NOBORDER)
7900c71c 402 offFlags |= WS_BORDER | WS_THICKFRAME;
a2327a9f
JS
403 if (style & wxFULLSCREEN_NOCAPTION)
404 offFlags |= (WS_CAPTION | WS_SYSMENU);
405
406 newStyle &= (~offFlags);
407
408 // change our window style to be compatible with full-screen mode
82c9f85c 409 ::SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
a2327a9f
JS
410
411 // resize to the size of the desktop
412 int width, height;
413
82c9f85c 414 RECT rect = wxGetWindowRect(::GetDesktopWindow());
a2327a9f
JS
415 width = rect.right - rect.left;
416 height = rect.bottom - rect.top;
417
418 SetSize(width, height);
419
420 // now flush the window style cache and actually go full-screen
421 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
422
423 wxSizeEvent event(wxSize(width, height), GetId());
424 GetEventHandler()->ProcessEvent(event);
425
426 return TRUE;
427 }
428 else
429 {
430 if (!IsFullScreen())
431 return FALSE;
432
433 m_fsIsShowing = FALSE;
434
1e6feb95 435#if wxUSE_TOOLBAR
a2327a9f
JS
436 wxToolBar *theToolBar = GetToolBar();
437
438 // restore the toolbar, menubar, and statusbar
439 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
440 {
441 theToolBar->SetSize(-1, m_fsToolBarHeight);
442 theToolBar->Show(TRUE);
443 }
1e6feb95 444#endif // wxUSE_TOOLBAR
a2327a9f 445
1e6feb95
VZ
446#if wxUSE_STATUSBAR
447 if ( m_fsStyle & wxFULLSCREEN_NOSTATUSBAR )
a2327a9f 448 {
579b10c2
JS
449 //CreateStatusBar(m_fsStatusBarFields);
450 if (GetStatusBar())
451 {
452 GetStatusBar()->Show(TRUE);
453 PositionStatusBar();
454 }
a2327a9f 455 }
1e6feb95 456#endif // wxUSE_STATUSBAR
a2327a9f 457
04ef50df 458#ifndef __WXMICROWIN__
a2327a9f
JS
459 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
460 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
04ef50df 461#endif
a2327a9f
JS
462
463 Maximize(m_fsIsMaximized);
464 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
465 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
466 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
467
468 return TRUE;
469 }
470}
471
2bda0e17
KB
472/*
473 * Frame window
474 *
475 */
476
1e6feb95 477bool wxFrameMSW::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow *wx_win, const wxChar *title,
debe6624 478 int x, int y, int width, int height, long style)
2bda0e17
KB
479
480{
2bda0e17
KB
481 // If child windows aren't properly drawn initially, WS_CLIPCHILDREN
482 // could be the culprit. But without it, you can get a lot of flicker.
483
2bda0e17 484 DWORD msflags = 0;
3ca6a5f0
BP
485 if ( style & wxCAPTION )
486 {
487 if ( style & wxFRAME_TOOL_WINDOW )
488 msflags |= WS_POPUPWINDOW;
489 else
490 msflags |= WS_OVERLAPPED;
491 }
2bda0e17 492 else
3ca6a5f0
BP
493 {
494 msflags |= WS_POPUP;
495 }
2bda0e17
KB
496
497 if (style & wxMINIMIZE_BOX)
498 msflags |= WS_MINIMIZEBOX;
499 if (style & wxMAXIMIZE_BOX)
500 msflags |= WS_MAXIMIZEBOX;
501 if (style & wxTHICK_FRAME)
502 msflags |= WS_THICKFRAME;
503 if (style & wxSYSTEM_MENU)
504 msflags |= WS_SYSMENU;
f6bcfd97 505 if ( style & wxMINIMIZE )
2bda0e17
KB
506 msflags |= WS_MINIMIZE;
507 if (style & wxMAXIMIZE)
508 msflags |= WS_MAXIMIZE;
509 if (style & wxCAPTION)
510 msflags |= WS_CAPTION;
1c089c47
JS
511 if (style & wxCLIP_CHILDREN)
512 msflags |= WS_CLIPCHILDREN;
2bda0e17 513
1e6feb95 514 // Keep this in wxFrameMSW because it saves recoding this function
2bda0e17 515 // in wxTinyFrame
8355a72f 516#if wxUSE_ITSY_BITSY && !defined(__WIN32__)
2bda0e17
KB
517 if (style & wxTINY_CAPTION_VERT)
518 msflags |= IBS_VERTCAPTION;
519 if (style & wxTINY_CAPTION_HORIZ)
520 msflags |= IBS_HORZCAPTION;
521#else
522 if (style & wxTINY_CAPTION_VERT)
523 msflags |= WS_CAPTION;
524 if (style & wxTINY_CAPTION_HORIZ)
525 msflags |= WS_CAPTION;
526#endif
527 if ((style & wxTHICK_FRAME) == 0)
528 msflags |= WS_BORDER;
529
530 WXDWORD extendedStyle = MakeExtendedStyle(style);
531
b0a6bb75 532 // make all frames appear in the win9x shell taskbar unless
b3daa5a3 533 // wxFRAME_TOOL_WINDOW or wxFRAME_NO_TASKBAR is given - without giving them
b0a6bb75 534 // WS_EX_APPWINDOW style, the child (i.e. owned) frames wouldn't appear in it
2432b92d 535#if !defined(__WIN16__) && !defined(__SC__)
4b9fc37a
GT
536 if ( (style & wxFRAME_TOOL_WINDOW) ||
537 (style & wxFRAME_NO_TASKBAR) )
b0a6bb75 538 extendedStyle |= WS_EX_TOOLWINDOW;
b3daa5a3 539 else if ( !(style & wxFRAME_NO_TASKBAR) )
b0a6bb75 540 extendedStyle |= WS_EX_APPWINDOW;
1e6d9499 541#endif
cd2df130 542
2bda0e17
KB
543 if (style & wxSTAY_ON_TOP)
544 extendedStyle |= WS_EX_TOPMOST;
545
4204da65 546#ifndef __WIN16__
b96340e6
JS
547 if (m_exStyle & wxFRAME_EX_CONTEXTHELP)
548 extendedStyle |= WS_EX_CONTEXTHELP;
4204da65 549#endif
b96340e6 550
2bda0e17 551 m_iconized = FALSE;
a23fd0e1
VZ
552 if ( !wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height,
553 msflags, NULL, extendedStyle) )
554 return FALSE;
555
2bda0e17
KB
556 // Seems to be necessary if we use WS_POPUP
557 // style instead of WS_OVERLAPPED
558 if (width > -1 && height > -1)
42e69d6b 559 ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
a23fd0e1
VZ
560
561 return TRUE;
2bda0e17
KB
562}
563
2bda0e17
KB
564// Default activation behaviour - set the focus for the first child
565// subwindow found.
1e6feb95 566void wxFrameMSW::OnActivate(wxActivateEvent& event)
2bda0e17 567{
f6bcfd97 568 if ( event.GetActive() )
00c4e897 569 {
f6bcfd97 570 // restore focus to the child which was last focused
1e6feb95 571 wxLogTrace(_T("focus"), _T("wxFrameMSW %08x activated."), m_hWnd);
00c4e897 572
e9456d8d
VZ
573 wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
574 : NULL;
575 if ( !parent )
576 {
577 parent = this;
578 }
579
580 wxSetFocusToChild(parent, &m_winLastFocused);
00c4e897 581 }
e9456d8d 582 else // deactivating
2bda0e17 583 {
e9456d8d 584 // remember the last focused child if it is our child
f6bcfd97 585 m_winLastFocused = FindFocus();
e9456d8d
VZ
586
587 // so we NULL it out if it's a child from some other frame
588 wxWindow *win = m_winLastFocused;
589 while ( win )
319fefa9 590 {
e9456d8d
VZ
591 if ( win->IsTopLevel() )
592 {
593 if ( win != this )
594 {
595 m_winLastFocused = NULL;
596 }
597
f6bcfd97 598 break;
e9456d8d 599 }
f6bcfd97 600
e9456d8d 601 win = win->GetParent();
319fefa9 602 }
f6bcfd97
BP
603
604 wxLogTrace(_T("focus"),
1e6feb95 605 _T("wxFrameMSW %08x deactivated, last focused: %08x."),
f6bcfd97
BP
606 m_hWnd,
607 m_winLastFocused ? GetHwndOf(m_winLastFocused)
608 : NULL);
609
610 event.Skip();
2bda0e17 611 }
2bda0e17
KB
612}
613
7c0ea335
VZ
614// ----------------------------------------------------------------------------
615// tool/status bar stuff
616// ----------------------------------------------------------------------------
617
d427503c 618#if wxUSE_TOOLBAR
7c0ea335 619
1e6feb95 620wxToolBar* wxFrameMSW::CreateToolBar(long style, wxWindowID id, const wxString& name)
81d66cf3 621{
7c0ea335 622 if ( wxFrameBase::CreateToolBar(style, id, name) )
81d66cf3 623 {
81d66cf3 624 PositionToolBar();
81d66cf3 625 }
81d66cf3 626
7c0ea335 627 return m_frameToolBar;
81d66cf3
JS
628}
629
1e6feb95 630void wxFrameMSW::PositionToolBar()
81d66cf3 631{
81d66cf3 632 RECT rect;
42e69d6b 633 ::GetClientRect(GetHwnd(), &rect);
81d66cf3 634
7c0ea335 635#if wxUSE_STATUSBAR
81d66cf3
JS
636 if ( GetStatusBar() )
637 {
7c0ea335
VZ
638 int statusX, statusY;
639 GetStatusBar()->GetClientSize(&statusX, &statusY);
640 rect.bottom -= statusY;
81d66cf3 641 }
7c0ea335 642#endif // wxUSE_STATUSBAR
81d66cf3 643
a2327a9f 644 if ( GetToolBar() && GetToolBar()->IsShown() )
81d66cf3
JS
645 {
646 int tw, th;
7c0ea335 647 GetToolBar()->GetSize(&tw, &th);
81d66cf3 648
7c0ea335 649 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
81d66cf3 650 {
7c0ea335 651 th = rect.bottom;
81d66cf3
JS
652 }
653 else
654 {
7c0ea335 655 tw = rect.right;
81d66cf3 656 }
7c0ea335
VZ
657
658 // Use the 'real' MSW position here
659 GetToolBar()->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
81d66cf3
JS
660 }
661}
d427503c 662#endif // wxUSE_TOOLBAR
d2aef312 663
7c0ea335
VZ
664// ----------------------------------------------------------------------------
665// frame state (iconized/maximized/...)
666// ----------------------------------------------------------------------------
667
a23fd0e1
VZ
668// propagate our state change to all child frames: this allows us to emulate X
669// Windows behaviour where child frames float independently of the parent one
670// on the desktop, but are iconized/restored with it
1e6feb95 671void wxFrameMSW::IconizeChildFrames(bool bIconize)
d2aef312 672{
a23fd0e1
VZ
673 for ( wxWindowList::Node *node = GetChildren().GetFirst();
674 node;
675 node = node->GetNext() )
676 {
677 wxWindow *win = node->GetData();
678
3ca6a5f0
BP
679 // iconizing the frames with this style under Win95 shell puts them at
680 // the bottom of the screen (as the MDI children) instead of making
681 // them appear in the taskbar because they are, by virtue of this
682 // style, not managed by the taskbar - instead leave Windows take care
683 // of them
684#ifdef __WIN95__
685 if ( win->GetWindowStyle() & wxFRAME_TOOL_WINDOW )
686 continue;
687#endif // Win95
688
3f7bc32b
VZ
689 // the child MDI frames are a special case and should not be touched by
690 // the parent frame - instead, they are managed by the user
2e9f62da 691 wxFrame *frame = wxDynamicCast(win, wxFrame);
1e6feb95
VZ
692 if ( frame
693#if wxUSE_MDI_ARCHITECTURE
694 && !wxDynamicCast(frame, wxMDIChildFrame)
695#endif // wxUSE_MDI_ARCHITECTURE
696 )
a23fd0e1 697 {
3f7bc32b 698 frame->Iconize(bIconize);
a23fd0e1 699 }
d2aef312 700 }
d2aef312
VZ
701}
702
82c9f85c
VZ
703WXHICON wxFrameMSW::GetDefaultIcon() const
704{
705 return (WXHICON)(wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON
706 : wxDEFAULT_FRAME_ICON);
707}
708
a23fd0e1 709// ===========================================================================
42e69d6b 710// message processing
a23fd0e1
VZ
711// ===========================================================================
712
42e69d6b
VZ
713// ---------------------------------------------------------------------------
714// preprocessing
715// ---------------------------------------------------------------------------
716
1e6feb95 717bool wxFrameMSW::MSWTranslateMessage(WXMSG* pMsg)
42e69d6b
VZ
718{
719 if ( wxWindow::MSWTranslateMessage(pMsg) )
720 return TRUE;
721
1e6feb95 722#if wxUSE_MENUS && wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
42e69d6b
VZ
723 // try the menu bar accels
724 wxMenuBar *menuBar = GetMenuBar();
725 if ( !menuBar )
726 return FALSE;
727
728 const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
c50f1fb9 729 return acceleratorTable.Translate(this, pMsg);
1e6feb95
VZ
730#else
731 return FALSE;
732#endif // wxUSE_MENUS && wxUSE_ACCEL
42e69d6b
VZ
733}
734
735// ---------------------------------------------------------------------------
736// our private (non virtual) message handlers
737// ---------------------------------------------------------------------------
738
1e6feb95 739bool wxFrameMSW::HandlePaint()
42e69d6b
VZ
740{
741 RECT rect;
742 if ( GetUpdateRect(GetHwnd(), &rect, FALSE) )
743 {
04ef50df 744#ifndef __WXMICROWIN__
42e69d6b
VZ
745 if ( m_iconized )
746 {
c50f1fb9 747 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
82c9f85c 748 : (HICON)GetDefaultIcon();
42e69d6b
VZ
749
750 // Hold a pointer to the dc so long as the OnPaint() message
751 // is being processed
752 PAINTSTRUCT ps;
753 HDC hdc = ::BeginPaint(GetHwnd(), &ps);
754
755 // Erase background before painting or we get white background
756 MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L);
757
758 if ( hIcon )
759 {
760 RECT rect;
761 ::GetClientRect(GetHwnd(), &rect);
762
763 // FIXME: why hardcoded?
764 static const int icon_width = 32;
765 static const int icon_height = 32;
766
767 int icon_x = (int)((rect.right - icon_width)/2);
768 int icon_y = (int)((rect.bottom - icon_height)/2);
769
770 ::DrawIcon(hdc, icon_x, icon_y, hIcon);
771 }
772
773 ::EndPaint(GetHwnd(), &ps);
774
775 return TRUE;
776 }
777 else
04ef50df 778 #endif
42e69d6b 779 {
5d1d2d46 780 return wxWindow::HandlePaint();
42e69d6b
VZ
781 }
782 }
783 else
784 {
785 // nothing to paint - processed
786 return TRUE;
787 }
788}
789
1e6feb95 790bool wxFrameMSW::HandleSize(int x, int y, WXUINT id)
42e69d6b
VZ
791{
792 bool processed = FALSE;
04ef50df 793#ifndef __WXMICROWIN__
42e69d6b
VZ
794
795 switch ( id )
796 {
797 case SIZENORMAL:
798 // only do it it if we were iconized before, otherwise resizing the
799 // parent frame has a curious side effect of bringing it under it's
800 // children
801 if ( !m_iconized )
802 break;
803
804 // restore all child frames too
805 IconizeChildFrames(FALSE);
806
3dd9b88a
VZ
807 (void)SendIconizeEvent(FALSE);
808
42e69d6b
VZ
809 // fall through
810
811 case SIZEFULLSCREEN:
812 m_iconized = FALSE;
813 break;
814
815 case SIZEICONIC:
816 // iconize all child frames too
817 IconizeChildFrames(TRUE);
818
3dd9b88a
VZ
819 (void)SendIconizeEvent();
820
42e69d6b
VZ
821 m_iconized = TRUE;
822 break;
823 }
04ef50df 824#endif
42e69d6b
VZ
825
826 if ( !m_iconized )
827 {
1e6feb95 828#if wxUSE_STATUSBAR
42e69d6b 829 PositionStatusBar();
1e6feb95
VZ
830#endif // wxUSE_STATUSBAR
831
832#if wxUSE_TOOLBAR
42e69d6b 833 PositionToolBar();
1e6feb95 834#endif // wxUSE_TOOLBAR
42e69d6b
VZ
835
836 wxSizeEvent event(wxSize(x, y), m_windowId);
837 event.SetEventObject( this );
838 processed = GetEventHandler()->ProcessEvent(event);
839 }
840
841 return processed;
842}
843
1e6feb95 844bool wxFrameMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
42e69d6b
VZ
845{
846 if ( control )
847 {
848 // In case it's e.g. a toolbar.
849 wxWindow *win = wxFindWinFromHandle(control);
850 if ( win )
851 return win->MSWCommand(cmd, id);
852 }
853
854 // handle here commands from menus and accelerators
855 if ( cmd == 0 || cmd == 1 )
856 {
1e6feb95 857#if wxUSE_MENUS_NATIVE
42e69d6b
VZ
858 if ( wxCurrentPopupMenu )
859 {
860 wxMenu *popupMenu = wxCurrentPopupMenu;
861 wxCurrentPopupMenu = NULL;
862
863 return popupMenu->MSWCommand(cmd, id);
864 }
1e6feb95 865#endif // wxUSE_MENUS_NATIVE
42e69d6b
VZ
866
867 if ( ProcessCommand(id) )
868 {
869 return TRUE;
870 }
871 }
872
873 return FALSE;
874}
875
1e6feb95 876bool wxFrameMSW::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
a23fd0e1
VZ
877{
878 int item;
c219cecc 879 if ( flags == 0xFFFF && hMenu == 0 )
a23fd0e1 880 {
c219cecc 881 // menu was removed from screen
a23fd0e1
VZ
882 item = -1;
883 }
04ef50df 884#ifndef __WXMICROWIN__
c219cecc 885 else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) )
a23fd0e1
VZ
886 {
887 item = nItem;
888 }
04ef50df 889#endif
a23fd0e1
VZ
890 else
891 {
1e6feb95 892#if wxUSE_STATUSBAR
c219cecc 893 // don't give hints for separators (doesn't make sense) nor for the
f6bcfd97
BP
894 // items opening popup menus (they don't have them anyhow) but do clear
895 // the status line - otherwise, we would be left with the help message
896 // for the previous item which doesn't apply any more
897 wxStatusBar *statbar = GetStatusBar();
898 if ( statbar )
899 {
900 statbar->SetStatusText(wxEmptyString);
901 }
1e6feb95 902#endif // wxUSE_STATUSBAR
f6bcfd97 903
a23fd0e1
VZ
904 return FALSE;
905 }
906
907 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
908 event.SetEventObject( this );
909
910 return GetEventHandler()->ProcessEvent(event);
911}
912
913// ---------------------------------------------------------------------------
1e6feb95 914// the window proc for wxFrameMSW
a23fd0e1
VZ
915// ---------------------------------------------------------------------------
916
1e6feb95 917long wxFrameMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
a23fd0e1
VZ
918{
919 long rc = 0;
920 bool processed = FALSE;
921
922 switch ( message )
923 {
42e69d6b
VZ
924 case WM_CLOSE:
925 // if we can't close, tell the system that we processed the
926 // message - otherwise it would close us
927 processed = !Close();
928 break;
929
930 case WM_COMMAND:
931 {
932 WORD id, cmd;
933 WXHWND hwnd;
934 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
935 &id, &hwnd, &cmd);
936
937 processed = HandleCommand(id, cmd, (WXHWND)hwnd);
938 }
939 break;
940
04ef50df 941#ifndef __WXMICROWIN__
a23fd0e1
VZ
942 case WM_MENUSELECT:
943 {
42e69d6b
VZ
944 WXWORD item, flags;
945 WXHMENU hmenu;
946 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
947
948 processed = HandleMenuSelect(item, flags, hmenu);
a23fd0e1
VZ
949 }
950 break;
04ef50df 951#endif
42e69d6b
VZ
952
953 case WM_PAINT:
954 processed = HandlePaint();
955 break;
956
04ef50df 957#ifndef __WXMICROWIN__
42e69d6b
VZ
958 case WM_QUERYDRAGICON:
959 {
c50f1fb9 960 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
82c9f85c 961 : (HICON)GetDefaultIcon();
42e69d6b
VZ
962 rc = (long)hIcon;
963 processed = rc != 0;
964 }
965 break;
04ef50df 966#endif
42e69d6b
VZ
967
968 case WM_SIZE:
969 processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
970 break;
a23fd0e1
VZ
971 }
972
973 if ( !processed )
974 rc = wxWindow::MSWWindowProc(message, wParam, lParam);
975
976 return rc;
977}
21802234 978