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