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