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