]> git.saurik.com Git - wxWidgets.git/blame - src/msw/frame.cpp
better focus handling (blind fix)
[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
a23fd0e1 66extern wxWindowList wxModelessWindows;
2ffa221c 67extern const wxChar *wxFrameClassName;
1e6feb95
VZ
68
69#if wxUSE_MENUS_NATIVE
e1a6fc11 70extern wxMenu *wxCurrentPopupMenu;
1e6feb95 71#endif // wxUSE_MENUS_NATIVE
2bda0e17 72
7c0ea335
VZ
73// ----------------------------------------------------------------------------
74// event tables
75// ----------------------------------------------------------------------------
76
1e6feb95
VZ
77BEGIN_EVENT_TABLE(wxFrameMSW, wxFrameBase)
78 EVT_ACTIVATE(wxFrameMSW::OnActivate)
79 EVT_SYS_COLOUR_CHANGED(wxFrameMSW::OnSysColourChanged)
2bda0e17
KB
80END_EVENT_TABLE()
81
6e264973 82#ifndef __WXUNIVERSAL__
af8964c4 83 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
6e264973 84#endif
2bda0e17 85
7c0ea335
VZ
86// ============================================================================
87// implementation
88// ============================================================================
89
90// ----------------------------------------------------------------------------
91// static class members
92// ----------------------------------------------------------------------------
93
1e6feb95
VZ
94#if wxUSE_STATUSBAR
95 #if wxUSE_NATIVE_STATUSBAR
96 bool wxFrameMSW::m_useNativeStatusBar = TRUE;
97 #else
98 bool wxFrameMSW::m_useNativeStatusBar = FALSE;
99 #endif
100#endif // wxUSE_NATIVE_STATUSBAR
2bda0e17 101
7c0ea335
VZ
102// ----------------------------------------------------------------------------
103// creation/destruction
104// ----------------------------------------------------------------------------
2bda0e17 105
1e6feb95 106void wxFrameMSW::Init()
2bda0e17 107{
bf505d28
VZ
108 m_iconized =
109 m_maximizeOnShow = FALSE;
7c0ea335 110
9f3362c4
VZ
111#if wxUSE_TOOLTIPS
112 m_hwndToolTip = 0;
113#endif
a2327a9f
JS
114
115 // Data to save/restore when calling ShowFullScreen
116 m_fsStyle = 0;
117 m_fsOldWindowStyle = 0;
118 m_fsStatusBarFields = 0;
119 m_fsStatusBarHeight = 0;
120 m_fsToolBarHeight = 0;
f6bcfd97 121// m_fsMenu = 0;
a2327a9f
JS
122 m_fsIsMaximized = FALSE;
123 m_fsIsShowing = FALSE;
f6bcfd97
BP
124
125 m_winLastFocused = (wxWindow *)NULL;
126
127 // unlike (almost?) all other windows, frames are created hidden
128 m_isShown = FALSE;
7c0ea335 129}
9f3362c4 130
1e6feb95 131bool wxFrameMSW::Create(wxWindow *parent,
7c0ea335
VZ
132 wxWindowID id,
133 const wxString& title,
134 const wxPoint& pos,
135 const wxSize& size,
136 long style,
137 const wxString& name)
138{
2bda0e17 139 SetName(name);
2bda0e17 140 m_windowStyle = style;
2bda0e17
KB
141
142 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
143
2bda0e17
KB
144 if ( id > -1 )
145 m_windowId = id;
146 else
147 m_windowId = (int)NewControlId();
148
149 if (parent) parent->AddChild(this);
150
151 int x = pos.x;
152 int y = pos.y;
153 int width = size.x;
154 int height = size.y;
155
156 m_iconized = FALSE;
d2aef312 157
f6bcfd97 158 wxTopLevelWindows.Append(this);
319fefa9 159
bb6e7c18
VZ
160 // the frame must have NULL parent HWND or it would be always on top of its
161 // parent which is not what we usually want (in fact, we only want it for
162 // frames with the special wxFRAME_TOOL_WINDOW style handled elsewhere)
163 MSWCreate(m_windowId, NULL, wxFrameClassName, this, title,
d2aef312 164 x, y, width, height, style);
2bda0e17
KB
165
166 wxModelessWindows.Append(this);
f6bcfd97 167
2bda0e17
KB
168 return TRUE;
169}
170
1e6feb95 171wxFrameMSW::~wxFrameMSW()
2bda0e17
KB
172{
173 m_isBeingDeleted = TRUE;
174 wxTopLevelWindows.DeleteObject(this);
175
f6bcfd97
BP
176 // the ~wxToolBar() code relies on the previous line to be executed before
177 // this one, i.e. the frame should remove itself from wxTopLevelWindows
178 // before destorying its toolbar
7c0ea335 179 DeleteAllBars();
2bda0e17
KB
180
181 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
182 {
183 wxTheApp->SetTopWindow(NULL);
184
185 if (wxTheApp->GetExitOnFrameDelete())
186 {
187 PostQuitMessage(0);
188 }
189 }
190
191 wxModelessWindows.DeleteObject(this);
192
193 // For some reason, wxWindows can activate another task altogether
194 // when a frame is destroyed after a modal dialog has been invoked.
195 // Try to bring the parent to the top.
36e2955a
UM
196 // MT:Only do this if this frame is currently the active window, else weird
197 // things start to happen
198 if ( wxGetActiveWindow() == this )
2bda0e17
KB
199 if (GetParent() && GetParent()->GetHWND())
200 ::BringWindowToTop((HWND) GetParent()->GetHWND());
201}
202
81d66cf3 203// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
1e6feb95 204void wxFrameMSW::DoGetClientSize(int *x, int *y) const
2bda0e17
KB
205{
206 RECT rect;
42e69d6b 207 ::GetClientRect(GetHwnd(), &rect);
2bda0e17 208
7c0ea335 209#if wxUSE_STATUSBAR
a2327a9f 210 if ( GetStatusBar() && GetStatusBar()->IsShown() )
2bda0e17 211 {
81d66cf3
JS
212 int statusX, statusY;
213 GetStatusBar()->GetClientSize(&statusX, &statusY);
214 rect.bottom -= statusY;
2bda0e17 215 }
7c0ea335 216#endif // wxUSE_STATUSBAR
81d66cf3
JS
217
218 wxPoint pt(GetClientAreaOrigin());
219 rect.bottom -= pt.y;
220 rect.right -= pt.x;
221
0655ad29
VZ
222 if ( x )
223 *x = rect.right;
224 if ( y )
225 *y = rect.bottom;
2bda0e17
KB
226}
227
228// Set the client size (i.e. leave the calculation of borders etc.
229// to wxWindows)
1e6feb95 230void wxFrameMSW::DoSetClientSize(int width, int height)
2bda0e17 231{
8d8bd249 232 HWND hWnd = GetHwnd();
2bda0e17 233
8d8bd249
VZ
234 RECT rectClient;
235 ::GetClientRect(hWnd, &rectClient);
2bda0e17 236
8d8bd249
VZ
237 RECT rectTotal;
238 ::GetWindowRect(hWnd, &rectTotal);
2bda0e17 239
8d8bd249
VZ
240 // Find the difference between the entire window (title bar and all)
241 // and the client area; add this to the new client size to move the
242 // window
243 width += rectTotal.right - rectTotal.left - rectClient.right;
244 height += rectTotal.bottom - rectTotal.top - rectClient.bottom;
2bda0e17 245
7c0ea335 246#if wxUSE_STATUSBAR
8d8bd249
VZ
247 wxStatusBar *statbar = GetStatusBar();
248 if ( statbar && statbar->IsShown() )
249 {
250 // leave enough space for the status bar
251 height += statbar->GetSize().y;
252 }
7c0ea335 253#endif // wxUSE_STATUSBAR
2bda0e17 254
8d8bd249
VZ
255 // note that this takes the toolbar into account
256 wxPoint pt = GetClientAreaOrigin();
257 width += pt.x;
258 height += pt.y;
2bda0e17 259
8d8bd249
VZ
260 if ( !::MoveWindow(hWnd, rectTotal.left, rectTotal.top,
261 width, height, TRUE /* redraw */) )
262 {
263 wxLogLastError(_T("MoveWindow"));
264 }
debe6624 265
8d8bd249
VZ
266 wxSizeEvent event(wxSize(width, height), m_windowId);
267 event.SetEventObject(this);
268 GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
269}
270
1e6feb95 271void wxFrameMSW::DoGetSize(int *width, int *height) const
2bda0e17 272{
3dd9b88a
VZ
273 RECT rect;
274 ::GetWindowRect(GetHwnd(), &rect);
275
276 *width = rect.right - rect.left;
277 *height = rect.bottom - rect.top;
2bda0e17
KB
278}
279
1e6feb95 280void wxFrameMSW::DoGetPosition(int *x, int *y) const
2bda0e17 281{
3dd9b88a
VZ
282 RECT rect;
283 ::GetWindowRect(GetHwnd(), &rect);
2bda0e17 284
3dd9b88a
VZ
285 *x = rect.left;
286 *y = rect.top;
2bda0e17
KB
287}
288
7c0ea335
VZ
289// ----------------------------------------------------------------------------
290// variations around ::ShowWindow()
291// ----------------------------------------------------------------------------
292
1e6feb95 293void wxFrameMSW::DoShowWindow(int nShowCmd)
7c0ea335
VZ
294{
295 ::ShowWindow(GetHwnd(), nShowCmd);
296
297 m_iconized = nShowCmd == SW_MINIMIZE;
298}
299
1e6feb95 300bool wxFrameMSW::Show(bool show)
2bda0e17 301{
f6bcfd97
BP
302 // don't use wxWindow version as we want to call DoShowWindow()
303 if ( !wxWindowBase::Show(show) )
304 return FALSE;
305
bf505d28
VZ
306 int nShowCmd;
307 if ( show )
308 {
309 if ( m_maximizeOnShow )
310 {
311 // show and maximize
312 nShowCmd = SW_MAXIMIZE;
313
314 m_maximizeOnShow = FALSE;
315 }
316 else // just show
317 {
318 nShowCmd = SW_SHOW;
319 }
320 }
321 else // hide
322 {
323 nShowCmd = SW_HIDE;
324 }
325
326 DoShowWindow(nShowCmd);
2bda0e17 327
7c0ea335 328 if ( show )
2bda0e17 329 {
7c0ea335 330 ::BringWindowToTop(GetHwnd());
2bda0e17 331
7c0ea335
VZ
332 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId);
333 event.SetEventObject( this );
334 GetEventHandler()->ProcessEvent(event);
335 }
bf505d28 336 else // hide
7c0ea335
VZ
337 {
338 // Try to highlight the correct window (the parent)
339 if ( GetParent() )
340 {
341 HWND hWndParent = GetHwndOf(GetParent());
342 if (hWndParent)
343 ::BringWindowToTop(hWndParent);
344 }
345 }
2bda0e17 346
7c0ea335 347 return TRUE;
2bda0e17
KB
348}
349
1e6feb95 350void wxFrameMSW::Iconize(bool iconize)
2bda0e17 351{
7c0ea335 352 DoShowWindow(iconize ? SW_MINIMIZE : SW_RESTORE);
2bda0e17
KB
353}
354
1e6feb95 355void wxFrameMSW::Maximize(bool maximize)
2bda0e17 356{
bf505d28
VZ
357 if ( IsShown() )
358 {
359 // just maximize it directly
360 DoShowWindow(maximize ? SW_MAXIMIZE : SW_RESTORE);
361 }
362 else // hidden
363 {
364 // we can't maximize the hidden frame because it shows it as well, so
365 // just remember that we should do it later in this case
366 m_maximizeOnShow = TRUE;
367 }
7c0ea335
VZ
368}
369
1e6feb95 370void wxFrameMSW::Restore()
7c0ea335
VZ
371{
372 DoShowWindow(SW_RESTORE);
2bda0e17
KB
373}
374
1e6feb95 375bool wxFrameMSW::IsIconized() const
2bda0e17 376{
04ef50df
JS
377#ifdef __WXMICROWIN__
378 // TODO
379 return FALSE;
380#else
1e6feb95 381 ((wxFrameMSW *)this)->m_iconized = (::IsIconic(GetHwnd()) != 0);
2bda0e17 382 return m_iconized;
04ef50df 383#endif
2bda0e17
KB
384}
385
6f63ec3f 386// Is it maximized?
1e6feb95 387bool wxFrameMSW::IsMaximized() const
6f63ec3f 388{
04ef50df
JS
389#ifdef __WXMICROWIN__
390 // TODO
391 return FALSE;
392#else
7c0ea335 393 return (::IsZoomed(GetHwnd()) != 0);
04ef50df 394#endif
2bda0e17
KB
395}
396
1e6feb95 397void wxFrameMSW::SetIcon(const wxIcon& icon)
2bda0e17 398{
7c0ea335
VZ
399 wxFrameBase::SetIcon(icon);
400
04ef50df 401#if defined(__WIN95__) && !defined(__WXMICROWIN__)
7c0ea335
VZ
402 if ( m_icon.Ok() )
403 {
404 SendMessage(GetHwnd(), WM_SETICON,
405 (WPARAM)TRUE, (LPARAM)(HICON) m_icon.GetHICON());
406 }
407#endif // __WIN95__
2bda0e17
KB
408}
409
67bd5bad 410// generate an artificial resize event
3a12b404 411void wxFrameMSW::SendSizeEvent()
67bd5bad
GT
412{
413 RECT r;
414#ifdef __WIN16__
415 ::GetWindowRect(GetHwnd(), &r);
416#else
417 if ( !::GetWindowRect(GetHwnd(), &r) )
418 {
419 wxLogLastError(_T("GetWindowRect"));
420 }
421#endif
422
423 if ( !m_iconized )
424 {
425 (void)::PostMessage(GetHwnd(), WM_SIZE,
426 IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
427 MAKELPARAM(r.right - r.left, r.bottom - r.top));
428 }
429}
430
d427503c 431#if wxUSE_STATUSBAR
1e6feb95 432wxStatusBar *wxFrameMSW::OnCreateStatusBar(int number,
7c0ea335
VZ
433 long style,
434 wxWindowID id,
435 const wxString& name)
2bda0e17
KB
436{
437 wxStatusBar *statusBar = NULL;
438
47d67540 439#if wxUSE_NATIVE_STATUSBAR
1f0500b3 440 if ( !UsesNativeStatusBar() )
2bda0e17 441 {
1f0500b3 442 statusBar = (wxStatusBar *)new wxStatusBarGeneric(this, id, style);
2bda0e17
KB
443 }
444 else
445#endif
446 {
1f0500b3
VZ
447 statusBar = new wxStatusBar(this, id, style, name);
448 }
ed791986 449
1f0500b3
VZ
450 // Set the height according to the font and the border size
451 wxClientDC dc(statusBar);
452 dc.SetFont(statusBar->GetFont());
ed791986 453
1f0500b3
VZ
454 wxCoord y;
455 dc.GetTextExtent(_T("X"), NULL, &y );
ed791986 456
1f0500b3 457 int height = (int)( (11*y)/10 + 2*statusBar->GetBorderY());
ed791986 458
1f0500b3 459 statusBar->SetSize(-1, -1, -1, height);
ed791986 460
1f0500b3 461 statusBar->SetFieldsCount(number);
2bda0e17 462
7c0ea335 463 return statusBar;
2bda0e17
KB
464}
465
1e6feb95 466void wxFrameMSW::PositionStatusBar()
2bda0e17 467{
ed791986
VZ
468 if ( !m_frameStatusBar )
469 return;
470
cbc66a27
VZ
471 int w, h;
472 GetClientSize(&w, &h);
473 int sw, sh;
474 m_frameStatusBar->GetSize(&sw, &sh);
475
476 // Since we wish the status bar to be directly under the client area,
477 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
478 m_frameStatusBar->SetSize(0, h, w, sh);
2bda0e17 479}
d427503c 480#endif // wxUSE_STATUSBAR
2bda0e17 481
6522713c 482#if wxUSE_MENUS_NATIVE
ea9a4296 483
6522713c 484void wxFrameMSW::AttachMenuBar(wxMenuBar *menubar)
2bda0e17 485{
f008af16 486 wxFrameBase::AttachMenuBar(menubar);
6beb85c0 487
f6bcfd97 488 if ( !menubar )
c2dcfdef 489 {
f6bcfd97
BP
490 // actually remove the menu from the frame
491 m_hMenu = (WXHMENU)0;
492 InternalSetMenuBar();
065de612 493 }
f6bcfd97 494 else // set new non NULL menu bar
065de612 495 {
f6bcfd97 496 // Can set a menubar several times.
f6bcfd97
BP
497 if ( menubar->GetHMenu() )
498 {
499 m_hMenu = menubar->GetHMenu();
500 }
f008af16 501 else // no HMENU yet
f6bcfd97 502 {
f6bcfd97 503 m_hMenu = menubar->Create();
065de612 504
f6bcfd97 505 if ( !m_hMenu )
f008af16
VZ
506 {
507 wxFAIL_MSG( _T("failed to create menu bar") );
f6bcfd97 508 return;
f008af16 509 }
f6bcfd97 510 }
065de612 511
f6bcfd97 512 InternalSetMenuBar();
1e6feb95 513 }
2bda0e17
KB
514}
515
1e6feb95 516void wxFrameMSW::InternalSetMenuBar()
2bda0e17 517{
04ef50df 518#ifndef __WXMICROWIN__
42e69d6b 519 if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) )
2bda0e17 520 {
f6bcfd97 521 wxLogLastError(wxT("SetMenu"));
2bda0e17 522 }
04ef50df 523#endif
2bda0e17
KB
524}
525
1e6feb95
VZ
526#endif // wxUSE_MENUS_NATIVE
527
2bda0e17 528// Responds to colour changes, and passes event on to children.
1e6feb95 529void wxFrameMSW::OnSysColourChanged(wxSysColourChangedEvent& event)
2bda0e17
KB
530{
531 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
532 Refresh();
533
1e6feb95 534#if wxUSE_STATUSBAR
2bda0e17
KB
535 if ( m_frameStatusBar )
536 {
537 wxSysColourChangedEvent event2;
538 event2.SetEventObject( m_frameStatusBar );
02800301 539 m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
2bda0e17 540 }
1e6feb95 541#endif // wxUSE_STATUSBAR
2bda0e17
KB
542
543 // Propagate the event to the non-top-level children
544 wxWindow::OnSysColourChanged(event);
545}
546
a2327a9f 547// Pass TRUE to show full screen, FALSE to restore.
1e6feb95 548bool wxFrameMSW::ShowFullScreen(bool show, long style)
a2327a9f
JS
549{
550 if (show)
551 {
552 if (IsFullScreen())
553 return FALSE;
554
555 m_fsIsShowing = TRUE;
556 m_fsStyle = style;
557
1e6feb95 558#if wxUSE_TOOLBAR
f6bcfd97 559 wxToolBar *theToolBar = GetToolBar();
a2327a9f 560 if (theToolBar)
1e6feb95 561 theToolBar->GetSize(NULL, &m_fsToolBarHeight);
a2327a9f
JS
562
563 // zap the toolbar, menubar, and statusbar
564
565 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
566 {
567 theToolBar->SetSize(-1,0);
568 theToolBar->Show(FALSE);
569 }
1e6feb95 570#endif // wxUSE_TOOLBAR
a2327a9f 571
04ef50df 572#ifndef __WXMICROWIN__
a2327a9f
JS
573 if (style & wxFULLSCREEN_NOMENUBAR)
574 SetMenu((HWND)GetHWND(), (HMENU) NULL);
04ef50df 575#endif
a2327a9f 576
1e6feb95
VZ
577#if wxUSE_STATUSBAR
578 wxStatusBar *theStatusBar = GetStatusBar();
579 if (theStatusBar)
580 theStatusBar->GetSize(NULL, &m_fsStatusBarHeight);
581
a2327a9f
JS
582 // Save the number of fields in the statusbar
583 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
584 {
579b10c2
JS
585 //m_fsStatusBarFields = theStatusBar->GetFieldsCount();
586 //SetStatusBar((wxStatusBar*) NULL);
587 //delete theStatusBar;
588 theStatusBar->Show(FALSE);
a2327a9f
JS
589 }
590 else
591 m_fsStatusBarFields = 0;
1e6feb95 592#endif // wxUSE_STATUSBAR
a2327a9f
JS
593
594 // zap the frame borders
595
596 // save the 'normal' window style
597 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
598
f6bcfd97 599 // save the old position, width & height, maximize state
a2327a9f 600 m_fsOldSize = GetRect();
f6bcfd97 601 m_fsIsMaximized = IsMaximized();
a2327a9f 602
f6bcfd97 603 // decide which window style flags to turn off
a2327a9f
JS
604 LONG newStyle = m_fsOldWindowStyle;
605 LONG offFlags = 0;
606
607 if (style & wxFULLSCREEN_NOBORDER)
608 offFlags |= WS_BORDER;
609 if (style & wxFULLSCREEN_NOCAPTION)
610 offFlags |= (WS_CAPTION | WS_SYSMENU);
611
612 newStyle &= (~offFlags);
613
614 // change our window style to be compatible with full-screen mode
615 SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
616
617 // resize to the size of the desktop
618 int width, height;
619
620 RECT rect;
621 ::GetWindowRect(GetDesktopWindow(), &rect);
622 width = rect.right - rect.left;
623 height = rect.bottom - rect.top;
624
625 SetSize(width, height);
626
627 // now flush the window style cache and actually go full-screen
628 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
629
630 wxSizeEvent event(wxSize(width, height), GetId());
631 GetEventHandler()->ProcessEvent(event);
632
633 return TRUE;
634 }
635 else
636 {
637 if (!IsFullScreen())
638 return FALSE;
639
640 m_fsIsShowing = FALSE;
641
1e6feb95 642#if wxUSE_TOOLBAR
a2327a9f
JS
643 wxToolBar *theToolBar = GetToolBar();
644
645 // restore the toolbar, menubar, and statusbar
646 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
647 {
648 theToolBar->SetSize(-1, m_fsToolBarHeight);
649 theToolBar->Show(TRUE);
650 }
1e6feb95 651#endif // wxUSE_TOOLBAR
a2327a9f 652
1e6feb95
VZ
653#if wxUSE_STATUSBAR
654 if ( m_fsStyle & wxFULLSCREEN_NOSTATUSBAR )
a2327a9f 655 {
579b10c2
JS
656 //CreateStatusBar(m_fsStatusBarFields);
657 if (GetStatusBar())
658 {
659 GetStatusBar()->Show(TRUE);
660 PositionStatusBar();
661 }
a2327a9f 662 }
1e6feb95 663#endif // wxUSE_STATUSBAR
a2327a9f 664
04ef50df 665#ifndef __WXMICROWIN__
a2327a9f
JS
666 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
667 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
04ef50df 668#endif
a2327a9f
JS
669
670 Maximize(m_fsIsMaximized);
671 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
672 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
673 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
674
675 return TRUE;
676 }
677}
678
2bda0e17
KB
679/*
680 * Frame window
681 *
682 */
683
1e6feb95 684bool wxFrameMSW::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow *wx_win, const wxChar *title,
debe6624 685 int x, int y, int width, int height, long style)
2bda0e17
KB
686
687{
688 m_defaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
689
690 // If child windows aren't properly drawn initially, WS_CLIPCHILDREN
691 // could be the culprit. But without it, you can get a lot of flicker.
692
2bda0e17 693 DWORD msflags = 0;
3ca6a5f0
BP
694 if ( style & wxCAPTION )
695 {
696 if ( style & wxFRAME_TOOL_WINDOW )
697 msflags |= WS_POPUPWINDOW;
698 else
699 msflags |= WS_OVERLAPPED;
700 }
2bda0e17 701 else
3ca6a5f0
BP
702 {
703 msflags |= WS_POPUP;
704 }
2bda0e17
KB
705
706 if (style & wxMINIMIZE_BOX)
707 msflags |= WS_MINIMIZEBOX;
708 if (style & wxMAXIMIZE_BOX)
709 msflags |= WS_MAXIMIZEBOX;
710 if (style & wxTHICK_FRAME)
711 msflags |= WS_THICKFRAME;
712 if (style & wxSYSTEM_MENU)
713 msflags |= WS_SYSMENU;
f6bcfd97 714 if ( style & wxMINIMIZE )
2bda0e17
KB
715 msflags |= WS_MINIMIZE;
716 if (style & wxMAXIMIZE)
717 msflags |= WS_MAXIMIZE;
718 if (style & wxCAPTION)
719 msflags |= WS_CAPTION;
1c089c47
JS
720 if (style & wxCLIP_CHILDREN)
721 msflags |= WS_CLIPCHILDREN;
2bda0e17 722
1e6feb95 723 // Keep this in wxFrameMSW because it saves recoding this function
2bda0e17 724 // in wxTinyFrame
8355a72f 725#if wxUSE_ITSY_BITSY && !defined(__WIN32__)
2bda0e17
KB
726 if (style & wxTINY_CAPTION_VERT)
727 msflags |= IBS_VERTCAPTION;
728 if (style & wxTINY_CAPTION_HORIZ)
729 msflags |= IBS_HORZCAPTION;
730#else
731 if (style & wxTINY_CAPTION_VERT)
732 msflags |= WS_CAPTION;
733 if (style & wxTINY_CAPTION_HORIZ)
734 msflags |= WS_CAPTION;
735#endif
736 if ((style & wxTHICK_FRAME) == 0)
737 msflags |= WS_BORDER;
738
739 WXDWORD extendedStyle = MakeExtendedStyle(style);
740
b0a6bb75 741 // make all frames appear in the win9x shell taskbar unless
b3daa5a3 742 // wxFRAME_TOOL_WINDOW or wxFRAME_NO_TASKBAR is given - without giving them
b0a6bb75 743 // WS_EX_APPWINDOW style, the child (i.e. owned) frames wouldn't appear in it
2432b92d 744#if !defined(__WIN16__) && !defined(__SC__)
4b9fc37a
GT
745 if ( (style & wxFRAME_TOOL_WINDOW) ||
746 (style & wxFRAME_NO_TASKBAR) )
b0a6bb75 747 extendedStyle |= WS_EX_TOOLWINDOW;
b3daa5a3 748 else if ( !(style & wxFRAME_NO_TASKBAR) )
b0a6bb75 749 extendedStyle |= WS_EX_APPWINDOW;
1e6d9499 750#endif
cd2df130 751
2bda0e17
KB
752 if (style & wxSTAY_ON_TOP)
753 extendedStyle |= WS_EX_TOPMOST;
754
4204da65 755#ifndef __WIN16__
b96340e6
JS
756 if (m_exStyle & wxFRAME_EX_CONTEXTHELP)
757 extendedStyle |= WS_EX_CONTEXTHELP;
4204da65 758#endif
b96340e6 759
2bda0e17 760 m_iconized = FALSE;
a23fd0e1
VZ
761 if ( !wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height,
762 msflags, NULL, extendedStyle) )
763 return FALSE;
764
2bda0e17
KB
765 // Seems to be necessary if we use WS_POPUP
766 // style instead of WS_OVERLAPPED
767 if (width > -1 && height > -1)
42e69d6b 768 ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
a23fd0e1
VZ
769
770 return TRUE;
2bda0e17
KB
771}
772
2bda0e17
KB
773// Default activation behaviour - set the focus for the first child
774// subwindow found.
1e6feb95 775void wxFrameMSW::OnActivate(wxActivateEvent& event)
2bda0e17 776{
f6bcfd97 777 if ( event.GetActive() )
00c4e897 778 {
f6bcfd97 779 // restore focus to the child which was last focused
1e6feb95 780 wxLogTrace(_T("focus"), _T("wxFrameMSW %08x activated."), m_hWnd);
00c4e897 781
e9456d8d
VZ
782 wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
783 : NULL;
784 if ( !parent )
785 {
786 parent = this;
787 }
788
789 wxSetFocusToChild(parent, &m_winLastFocused);
00c4e897 790 }
e9456d8d 791 else // deactivating
2bda0e17 792 {
e9456d8d 793 // remember the last focused child if it is our child
f6bcfd97 794 m_winLastFocused = FindFocus();
e9456d8d
VZ
795
796 // so we NULL it out if it's a child from some other frame
797 wxWindow *win = m_winLastFocused;
798 while ( win )
319fefa9 799 {
e9456d8d
VZ
800 if ( win->IsTopLevel() )
801 {
802 if ( win != this )
803 {
804 m_winLastFocused = NULL;
805 }
806
f6bcfd97 807 break;
e9456d8d 808 }
f6bcfd97 809
e9456d8d 810 win = win->GetParent();
319fefa9 811 }
f6bcfd97
BP
812
813 wxLogTrace(_T("focus"),
1e6feb95 814 _T("wxFrameMSW %08x deactivated, last focused: %08x."),
f6bcfd97
BP
815 m_hWnd,
816 m_winLastFocused ? GetHwndOf(m_winLastFocused)
817 : NULL);
818
819 event.Skip();
2bda0e17 820 }
2bda0e17
KB
821}
822
7c0ea335
VZ
823// ----------------------------------------------------------------------------
824// tool/status bar stuff
825// ----------------------------------------------------------------------------
826
d427503c 827#if wxUSE_TOOLBAR
7c0ea335 828
1e6feb95 829wxToolBar* wxFrameMSW::CreateToolBar(long style, wxWindowID id, const wxString& name)
81d66cf3 830{
7c0ea335 831 if ( wxFrameBase::CreateToolBar(style, id, name) )
81d66cf3 832 {
81d66cf3 833 PositionToolBar();
81d66cf3 834 }
81d66cf3 835
7c0ea335 836 return m_frameToolBar;
81d66cf3
JS
837}
838
1e6feb95 839void wxFrameMSW::PositionToolBar()
81d66cf3 840{
81d66cf3 841 RECT rect;
42e69d6b 842 ::GetClientRect(GetHwnd(), &rect);
81d66cf3 843
7c0ea335 844#if wxUSE_STATUSBAR
81d66cf3
JS
845 if ( GetStatusBar() )
846 {
7c0ea335
VZ
847 int statusX, statusY;
848 GetStatusBar()->GetClientSize(&statusX, &statusY);
849 rect.bottom -= statusY;
81d66cf3 850 }
7c0ea335 851#endif // wxUSE_STATUSBAR
81d66cf3 852
a2327a9f 853 if ( GetToolBar() && GetToolBar()->IsShown() )
81d66cf3
JS
854 {
855 int tw, th;
7c0ea335 856 GetToolBar()->GetSize(&tw, &th);
81d66cf3 857
7c0ea335 858 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
81d66cf3 859 {
7c0ea335 860 th = rect.bottom;
81d66cf3
JS
861 }
862 else
863 {
7c0ea335 864 tw = rect.right;
81d66cf3 865 }
7c0ea335
VZ
866
867 // Use the 'real' MSW position here
868 GetToolBar()->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
81d66cf3
JS
869 }
870}
d427503c 871#endif // wxUSE_TOOLBAR
d2aef312 872
7c0ea335
VZ
873// ----------------------------------------------------------------------------
874// frame state (iconized/maximized/...)
875// ----------------------------------------------------------------------------
876
a23fd0e1
VZ
877// propagate our state change to all child frames: this allows us to emulate X
878// Windows behaviour where child frames float independently of the parent one
879// on the desktop, but are iconized/restored with it
1e6feb95 880void wxFrameMSW::IconizeChildFrames(bool bIconize)
d2aef312 881{
a23fd0e1
VZ
882 for ( wxWindowList::Node *node = GetChildren().GetFirst();
883 node;
884 node = node->GetNext() )
885 {
886 wxWindow *win = node->GetData();
887
3ca6a5f0
BP
888 // iconizing the frames with this style under Win95 shell puts them at
889 // the bottom of the screen (as the MDI children) instead of making
890 // them appear in the taskbar because they are, by virtue of this
891 // style, not managed by the taskbar - instead leave Windows take care
892 // of them
893#ifdef __WIN95__
894 if ( win->GetWindowStyle() & wxFRAME_TOOL_WINDOW )
895 continue;
896#endif // Win95
897
3f7bc32b
VZ
898 // the child MDI frames are a special case and should not be touched by
899 // the parent frame - instead, they are managed by the user
b016a65b 900 wxFrameMSW *frame = wxDynamicCast(win, wxFrame);
1e6feb95
VZ
901 if ( frame
902#if wxUSE_MDI_ARCHITECTURE
903 && !wxDynamicCast(frame, wxMDIChildFrame)
904#endif // wxUSE_MDI_ARCHITECTURE
905 )
a23fd0e1 906 {
3f7bc32b 907 frame->Iconize(bIconize);
a23fd0e1 908 }
d2aef312 909 }
d2aef312
VZ
910}
911
a23fd0e1 912// ===========================================================================
42e69d6b 913// message processing
a23fd0e1
VZ
914// ===========================================================================
915
42e69d6b
VZ
916// ---------------------------------------------------------------------------
917// preprocessing
918// ---------------------------------------------------------------------------
919
1e6feb95 920bool wxFrameMSW::MSWTranslateMessage(WXMSG* pMsg)
42e69d6b
VZ
921{
922 if ( wxWindow::MSWTranslateMessage(pMsg) )
923 return TRUE;
924
1e6feb95 925#if wxUSE_MENUS && wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
42e69d6b
VZ
926 // try the menu bar accels
927 wxMenuBar *menuBar = GetMenuBar();
928 if ( !menuBar )
929 return FALSE;
930
931 const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
c50f1fb9 932 return acceleratorTable.Translate(this, pMsg);
1e6feb95
VZ
933#else
934 return FALSE;
935#endif // wxUSE_MENUS && wxUSE_ACCEL
42e69d6b
VZ
936}
937
938// ---------------------------------------------------------------------------
939// our private (non virtual) message handlers
940// ---------------------------------------------------------------------------
941
1e6feb95 942bool wxFrameMSW::HandlePaint()
42e69d6b
VZ
943{
944 RECT rect;
945 if ( GetUpdateRect(GetHwnd(), &rect, FALSE) )
946 {
04ef50df 947#ifndef __WXMICROWIN__
42e69d6b
VZ
948 if ( m_iconized )
949 {
c50f1fb9 950 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
42e69d6b
VZ
951 : (HICON)m_defaultIcon;
952
953 // Hold a pointer to the dc so long as the OnPaint() message
954 // is being processed
955 PAINTSTRUCT ps;
956 HDC hdc = ::BeginPaint(GetHwnd(), &ps);
957
958 // Erase background before painting or we get white background
959 MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L);
960
961 if ( hIcon )
962 {
963 RECT rect;
964 ::GetClientRect(GetHwnd(), &rect);
965
966 // FIXME: why hardcoded?
967 static const int icon_width = 32;
968 static const int icon_height = 32;
969
970 int icon_x = (int)((rect.right - icon_width)/2);
971 int icon_y = (int)((rect.bottom - icon_height)/2);
972
973 ::DrawIcon(hdc, icon_x, icon_y, hIcon);
974 }
975
976 ::EndPaint(GetHwnd(), &ps);
977
978 return TRUE;
979 }
980 else
04ef50df 981 #endif
42e69d6b 982 {
5d1d2d46 983 return wxWindow::HandlePaint();
42e69d6b
VZ
984 }
985 }
986 else
987 {
988 // nothing to paint - processed
989 return TRUE;
990 }
991}
992
1e6feb95 993bool wxFrameMSW::HandleSize(int x, int y, WXUINT id)
42e69d6b
VZ
994{
995 bool processed = FALSE;
04ef50df 996#ifndef __WXMICROWIN__
42e69d6b
VZ
997
998 switch ( id )
999 {
1000 case SIZENORMAL:
1001 // only do it it if we were iconized before, otherwise resizing the
1002 // parent frame has a curious side effect of bringing it under it's
1003 // children
1004 if ( !m_iconized )
1005 break;
1006
1007 // restore all child frames too
1008 IconizeChildFrames(FALSE);
1009
3dd9b88a
VZ
1010 (void)SendIconizeEvent(FALSE);
1011
42e69d6b
VZ
1012 // fall through
1013
1014 case SIZEFULLSCREEN:
1015 m_iconized = FALSE;
1016 break;
1017
1018 case SIZEICONIC:
1019 // iconize all child frames too
1020 IconizeChildFrames(TRUE);
1021
3dd9b88a
VZ
1022 (void)SendIconizeEvent();
1023
42e69d6b
VZ
1024 m_iconized = TRUE;
1025 break;
1026 }
04ef50df 1027#endif
42e69d6b
VZ
1028
1029 if ( !m_iconized )
1030 {
1e6feb95 1031#if wxUSE_STATUSBAR
42e69d6b 1032 PositionStatusBar();
1e6feb95
VZ
1033#endif // wxUSE_STATUSBAR
1034
1035#if wxUSE_TOOLBAR
42e69d6b 1036 PositionToolBar();
1e6feb95 1037#endif // wxUSE_TOOLBAR
42e69d6b
VZ
1038
1039 wxSizeEvent event(wxSize(x, y), m_windowId);
1040 event.SetEventObject( this );
1041 processed = GetEventHandler()->ProcessEvent(event);
1042 }
1043
1044 return processed;
1045}
1046
1e6feb95 1047bool wxFrameMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
42e69d6b
VZ
1048{
1049 if ( control )
1050 {
1051 // In case it's e.g. a toolbar.
1052 wxWindow *win = wxFindWinFromHandle(control);
1053 if ( win )
1054 return win->MSWCommand(cmd, id);
1055 }
1056
1057 // handle here commands from menus and accelerators
1058 if ( cmd == 0 || cmd == 1 )
1059 {
1e6feb95 1060#if wxUSE_MENUS_NATIVE
42e69d6b
VZ
1061 if ( wxCurrentPopupMenu )
1062 {
1063 wxMenu *popupMenu = wxCurrentPopupMenu;
1064 wxCurrentPopupMenu = NULL;
1065
1066 return popupMenu->MSWCommand(cmd, id);
1067 }
1e6feb95 1068#endif // wxUSE_MENUS_NATIVE
42e69d6b
VZ
1069
1070 if ( ProcessCommand(id) )
1071 {
1072 return TRUE;
1073 }
1074 }
1075
1076 return FALSE;
1077}
1078
1e6feb95 1079bool wxFrameMSW::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
a23fd0e1
VZ
1080{
1081 int item;
c219cecc 1082 if ( flags == 0xFFFF && hMenu == 0 )
a23fd0e1 1083 {
c219cecc 1084 // menu was removed from screen
a23fd0e1
VZ
1085 item = -1;
1086 }
04ef50df 1087#ifndef __WXMICROWIN__
c219cecc 1088 else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) )
a23fd0e1
VZ
1089 {
1090 item = nItem;
1091 }
04ef50df 1092#endif
a23fd0e1
VZ
1093 else
1094 {
1e6feb95 1095#if wxUSE_STATUSBAR
c219cecc 1096 // don't give hints for separators (doesn't make sense) nor for the
f6bcfd97
BP
1097 // items opening popup menus (they don't have them anyhow) but do clear
1098 // the status line - otherwise, we would be left with the help message
1099 // for the previous item which doesn't apply any more
1100 wxStatusBar *statbar = GetStatusBar();
1101 if ( statbar )
1102 {
1103 statbar->SetStatusText(wxEmptyString);
1104 }
1e6feb95 1105#endif // wxUSE_STATUSBAR
f6bcfd97 1106
a23fd0e1
VZ
1107 return FALSE;
1108 }
1109
1110 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
1111 event.SetEventObject( this );
1112
1113 return GetEventHandler()->ProcessEvent(event);
1114}
1115
1116// ---------------------------------------------------------------------------
1e6feb95 1117// the window proc for wxFrameMSW
a23fd0e1
VZ
1118// ---------------------------------------------------------------------------
1119
1e6feb95 1120long wxFrameMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
a23fd0e1
VZ
1121{
1122 long rc = 0;
1123 bool processed = FALSE;
1124
1125 switch ( message )
1126 {
42e69d6b
VZ
1127 case WM_CLOSE:
1128 // if we can't close, tell the system that we processed the
1129 // message - otherwise it would close us
1130 processed = !Close();
1131 break;
1132
1133 case WM_COMMAND:
1134 {
1135 WORD id, cmd;
1136 WXHWND hwnd;
1137 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
1138 &id, &hwnd, &cmd);
1139
1140 processed = HandleCommand(id, cmd, (WXHWND)hwnd);
1141 }
1142 break;
1143
04ef50df 1144#ifndef __WXMICROWIN__
a23fd0e1
VZ
1145 case WM_MENUSELECT:
1146 {
42e69d6b
VZ
1147 WXWORD item, flags;
1148 WXHMENU hmenu;
1149 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
1150
1151 processed = HandleMenuSelect(item, flags, hmenu);
a23fd0e1
VZ
1152 }
1153 break;
04ef50df 1154#endif
42e69d6b
VZ
1155
1156 case WM_PAINT:
1157 processed = HandlePaint();
1158 break;
1159
04ef50df 1160#ifndef __WXMICROWIN__
42e69d6b
VZ
1161 case WM_QUERYDRAGICON:
1162 {
c50f1fb9 1163 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
42e69d6b
VZ
1164 : (HICON)(m_defaultIcon);
1165 rc = (long)hIcon;
1166 processed = rc != 0;
1167 }
1168 break;
04ef50df 1169#endif
42e69d6b
VZ
1170
1171 case WM_SIZE:
1172 processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
1173 break;
a23fd0e1
VZ
1174 }
1175
1176 if ( !processed )
1177 rc = wxWindow::MSWWindowProc(message, wParam, lParam);
1178
1179 return rc;
1180}
21802234 1181