]> git.saurik.com Git - wxWidgets.git/blob - src/msw/frame.cpp
fixed wxBase and GUI separation for sockets code
[wxWidgets.git] / src / msw / frame.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/frame.cpp
3 // Purpose: wxFrame
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
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 #ifdef __WXWINCE__
46 #include <commctrl.h>
47 #endif
48
49 #if wxUSE_STATUSBAR
50 #include "wx/statusbr.h"
51 #include "wx/generic/statusbr.h"
52 #endif // wxUSE_STATUSBAR
53
54 #if wxUSE_TOOLBAR
55 #include "wx/toolbar.h"
56 #endif // wxUSE_TOOLBAR
57
58 #include "wx/menuitem.h"
59 #include "wx/log.h"
60
61 #ifdef __WXUNIVERSAL__
62 #include "wx/univ/theme.h"
63 #include "wx/univ/colschem.h"
64 #endif // __WXUNIVERSAL__
65
66 // ----------------------------------------------------------------------------
67 // globals
68 // ----------------------------------------------------------------------------
69
70 #if wxUSE_MENUS_NATIVE
71 extern wxMenu *wxCurrentPopupMenu;
72 #endif // wxUSE_MENUS_NATIVE
73
74 // ----------------------------------------------------------------------------
75 // event tables
76 // ----------------------------------------------------------------------------
77
78 BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
79 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
80 END_EVENT_TABLE()
81
82 #if wxUSE_EXTENDED_RTTI
83 IMPLEMENT_DYNAMIC_CLASS_XTI(wxFrame, wxTopLevelWindow,"wx/frame.h")
84
85 WX_BEGIN_PROPERTIES_TABLE(wxFrame)
86 /*
87 TODO PROPERTIES
88
89 style (wxDEFAULT_FRAME_STYLE)
90 centered (bool, false )
91 */
92 WX_END_PROPERTIES_TABLE()
93
94 WX_BEGIN_HANDLERS_TABLE(wxFrame)
95 WX_END_HANDLERS_TABLE()
96
97 WX_CONSTRUCTOR_5( wxFrame , wxWindow* , Parent , wxWindowID , Id , wxString , Title , wxPoint , Position , wxSize , Size )
98
99 #else
100 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
101 #endif
102
103 // ============================================================================
104 // implementation
105 // ============================================================================
106
107 // ----------------------------------------------------------------------------
108 // static class members
109 // ----------------------------------------------------------------------------
110
111 #if wxUSE_STATUSBAR
112 #if wxUSE_NATIVE_STATUSBAR
113 bool wxFrame::m_useNativeStatusBar = TRUE;
114 #else
115 bool wxFrame::m_useNativeStatusBar = FALSE;
116 #endif
117 #endif // wxUSE_NATIVE_STATUSBAR
118
119 // ----------------------------------------------------------------------------
120 // creation/destruction
121 // ----------------------------------------------------------------------------
122
123 void wxFrame::Init()
124 {
125 #if wxUSE_TOOLTIPS
126 m_hwndToolTip = 0;
127 #endif
128
129 // Data to save/restore when calling ShowFullScreen
130 m_fsStatusBarFields = 0;
131 m_fsStatusBarHeight = 0;
132 m_fsToolBarHeight = 0;
133
134 m_wasMinimized = FALSE;
135 }
136
137 bool wxFrame::Create(wxWindow *parent,
138 wxWindowID id,
139 const wxString& title,
140 const wxPoint& pos,
141 const wxSize& size,
142 long style,
143 const wxString& name)
144 {
145 if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) )
146 return FALSE;
147
148 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
149
150 wxModelessWindows.Append(this);
151
152 return TRUE;
153 }
154
155 wxFrame::~wxFrame()
156 {
157 m_isBeingDeleted = TRUE;
158 DeleteAllBars();
159 }
160
161 // ----------------------------------------------------------------------------
162 // wxFrame client size calculations
163 // ----------------------------------------------------------------------------
164
165 void wxFrame::DoSetClientSize(int width, int height)
166 {
167 // leave enough space for the status bar if we have (and show) it
168 #if wxUSE_STATUSBAR
169 wxStatusBar *statbar = GetStatusBar();
170 if ( statbar && statbar->IsShown() )
171 {
172 height += statbar->GetSize().y;
173 }
174 #endif // wxUSE_STATUSBAR
175
176 // call GetClientAreaOrigin() to take the toolbar into account
177 wxPoint pt = GetClientAreaOrigin();
178 width += pt.x;
179 height += pt.y;
180
181 wxTopLevelWindow::DoSetClientSize(width, height);
182 }
183
184 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
185 void wxFrame::DoGetClientSize(int *x, int *y) const
186 {
187 wxTopLevelWindow::DoGetClientSize(x, y);
188
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
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
210 // ----------------------------------------------------------------------------
211 // wxFrame: various geometry-related functions
212 // ----------------------------------------------------------------------------
213
214 void wxFrame::Raise()
215 {
216 ::SetForegroundWindow(GetHwnd());
217 }
218
219 // generate an artificial resize event
220 void wxFrame::SendSizeEvent()
221 {
222 if ( !m_iconized )
223 {
224 RECT r = wxGetWindowRect(GetHwnd());
225
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
232 #if wxUSE_STATUSBAR
233 wxStatusBar *wxFrame::OnCreateStatusBar(int number,
234 long style,
235 wxWindowID id,
236 const wxString& name)
237 {
238 wxStatusBar *statusBar = NULL;
239
240 #if wxUSE_NATIVE_STATUSBAR
241 if ( !UsesNativeStatusBar() )
242 {
243 statusBar = (wxStatusBar *)new wxStatusBarGeneric(this, id, style);
244 }
245 else
246 #endif
247 {
248 statusBar = new wxStatusBar(this, id, style, name);
249 }
250
251 statusBar->SetFieldsCount(number);
252
253 return statusBar;
254 }
255
256 void wxFrame::PositionStatusBar()
257 {
258 if ( !m_frameStatusBar || !m_frameStatusBar->IsShown() )
259 return;
260
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);
269 }
270 #endif // wxUSE_STATUSBAR
271
272 #if wxUSE_MENUS_NATIVE
273
274 void wxFrame::AttachMenuBar(wxMenuBar *menubar)
275 {
276 wxFrameBase::AttachMenuBar(menubar);
277
278 if ( !menubar )
279 {
280 // actually remove the menu from the frame
281 m_hMenu = (WXHMENU)0;
282 InternalSetMenuBar();
283 }
284 else // set new non NULL menu bar
285 {
286 #ifndef __WXWINCE__
287 // Can set a menubar several times.
288 if ( menubar->GetHMenu() )
289 {
290 m_hMenu = menubar->GetHMenu();
291 }
292 else // no HMENU yet
293 {
294 m_hMenu = menubar->Create();
295
296 if ( !m_hMenu )
297 {
298 wxFAIL_MSG( _T("failed to create menu bar") );
299 return;
300 }
301 }
302 #endif
303 InternalSetMenuBar();
304 }
305 }
306
307 void wxFrame::InternalSetMenuBar()
308 {
309 #ifdef __WXMICROWIN__
310 // Nothing
311 #elif defined(__WXWINCE__)
312
313 if (!GetToolBar())
314 {
315 wxToolBar* toolBar = new wxToolBar(this, -1,
316 wxDefaultPosition, wxDefaultSize,
317 wxBORDER_NONE | wxTB_HORIZONTAL,
318 wxToolBarNameStr, GetMenuBar());
319 SetToolBar(toolBar);
320 }
321 #else
322 if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) )
323 {
324 wxLogLastError(wxT("SetMenu"));
325 }
326 #endif
327 }
328
329 #endif // wxUSE_MENUS_NATIVE
330
331 // Responds to colour changes, and passes event on to children.
332 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
333 {
334 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
335 Refresh();
336
337 #if wxUSE_STATUSBAR
338 if ( m_frameStatusBar )
339 {
340 wxSysColourChangedEvent event2;
341 event2.SetEventObject( m_frameStatusBar );
342 m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
343 }
344 #endif // wxUSE_STATUSBAR
345
346 // Propagate the event to the non-top-level children
347 wxWindow::OnSysColourChanged(event);
348 }
349
350 // Pass TRUE to show full screen, FALSE to restore.
351 bool wxFrame::ShowFullScreen(bool show, long style)
352 {
353 if ( IsFullScreen() == show )
354 return FALSE;
355
356 if (show)
357 {
358 #if wxUSE_TOOLBAR
359 #ifdef __WXWINCE__
360 // TODO: hide commandbar
361 #else
362 wxToolBar *theToolBar = GetToolBar();
363 if (theToolBar)
364 theToolBar->GetSize(NULL, &m_fsToolBarHeight);
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 }
373 #endif // __WXWINCE__
374 #endif // wxUSE_TOOLBAR
375
376 // TODO: make it work for WinCE
377 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
378 if (style & wxFULLSCREEN_NOMENUBAR)
379 SetMenu((HWND)GetHWND(), (HMENU) NULL);
380 #endif
381
382 #if wxUSE_STATUSBAR
383 wxStatusBar *theStatusBar = GetStatusBar();
384 if (theStatusBar)
385 theStatusBar->GetSize(NULL, &m_fsStatusBarHeight);
386
387 // Save the number of fields in the statusbar
388 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
389 {
390 //m_fsStatusBarFields = theStatusBar->GetFieldsCount();
391 //SetStatusBar((wxStatusBar*) NULL);
392 //delete theStatusBar;
393 theStatusBar->Show(FALSE);
394 }
395 else
396 m_fsStatusBarFields = 0;
397 #endif // wxUSE_STATUSBAR
398 }
399 else
400 {
401 #if wxUSE_TOOLBAR
402 #ifdef __WXWINCE__
403 // TODO: show commandbar
404 #else
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 }
413 #endif // __WXWINCE__
414 #endif // wxUSE_TOOLBAR
415
416 #if wxUSE_STATUSBAR
417 if ( m_fsStyle & wxFULLSCREEN_NOSTATUSBAR )
418 {
419 //CreateStatusBar(m_fsStatusBarFields);
420 if (GetStatusBar())
421 {
422 GetStatusBar()->Show(TRUE);
423 PositionStatusBar();
424 }
425 }
426 #endif // wxUSE_STATUSBAR
427
428 // TODO: make it work for WinCE
429 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
430 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
431 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
432 #endif
433 }
434
435 return wxFrameBase::ShowFullScreen(show, style);
436 }
437
438 // ----------------------------------------------------------------------------
439 // tool/status bar stuff
440 // ----------------------------------------------------------------------------
441
442 #if wxUSE_TOOLBAR
443
444 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
445 {
446 #ifdef __WXWINCE__
447 // We may already have a toolbar from calling SetMenuBar.
448 if (GetToolBar())
449 return GetToolBar();
450 #endif
451 if ( wxFrameBase::CreateToolBar(style, id, name) )
452 {
453 PositionToolBar();
454 }
455
456 return m_frameToolBar;
457 }
458
459 void wxFrame::PositionToolBar()
460 {
461 wxToolBar *toolbar = GetToolBar();
462 if ( toolbar && toolbar->IsShown() )
463 {
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
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);
474
475 #if wxUSE_STATUSBAR
476 wxStatusBar *statbar = GetStatusBar();
477 if ( statbar && statbar->IsShown() )
478 {
479 height -= statbar->GetClientSize().y;
480 }
481 #endif // wxUSE_STATUSBAR
482
483 int tx, ty;
484 int tw, th;
485 toolbar->GetPosition(&tx, &ty);
486 toolbar->GetSize(&tw, &th);
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;
496
497 if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
498 {
499 desiredH = height;
500 }
501 else
502 {
503 desiredW = width;
504 // if ( toolbar->GetWindowStyleFlag() & wxTB_FLAT )
505 // desiredW -= 3;
506 }
507
508 // use the 'real' MSW position here, don't offset relativly to the
509 // client area origin
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
540 #endif // __WXWINCE__
541 }
542 }
543
544 #endif // wxUSE_TOOLBAR
545
546 // ----------------------------------------------------------------------------
547 // frame state (iconized/maximized/...)
548 // ----------------------------------------------------------------------------
549
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
553 void wxFrame::IconizeChildFrames(bool bIconize)
554 {
555 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
556 node;
557 node = node->GetNext() )
558 {
559 wxWindow *win = node->GetData();
560
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
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
573 wxFrame *frame = wxDynamicCast(win, wxFrame);
574 if ( frame
575 #if wxUSE_MDI_ARCHITECTURE
576 && !wxDynamicCast(frame, wxMDIChildFrame)
577 #endif // wxUSE_MDI_ARCHITECTURE
578 )
579 {
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 {
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();
590 }
591
592 // this test works for both iconizing and restoring
593 if ( !frame->m_wasMinimized )
594 frame->Iconize(bIconize);
595 }
596 }
597 }
598
599 WXHICON wxFrame::GetDefaultIcon() const
600 {
601 // we don't have any standard icons (any more)
602 return (WXHICON)0;
603 }
604
605 // ===========================================================================
606 // message processing
607 // ===========================================================================
608
609 // ---------------------------------------------------------------------------
610 // preprocessing
611 // ---------------------------------------------------------------------------
612
613 bool wxFrame::MSWTranslateMessage(WXMSG* pMsg)
614 {
615 if ( wxWindow::MSWTranslateMessage(pMsg) )
616 return TRUE;
617
618 #if wxUSE_MENUS && wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
619 // try the menu bar accels
620 wxMenuBar *menuBar = GetMenuBar();
621 if ( !menuBar )
622 return FALSE;
623
624 const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
625 return acceleratorTable.Translate(this, pMsg);
626 #else
627 return FALSE;
628 #endif // wxUSE_MENUS && wxUSE_ACCEL
629 }
630
631 // ---------------------------------------------------------------------------
632 // our private (non virtual) message handlers
633 // ---------------------------------------------------------------------------
634
635 bool wxFrame::HandlePaint()
636 {
637 RECT rect;
638 if ( GetUpdateRect(GetHwnd(), &rect, FALSE) )
639 {
640 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
641 if ( m_iconized )
642 {
643 const wxIcon& icon = GetIcon();
644 HICON hIcon = icon.Ok() ? GetHiconOf(icon)
645 : (HICON)GetDefaultIcon();
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
675 #endif
676 {
677 return wxWindow::HandlePaint();
678 }
679 }
680 else
681 {
682 // nothing to paint - processed
683 return TRUE;
684 }
685 }
686
687 bool wxFrame::HandleSize(int x, int y, WXUINT id)
688 {
689 bool processed = FALSE;
690 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
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
704 (void)SendIconizeEvent(FALSE);
705
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
716 (void)SendIconizeEvent();
717
718 m_iconized = TRUE;
719 break;
720 }
721 #endif
722
723 if ( !m_iconized )
724 {
725 #if wxUSE_STATUSBAR
726 PositionStatusBar();
727 #endif // wxUSE_STATUSBAR
728
729 #if wxUSE_TOOLBAR
730 PositionToolBar();
731 #endif // wxUSE_TOOLBAR
732
733 processed = wxWindow::HandleSize(x, y, id);
734 }
735
736 return processed;
737 }
738
739 bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
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 {
752 #if wxUSE_MENUS_NATIVE
753 if ( wxCurrentPopupMenu )
754 {
755 wxMenu *popupMenu = wxCurrentPopupMenu;
756 wxCurrentPopupMenu = NULL;
757
758 return popupMenu->MSWCommand(cmd, id);
759 }
760 #endif // wxUSE_MENUS_NATIVE
761
762 if ( ProcessCommand(id) )
763 {
764 return TRUE;
765 }
766 }
767
768 return FALSE;
769 }
770
771 bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
772 {
773 int item;
774 if ( flags == 0xFFFF && hMenu == 0 )
775 {
776 // menu was removed from screen
777 item = -1;
778 }
779 #ifndef __WXMICROWIN__
780 else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) )
781 {
782 item = nItem;
783 }
784 #endif
785 else
786 {
787 // don't give hints for separators (doesn't make sense) nor for the
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
791 DoGiveHelp(wxEmptyString, FALSE);
792
793 return FALSE;
794 }
795
796 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
797 event.SetEventObject(this);
798
799 return GetEventHandler()->ProcessEvent(event);
800 }
801
802 bool 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);
808
809 return GetEventHandler()->ProcessEvent(event);
810 }
811
812 // ---------------------------------------------------------------------------
813 // the window proc for wxFrame
814 // ---------------------------------------------------------------------------
815
816 long wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
817 {
818 long rc = 0;
819 bool processed = FALSE;
820
821 switch ( message )
822 {
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
829 case WM_SIZE:
830 processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
831 break;
832
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
844 case WM_PAINT:
845 processed = HandlePaint();
846 break;
847
848 case WM_INITMENUPOPUP:
849 processed = HandleInitMenuPopup((WXHMENU) wParam);
850 break;
851
852 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
853 case WM_MENUSELECT:
854 {
855 WXWORD item, flags;
856 WXHMENU hmenu;
857 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
858
859 processed = HandleMenuSelect(item, flags, hmenu);
860 }
861 break;
862
863 case WM_EXITMENULOOP:
864 processed = HandleMenuLoop(wxEVT_MENU_CLOSE, wParam);
865 break;
866
867 case WM_QUERYDRAGICON:
868 {
869 const wxIcon& icon = GetIcon();
870 HICON hIcon = icon.Ok() ? GetHiconOf(icon)
871 : (HICON)GetDefaultIcon();
872 rc = (long)hIcon;
873 processed = rc != 0;
874 }
875 break;
876 #endif // !__WXMICROWIN__
877 }
878
879 if ( !processed )
880 rc = wxFrameBase::MSWWindowProc(message, wParam, lParam);
881
882 return rc;
883 }
884
885 // handle WM_INITMENUPOPUP message
886 bool wxFrame::HandleInitMenuPopup(WXHMENU hMenu)
887 {
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);
903 event.SetEventObject(this);
904
905 return GetEventHandler()->ProcessEvent(event);
906 }