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