]> git.saurik.com Git - wxWidgets.git/blame - src/msw/frame.cpp
better learn the operators...
[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
c48926e1
VZ
350void wxFrameMSW::Raise()
351{
352#ifdef __WIN16__
353 // no SetForegroundWindow() in Win16
354 wxFrameBase::Raise();
355#else // Win32
356 ::SetForegroundWindow(GetHwnd());
357#endif // Win16/32
358}
359
1e6feb95 360void wxFrameMSW::Iconize(bool iconize)
2bda0e17 361{
7c0ea335 362 DoShowWindow(iconize ? SW_MINIMIZE : SW_RESTORE);
2bda0e17
KB
363}
364
1e6feb95 365void wxFrameMSW::Maximize(bool maximize)
2bda0e17 366{
bf505d28
VZ
367 if ( IsShown() )
368 {
369 // just maximize it directly
370 DoShowWindow(maximize ? SW_MAXIMIZE : SW_RESTORE);
371 }
372 else // hidden
373 {
374 // we can't maximize the hidden frame because it shows it as well, so
375 // just remember that we should do it later in this case
376 m_maximizeOnShow = TRUE;
377 }
7c0ea335
VZ
378}
379
1e6feb95 380void wxFrameMSW::Restore()
7c0ea335
VZ
381{
382 DoShowWindow(SW_RESTORE);
2bda0e17
KB
383}
384
1e6feb95 385bool wxFrameMSW::IsIconized() const
2bda0e17 386{
04ef50df
JS
387#ifdef __WXMICROWIN__
388 // TODO
389 return FALSE;
390#else
1e6feb95 391 ((wxFrameMSW *)this)->m_iconized = (::IsIconic(GetHwnd()) != 0);
2bda0e17 392 return m_iconized;
04ef50df 393#endif
2bda0e17
KB
394}
395
6f63ec3f 396// Is it maximized?
1e6feb95 397bool wxFrameMSW::IsMaximized() const
6f63ec3f 398{
04ef50df
JS
399#ifdef __WXMICROWIN__
400 // TODO
401 return FALSE;
402#else
7c0ea335 403 return (::IsZoomed(GetHwnd()) != 0);
04ef50df 404#endif
2bda0e17
KB
405}
406
1e6feb95 407void wxFrameMSW::SetIcon(const wxIcon& icon)
2bda0e17 408{
7c0ea335
VZ
409 wxFrameBase::SetIcon(icon);
410
04ef50df 411#if defined(__WIN95__) && !defined(__WXMICROWIN__)
7c0ea335
VZ
412 if ( m_icon.Ok() )
413 {
414 SendMessage(GetHwnd(), WM_SETICON,
415 (WPARAM)TRUE, (LPARAM)(HICON) m_icon.GetHICON());
416 }
417#endif // __WIN95__
2bda0e17
KB
418}
419
67bd5bad 420// generate an artificial resize event
3a12b404 421void wxFrameMSW::SendSizeEvent()
67bd5bad
GT
422{
423 RECT r;
424#ifdef __WIN16__
425 ::GetWindowRect(GetHwnd(), &r);
426#else
427 if ( !::GetWindowRect(GetHwnd(), &r) )
428 {
429 wxLogLastError(_T("GetWindowRect"));
430 }
431#endif
432
433 if ( !m_iconized )
434 {
435 (void)::PostMessage(GetHwnd(), WM_SIZE,
436 IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED,
437 MAKELPARAM(r.right - r.left, r.bottom - r.top));
438 }
439}
440
d427503c 441#if wxUSE_STATUSBAR
1e6feb95 442wxStatusBar *wxFrameMSW::OnCreateStatusBar(int number,
7c0ea335
VZ
443 long style,
444 wxWindowID id,
445 const wxString& name)
2bda0e17
KB
446{
447 wxStatusBar *statusBar = NULL;
448
47d67540 449#if wxUSE_NATIVE_STATUSBAR
1f0500b3 450 if ( !UsesNativeStatusBar() )
2bda0e17 451 {
1f0500b3 452 statusBar = (wxStatusBar *)new wxStatusBarGeneric(this, id, style);
2bda0e17
KB
453 }
454 else
455#endif
456 {
1f0500b3
VZ
457 statusBar = new wxStatusBar(this, id, style, name);
458 }
ed791986 459
1f0500b3
VZ
460 // Set the height according to the font and the border size
461 wxClientDC dc(statusBar);
462 dc.SetFont(statusBar->GetFont());
ed791986 463
1f0500b3
VZ
464 wxCoord y;
465 dc.GetTextExtent(_T("X"), NULL, &y );
ed791986 466
1f0500b3 467 int height = (int)( (11*y)/10 + 2*statusBar->GetBorderY());
ed791986 468
1f0500b3 469 statusBar->SetSize(-1, -1, -1, height);
ed791986 470
1f0500b3 471 statusBar->SetFieldsCount(number);
2bda0e17 472
7c0ea335 473 return statusBar;
2bda0e17
KB
474}
475
1e6feb95 476void wxFrameMSW::PositionStatusBar()
2bda0e17 477{
ed791986
VZ
478 if ( !m_frameStatusBar )
479 return;
480
cbc66a27
VZ
481 int w, h;
482 GetClientSize(&w, &h);
483 int sw, sh;
484 m_frameStatusBar->GetSize(&sw, &sh);
485
486 // Since we wish the status bar to be directly under the client area,
487 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
488 m_frameStatusBar->SetSize(0, h, w, sh);
2bda0e17 489}
d427503c 490#endif // wxUSE_STATUSBAR
2bda0e17 491
6522713c 492#if wxUSE_MENUS_NATIVE
ea9a4296 493
6522713c 494void wxFrameMSW::AttachMenuBar(wxMenuBar *menubar)
2bda0e17 495{
f008af16 496 wxFrameBase::AttachMenuBar(menubar);
6beb85c0 497
f6bcfd97 498 if ( !menubar )
c2dcfdef 499 {
f6bcfd97
BP
500 // actually remove the menu from the frame
501 m_hMenu = (WXHMENU)0;
502 InternalSetMenuBar();
065de612 503 }
f6bcfd97 504 else // set new non NULL menu bar
065de612 505 {
f6bcfd97 506 // Can set a menubar several times.
f6bcfd97
BP
507 if ( menubar->GetHMenu() )
508 {
509 m_hMenu = menubar->GetHMenu();
510 }
f008af16 511 else // no HMENU yet
f6bcfd97 512 {
f6bcfd97 513 m_hMenu = menubar->Create();
065de612 514
f6bcfd97 515 if ( !m_hMenu )
f008af16
VZ
516 {
517 wxFAIL_MSG( _T("failed to create menu bar") );
f6bcfd97 518 return;
f008af16 519 }
f6bcfd97 520 }
065de612 521
f6bcfd97 522 InternalSetMenuBar();
1e6feb95 523 }
2bda0e17
KB
524}
525
1e6feb95 526void wxFrameMSW::InternalSetMenuBar()
2bda0e17 527{
04ef50df 528#ifndef __WXMICROWIN__
42e69d6b 529 if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) )
2bda0e17 530 {
f6bcfd97 531 wxLogLastError(wxT("SetMenu"));
2bda0e17 532 }
04ef50df 533#endif
2bda0e17
KB
534}
535
1e6feb95
VZ
536#endif // wxUSE_MENUS_NATIVE
537
2bda0e17 538// Responds to colour changes, and passes event on to children.
1e6feb95 539void wxFrameMSW::OnSysColourChanged(wxSysColourChangedEvent& event)
2bda0e17
KB
540{
541 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
542 Refresh();
543
1e6feb95 544#if wxUSE_STATUSBAR
2bda0e17
KB
545 if ( m_frameStatusBar )
546 {
547 wxSysColourChangedEvent event2;
548 event2.SetEventObject( m_frameStatusBar );
02800301 549 m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
2bda0e17 550 }
1e6feb95 551#endif // wxUSE_STATUSBAR
2bda0e17
KB
552
553 // Propagate the event to the non-top-level children
554 wxWindow::OnSysColourChanged(event);
555}
556
a2327a9f 557// Pass TRUE to show full screen, FALSE to restore.
1e6feb95 558bool wxFrameMSW::ShowFullScreen(bool show, long style)
a2327a9f
JS
559{
560 if (show)
561 {
562 if (IsFullScreen())
563 return FALSE;
564
565 m_fsIsShowing = TRUE;
566 m_fsStyle = style;
567
1e6feb95 568#if wxUSE_TOOLBAR
f6bcfd97 569 wxToolBar *theToolBar = GetToolBar();
a2327a9f 570 if (theToolBar)
1e6feb95 571 theToolBar->GetSize(NULL, &m_fsToolBarHeight);
a2327a9f
JS
572
573 // zap the toolbar, menubar, and statusbar
574
575 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
576 {
577 theToolBar->SetSize(-1,0);
578 theToolBar->Show(FALSE);
579 }
1e6feb95 580#endif // wxUSE_TOOLBAR
a2327a9f 581
04ef50df 582#ifndef __WXMICROWIN__
a2327a9f
JS
583 if (style & wxFULLSCREEN_NOMENUBAR)
584 SetMenu((HWND)GetHWND(), (HMENU) NULL);
04ef50df 585#endif
a2327a9f 586
1e6feb95
VZ
587#if wxUSE_STATUSBAR
588 wxStatusBar *theStatusBar = GetStatusBar();
589 if (theStatusBar)
590 theStatusBar->GetSize(NULL, &m_fsStatusBarHeight);
591
a2327a9f
JS
592 // Save the number of fields in the statusbar
593 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
594 {
579b10c2
JS
595 //m_fsStatusBarFields = theStatusBar->GetFieldsCount();
596 //SetStatusBar((wxStatusBar*) NULL);
597 //delete theStatusBar;
598 theStatusBar->Show(FALSE);
a2327a9f
JS
599 }
600 else
601 m_fsStatusBarFields = 0;
1e6feb95 602#endif // wxUSE_STATUSBAR
a2327a9f
JS
603
604 // zap the frame borders
605
606 // save the 'normal' window style
607 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
608
f6bcfd97 609 // save the old position, width & height, maximize state
a2327a9f 610 m_fsOldSize = GetRect();
f6bcfd97 611 m_fsIsMaximized = IsMaximized();
a2327a9f 612
f6bcfd97 613 // decide which window style flags to turn off
a2327a9f
JS
614 LONG newStyle = m_fsOldWindowStyle;
615 LONG offFlags = 0;
616
617 if (style & wxFULLSCREEN_NOBORDER)
7900c71c 618 offFlags |= WS_BORDER | WS_THICKFRAME;
a2327a9f
JS
619 if (style & wxFULLSCREEN_NOCAPTION)
620 offFlags |= (WS_CAPTION | WS_SYSMENU);
621
622 newStyle &= (~offFlags);
623
624 // change our window style to be compatible with full-screen mode
625 SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
626
627 // resize to the size of the desktop
628 int width, height;
629
630 RECT rect;
631 ::GetWindowRect(GetDesktopWindow(), &rect);
632 width = rect.right - rect.left;
633 height = rect.bottom - rect.top;
634
635 SetSize(width, height);
636
637 // now flush the window style cache and actually go full-screen
638 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
639
640 wxSizeEvent event(wxSize(width, height), GetId());
641 GetEventHandler()->ProcessEvent(event);
642
643 return TRUE;
644 }
645 else
646 {
647 if (!IsFullScreen())
648 return FALSE;
649
650 m_fsIsShowing = FALSE;
651
1e6feb95 652#if wxUSE_TOOLBAR
a2327a9f
JS
653 wxToolBar *theToolBar = GetToolBar();
654
655 // restore the toolbar, menubar, and statusbar
656 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
657 {
658 theToolBar->SetSize(-1, m_fsToolBarHeight);
659 theToolBar->Show(TRUE);
660 }
1e6feb95 661#endif // wxUSE_TOOLBAR
a2327a9f 662
1e6feb95
VZ
663#if wxUSE_STATUSBAR
664 if ( m_fsStyle & wxFULLSCREEN_NOSTATUSBAR )
a2327a9f 665 {
579b10c2
JS
666 //CreateStatusBar(m_fsStatusBarFields);
667 if (GetStatusBar())
668 {
669 GetStatusBar()->Show(TRUE);
670 PositionStatusBar();
671 }
a2327a9f 672 }
1e6feb95 673#endif // wxUSE_STATUSBAR
a2327a9f 674
04ef50df 675#ifndef __WXMICROWIN__
a2327a9f
JS
676 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
677 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
04ef50df 678#endif
a2327a9f
JS
679
680 Maximize(m_fsIsMaximized);
681 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
682 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
683 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
684
685 return TRUE;
686 }
687}
688
2bda0e17
KB
689/*
690 * Frame window
691 *
692 */
693
1e6feb95 694bool wxFrameMSW::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow *wx_win, const wxChar *title,
debe6624 695 int x, int y, int width, int height, long style)
2bda0e17
KB
696
697{
698 m_defaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
699
700 // If child windows aren't properly drawn initially, WS_CLIPCHILDREN
701 // could be the culprit. But without it, you can get a lot of flicker.
702
2bda0e17 703 DWORD msflags = 0;
3ca6a5f0
BP
704 if ( style & wxCAPTION )
705 {
706 if ( style & wxFRAME_TOOL_WINDOW )
707 msflags |= WS_POPUPWINDOW;
708 else
709 msflags |= WS_OVERLAPPED;
710 }
2bda0e17 711 else
3ca6a5f0
BP
712 {
713 msflags |= WS_POPUP;
714 }
2bda0e17
KB
715
716 if (style & wxMINIMIZE_BOX)
717 msflags |= WS_MINIMIZEBOX;
718 if (style & wxMAXIMIZE_BOX)
719 msflags |= WS_MAXIMIZEBOX;
720 if (style & wxTHICK_FRAME)
721 msflags |= WS_THICKFRAME;
722 if (style & wxSYSTEM_MENU)
723 msflags |= WS_SYSMENU;
f6bcfd97 724 if ( style & wxMINIMIZE )
2bda0e17
KB
725 msflags |= WS_MINIMIZE;
726 if (style & wxMAXIMIZE)
727 msflags |= WS_MAXIMIZE;
728 if (style & wxCAPTION)
729 msflags |= WS_CAPTION;
1c089c47
JS
730 if (style & wxCLIP_CHILDREN)
731 msflags |= WS_CLIPCHILDREN;
2bda0e17 732
1e6feb95 733 // Keep this in wxFrameMSW because it saves recoding this function
2bda0e17 734 // in wxTinyFrame
8355a72f 735#if wxUSE_ITSY_BITSY && !defined(__WIN32__)
2bda0e17
KB
736 if (style & wxTINY_CAPTION_VERT)
737 msflags |= IBS_VERTCAPTION;
738 if (style & wxTINY_CAPTION_HORIZ)
739 msflags |= IBS_HORZCAPTION;
740#else
741 if (style & wxTINY_CAPTION_VERT)
742 msflags |= WS_CAPTION;
743 if (style & wxTINY_CAPTION_HORIZ)
744 msflags |= WS_CAPTION;
745#endif
746 if ((style & wxTHICK_FRAME) == 0)
747 msflags |= WS_BORDER;
748
749 WXDWORD extendedStyle = MakeExtendedStyle(style);
750
b0a6bb75 751 // make all frames appear in the win9x shell taskbar unless
b3daa5a3 752 // wxFRAME_TOOL_WINDOW or wxFRAME_NO_TASKBAR is given - without giving them
b0a6bb75 753 // WS_EX_APPWINDOW style, the child (i.e. owned) frames wouldn't appear in it
2432b92d 754#if !defined(__WIN16__) && !defined(__SC__)
4b9fc37a
GT
755 if ( (style & wxFRAME_TOOL_WINDOW) ||
756 (style & wxFRAME_NO_TASKBAR) )
b0a6bb75 757 extendedStyle |= WS_EX_TOOLWINDOW;
b3daa5a3 758 else if ( !(style & wxFRAME_NO_TASKBAR) )
b0a6bb75 759 extendedStyle |= WS_EX_APPWINDOW;
1e6d9499 760#endif
cd2df130 761
2bda0e17
KB
762 if (style & wxSTAY_ON_TOP)
763 extendedStyle |= WS_EX_TOPMOST;
764
4204da65 765#ifndef __WIN16__
b96340e6
JS
766 if (m_exStyle & wxFRAME_EX_CONTEXTHELP)
767 extendedStyle |= WS_EX_CONTEXTHELP;
4204da65 768#endif
b96340e6 769
2bda0e17 770 m_iconized = FALSE;
a23fd0e1
VZ
771 if ( !wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height,
772 msflags, NULL, extendedStyle) )
773 return FALSE;
774
2bda0e17
KB
775 // Seems to be necessary if we use WS_POPUP
776 // style instead of WS_OVERLAPPED
777 if (width > -1 && height > -1)
42e69d6b 778 ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
a23fd0e1
VZ
779
780 return TRUE;
2bda0e17
KB
781}
782
2bda0e17
KB
783// Default activation behaviour - set the focus for the first child
784// subwindow found.
1e6feb95 785void wxFrameMSW::OnActivate(wxActivateEvent& event)
2bda0e17 786{
f6bcfd97 787 if ( event.GetActive() )
00c4e897 788 {
f6bcfd97 789 // restore focus to the child which was last focused
1e6feb95 790 wxLogTrace(_T("focus"), _T("wxFrameMSW %08x activated."), m_hWnd);
00c4e897 791
e9456d8d
VZ
792 wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
793 : NULL;
794 if ( !parent )
795 {
796 parent = this;
797 }
798
799 wxSetFocusToChild(parent, &m_winLastFocused);
00c4e897 800 }
e9456d8d 801 else // deactivating
2bda0e17 802 {
e9456d8d 803 // remember the last focused child if it is our child
f6bcfd97 804 m_winLastFocused = FindFocus();
e9456d8d
VZ
805
806 // so we NULL it out if it's a child from some other frame
807 wxWindow *win = m_winLastFocused;
808 while ( win )
319fefa9 809 {
e9456d8d
VZ
810 if ( win->IsTopLevel() )
811 {
812 if ( win != this )
813 {
814 m_winLastFocused = NULL;
815 }
816
f6bcfd97 817 break;
e9456d8d 818 }
f6bcfd97 819
e9456d8d 820 win = win->GetParent();
319fefa9 821 }
f6bcfd97
BP
822
823 wxLogTrace(_T("focus"),
1e6feb95 824 _T("wxFrameMSW %08x deactivated, last focused: %08x."),
f6bcfd97
BP
825 m_hWnd,
826 m_winLastFocused ? GetHwndOf(m_winLastFocused)
827 : NULL);
828
829 event.Skip();
2bda0e17 830 }
2bda0e17
KB
831}
832
7c0ea335
VZ
833// ----------------------------------------------------------------------------
834// tool/status bar stuff
835// ----------------------------------------------------------------------------
836
d427503c 837#if wxUSE_TOOLBAR
7c0ea335 838
1e6feb95 839wxToolBar* wxFrameMSW::CreateToolBar(long style, wxWindowID id, const wxString& name)
81d66cf3 840{
7c0ea335 841 if ( wxFrameBase::CreateToolBar(style, id, name) )
81d66cf3 842 {
81d66cf3 843 PositionToolBar();
81d66cf3 844 }
81d66cf3 845
7c0ea335 846 return m_frameToolBar;
81d66cf3
JS
847}
848
1e6feb95 849void wxFrameMSW::PositionToolBar()
81d66cf3 850{
81d66cf3 851 RECT rect;
42e69d6b 852 ::GetClientRect(GetHwnd(), &rect);
81d66cf3 853
7c0ea335 854#if wxUSE_STATUSBAR
81d66cf3
JS
855 if ( GetStatusBar() )
856 {
7c0ea335
VZ
857 int statusX, statusY;
858 GetStatusBar()->GetClientSize(&statusX, &statusY);
859 rect.bottom -= statusY;
81d66cf3 860 }
7c0ea335 861#endif // wxUSE_STATUSBAR
81d66cf3 862
a2327a9f 863 if ( GetToolBar() && GetToolBar()->IsShown() )
81d66cf3
JS
864 {
865 int tw, th;
7c0ea335 866 GetToolBar()->GetSize(&tw, &th);
81d66cf3 867
7c0ea335 868 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
81d66cf3 869 {
7c0ea335 870 th = rect.bottom;
81d66cf3
JS
871 }
872 else
873 {
7c0ea335 874 tw = rect.right;
81d66cf3 875 }
7c0ea335
VZ
876
877 // Use the 'real' MSW position here
878 GetToolBar()->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
81d66cf3
JS
879 }
880}
d427503c 881#endif // wxUSE_TOOLBAR
d2aef312 882
7c0ea335
VZ
883// ----------------------------------------------------------------------------
884// frame state (iconized/maximized/...)
885// ----------------------------------------------------------------------------
886
a23fd0e1
VZ
887// propagate our state change to all child frames: this allows us to emulate X
888// Windows behaviour where child frames float independently of the parent one
889// on the desktop, but are iconized/restored with it
1e6feb95 890void wxFrameMSW::IconizeChildFrames(bool bIconize)
d2aef312 891{
a23fd0e1
VZ
892 for ( wxWindowList::Node *node = GetChildren().GetFirst();
893 node;
894 node = node->GetNext() )
895 {
896 wxWindow *win = node->GetData();
897
3ca6a5f0
BP
898 // iconizing the frames with this style under Win95 shell puts them at
899 // the bottom of the screen (as the MDI children) instead of making
900 // them appear in the taskbar because they are, by virtue of this
901 // style, not managed by the taskbar - instead leave Windows take care
902 // of them
903#ifdef __WIN95__
904 if ( win->GetWindowStyle() & wxFRAME_TOOL_WINDOW )
905 continue;
906#endif // Win95
907
3f7bc32b
VZ
908 // the child MDI frames are a special case and should not be touched by
909 // the parent frame - instead, they are managed by the user
b016a65b 910 wxFrameMSW *frame = wxDynamicCast(win, wxFrame);
1e6feb95
VZ
911 if ( frame
912#if wxUSE_MDI_ARCHITECTURE
913 && !wxDynamicCast(frame, wxMDIChildFrame)
914#endif // wxUSE_MDI_ARCHITECTURE
915 )
a23fd0e1 916 {
3f7bc32b 917 frame->Iconize(bIconize);
a23fd0e1 918 }
d2aef312 919 }
d2aef312
VZ
920}
921
a23fd0e1 922// ===========================================================================
42e69d6b 923// message processing
a23fd0e1
VZ
924// ===========================================================================
925
42e69d6b
VZ
926// ---------------------------------------------------------------------------
927// preprocessing
928// ---------------------------------------------------------------------------
929
1e6feb95 930bool wxFrameMSW::MSWTranslateMessage(WXMSG* pMsg)
42e69d6b
VZ
931{
932 if ( wxWindow::MSWTranslateMessage(pMsg) )
933 return TRUE;
934
1e6feb95 935#if wxUSE_MENUS && wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
42e69d6b
VZ
936 // try the menu bar accels
937 wxMenuBar *menuBar = GetMenuBar();
938 if ( !menuBar )
939 return FALSE;
940
941 const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
c50f1fb9 942 return acceleratorTable.Translate(this, pMsg);
1e6feb95
VZ
943#else
944 return FALSE;
945#endif // wxUSE_MENUS && wxUSE_ACCEL
42e69d6b
VZ
946}
947
948// ---------------------------------------------------------------------------
949// our private (non virtual) message handlers
950// ---------------------------------------------------------------------------
951
1e6feb95 952bool wxFrameMSW::HandlePaint()
42e69d6b
VZ
953{
954 RECT rect;
955 if ( GetUpdateRect(GetHwnd(), &rect, FALSE) )
956 {
04ef50df 957#ifndef __WXMICROWIN__
42e69d6b
VZ
958 if ( m_iconized )
959 {
c50f1fb9 960 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
42e69d6b
VZ
961 : (HICON)m_defaultIcon;
962
963 // Hold a pointer to the dc so long as the OnPaint() message
964 // is being processed
965 PAINTSTRUCT ps;
966 HDC hdc = ::BeginPaint(GetHwnd(), &ps);
967
968 // Erase background before painting or we get white background
969 MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L);
970
971 if ( hIcon )
972 {
973 RECT rect;
974 ::GetClientRect(GetHwnd(), &rect);
975
976 // FIXME: why hardcoded?
977 static const int icon_width = 32;
978 static const int icon_height = 32;
979
980 int icon_x = (int)((rect.right - icon_width)/2);
981 int icon_y = (int)((rect.bottom - icon_height)/2);
982
983 ::DrawIcon(hdc, icon_x, icon_y, hIcon);
984 }
985
986 ::EndPaint(GetHwnd(), &ps);
987
988 return TRUE;
989 }
990 else
04ef50df 991 #endif
42e69d6b 992 {
5d1d2d46 993 return wxWindow::HandlePaint();
42e69d6b
VZ
994 }
995 }
996 else
997 {
998 // nothing to paint - processed
999 return TRUE;
1000 }
1001}
1002
1e6feb95 1003bool wxFrameMSW::HandleSize(int x, int y, WXUINT id)
42e69d6b
VZ
1004{
1005 bool processed = FALSE;
04ef50df 1006#ifndef __WXMICROWIN__
42e69d6b
VZ
1007
1008 switch ( id )
1009 {
1010 case SIZENORMAL:
1011 // only do it it if we were iconized before, otherwise resizing the
1012 // parent frame has a curious side effect of bringing it under it's
1013 // children
1014 if ( !m_iconized )
1015 break;
1016
1017 // restore all child frames too
1018 IconizeChildFrames(FALSE);
1019
3dd9b88a
VZ
1020 (void)SendIconizeEvent(FALSE);
1021
42e69d6b
VZ
1022 // fall through
1023
1024 case SIZEFULLSCREEN:
1025 m_iconized = FALSE;
1026 break;
1027
1028 case SIZEICONIC:
1029 // iconize all child frames too
1030 IconizeChildFrames(TRUE);
1031
3dd9b88a
VZ
1032 (void)SendIconizeEvent();
1033
42e69d6b
VZ
1034 m_iconized = TRUE;
1035 break;
1036 }
04ef50df 1037#endif
42e69d6b
VZ
1038
1039 if ( !m_iconized )
1040 {
1e6feb95 1041#if wxUSE_STATUSBAR
42e69d6b 1042 PositionStatusBar();
1e6feb95
VZ
1043#endif // wxUSE_STATUSBAR
1044
1045#if wxUSE_TOOLBAR
42e69d6b 1046 PositionToolBar();
1e6feb95 1047#endif // wxUSE_TOOLBAR
42e69d6b
VZ
1048
1049 wxSizeEvent event(wxSize(x, y), m_windowId);
1050 event.SetEventObject( this );
1051 processed = GetEventHandler()->ProcessEvent(event);
1052 }
1053
1054 return processed;
1055}
1056
1e6feb95 1057bool wxFrameMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
42e69d6b
VZ
1058{
1059 if ( control )
1060 {
1061 // In case it's e.g. a toolbar.
1062 wxWindow *win = wxFindWinFromHandle(control);
1063 if ( win )
1064 return win->MSWCommand(cmd, id);
1065 }
1066
1067 // handle here commands from menus and accelerators
1068 if ( cmd == 0 || cmd == 1 )
1069 {
1e6feb95 1070#if wxUSE_MENUS_NATIVE
42e69d6b
VZ
1071 if ( wxCurrentPopupMenu )
1072 {
1073 wxMenu *popupMenu = wxCurrentPopupMenu;
1074 wxCurrentPopupMenu = NULL;
1075
1076 return popupMenu->MSWCommand(cmd, id);
1077 }
1e6feb95 1078#endif // wxUSE_MENUS_NATIVE
42e69d6b
VZ
1079
1080 if ( ProcessCommand(id) )
1081 {
1082 return TRUE;
1083 }
1084 }
1085
1086 return FALSE;
1087}
1088
1e6feb95 1089bool wxFrameMSW::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
a23fd0e1
VZ
1090{
1091 int item;
c219cecc 1092 if ( flags == 0xFFFF && hMenu == 0 )
a23fd0e1 1093 {
c219cecc 1094 // menu was removed from screen
a23fd0e1
VZ
1095 item = -1;
1096 }
04ef50df 1097#ifndef __WXMICROWIN__
c219cecc 1098 else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) )
a23fd0e1
VZ
1099 {
1100 item = nItem;
1101 }
04ef50df 1102#endif
a23fd0e1
VZ
1103 else
1104 {
1e6feb95 1105#if wxUSE_STATUSBAR
c219cecc 1106 // don't give hints for separators (doesn't make sense) nor for the
f6bcfd97
BP
1107 // items opening popup menus (they don't have them anyhow) but do clear
1108 // the status line - otherwise, we would be left with the help message
1109 // for the previous item which doesn't apply any more
1110 wxStatusBar *statbar = GetStatusBar();
1111 if ( statbar )
1112 {
1113 statbar->SetStatusText(wxEmptyString);
1114 }
1e6feb95 1115#endif // wxUSE_STATUSBAR
f6bcfd97 1116
a23fd0e1
VZ
1117 return FALSE;
1118 }
1119
1120 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
1121 event.SetEventObject( this );
1122
1123 return GetEventHandler()->ProcessEvent(event);
1124}
1125
1126// ---------------------------------------------------------------------------
1e6feb95 1127// the window proc for wxFrameMSW
a23fd0e1
VZ
1128// ---------------------------------------------------------------------------
1129
1e6feb95 1130long wxFrameMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
a23fd0e1
VZ
1131{
1132 long rc = 0;
1133 bool processed = FALSE;
1134
1135 switch ( message )
1136 {
42e69d6b
VZ
1137 case WM_CLOSE:
1138 // if we can't close, tell the system that we processed the
1139 // message - otherwise it would close us
1140 processed = !Close();
1141 break;
1142
1143 case WM_COMMAND:
1144 {
1145 WORD id, cmd;
1146 WXHWND hwnd;
1147 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
1148 &id, &hwnd, &cmd);
1149
1150 processed = HandleCommand(id, cmd, (WXHWND)hwnd);
1151 }
1152 break;
1153
04ef50df 1154#ifndef __WXMICROWIN__
a23fd0e1
VZ
1155 case WM_MENUSELECT:
1156 {
42e69d6b
VZ
1157 WXWORD item, flags;
1158 WXHMENU hmenu;
1159 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
1160
1161 processed = HandleMenuSelect(item, flags, hmenu);
a23fd0e1
VZ
1162 }
1163 break;
04ef50df 1164#endif
42e69d6b
VZ
1165
1166 case WM_PAINT:
1167 processed = HandlePaint();
1168 break;
1169
04ef50df 1170#ifndef __WXMICROWIN__
42e69d6b
VZ
1171 case WM_QUERYDRAGICON:
1172 {
c50f1fb9 1173 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
42e69d6b
VZ
1174 : (HICON)(m_defaultIcon);
1175 rc = (long)hIcon;
1176 processed = rc != 0;
1177 }
1178 break;
04ef50df 1179#endif
42e69d6b
VZ
1180
1181 case WM_SIZE:
1182 processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
1183 break;
a23fd0e1
VZ
1184 }
1185
1186 if ( !processed )
1187 rc = wxWindow::MSWWindowProc(message, wParam, lParam);
1188
1189 return rc;
1190}
21802234 1191