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