]> git.saurik.com Git - wxWidgets.git/blob - src/os2/frame.cpp
attempt to fix wxMenuBar::EnableTop
[wxWidgets.git] / src / os2 / frame.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: frame.cpp
3 // Purpose: wxFrame
4 // Author: David Webster
5 // Modified by:
6 // Created: 08/12/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include "wx/setup.h"
17 #include "wx/frame.h"
18 #include "wx/menu.h"
19 #include "wx/app.h"
20 #include "wx/utils.h"
21 #include "wx/dialog.h"
22 #include "wx/settings.h"
23 #include "wx/dcclient.h"
24 #endif // WX_PRECOMP
25
26 #include "wx/os2/private.h"
27 #include "wx/statusbr.h"
28 #include "wx/toolbar.h"
29 #include "wx/menuitem.h"
30 #include "wx/log.h"
31
32 extern wxWindowList wxModelessWindows;
33 extern wxList WXDLLEXPORT wxPendingDelete;
34 extern wxChar wxFrameClassName[];
35 extern wxMenu *wxCurrentPopupMenu;
36
37 #if !USE_SHARED_LIBRARY
38 BEGIN_EVENT_TABLE(wxFrame, wxWindow)
39 EVT_SIZE(wxFrame::OnSize)
40 EVT_ACTIVATE(wxFrame::OnActivate)
41 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
42 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
43 EVT_IDLE(wxFrame::OnIdle)
44 EVT_CLOSE(wxFrame::OnCloseWindow)
45 END_EVENT_TABLE()
46
47 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
48 #endif
49
50 bool wxFrame::m_useNativeStatusBar = FALSE;
51
52 wxFrame::wxFrame()
53 {
54 #if wxUSE_TOOLBAR
55 m_frameToolBar = NULL ;
56 #endif
57 m_frameMenuBar = NULL;
58 m_frameStatusBar = NULL;
59
60 m_iconized = FALSE;
61 }
62
63 bool wxFrame::Create( wxWindow *parent
64 ,wxWindowID id
65 ,const wxString& title
66 ,const wxPoint& pos
67 ,const wxSize& size
68 ,long style
69 ,const wxString& name
70 )
71 {
72 #if wxUSE_TOOLTIPS
73 m_hwndToolTip = 0;
74 #endif
75
76 SetName(name);
77 m_windowStyle = style;
78 m_frameMenuBar = NULL;
79 #if wxUSE_TOOLBAR
80 m_frameToolBar = NULL ;
81 #endif
82 m_frameStatusBar = NULL;
83
84 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
85
86 // m_icon = NULL;
87 if ( id > -1 )
88 m_windowId = id;
89 else
90 m_windowId = (int)NewControlId();
91
92 if (parent) parent->AddChild(this);
93
94 int x = pos.x;
95 int y = pos.y;
96 int width = size.x;
97 int height = size.y;
98
99 m_iconized = FALSE;
100
101 if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
102 parent = NULL;
103
104 if (!parent)
105 wxTopLevelWindows.Append(this);
106
107 OS2Create(m_windowId, parent, wxFrameClassName, this, title,
108 x, y, width, height, style);
109
110 wxModelessWindows.Append(this);
111 return TRUE;
112 }
113
114 wxFrame::~wxFrame()
115 {
116 m_isBeingDeleted = TRUE;
117 wxTopLevelWindows.DeleteObject(this);
118
119 if (m_frameStatusBar)
120 delete m_frameStatusBar;
121 if (m_frameMenuBar)
122 delete m_frameMenuBar;
123
124 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
125 {
126 wxTheApp->SetTopWindow(NULL);
127
128 if (wxTheApp->GetExitOnFrameDelete())
129 {
130 // TODO: PostQuitMessage(0);
131 return;
132 }
133 }
134
135 wxModelessWindows.DeleteObject(this);
136
137 // For some reason, wxWindows can activate another task altogether
138 // when a frame is destroyed after a modal dialog has been invoked.
139 // Try to bring the parent to the top.
140 // MT:Only do this if this frame is currently the active window, else weird
141 // things start to happen
142 if ( wxGetActiveWindow() == this )
143 if (GetParent() && GetParent()->GetHWND())
144 // TODO: OS/2 PM version
145 // ::BringWindowToTop((HWND) GetParent()->GetHWND());
146 return;
147 }
148
149 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
150 void wxFrame::DoGetClientSize(int *x, int *y) const
151 {
152 RECT rect;
153 //TODO: ::GetClientRect(GetHwnd(), &rect);
154
155 if ( GetStatusBar() )
156 {
157 int statusX, statusY;
158 GetStatusBar()->GetClientSize(&statusX, &statusY);
159 // TODO: OS/2's rect rect.bottom -= statusY;
160 }
161
162 wxPoint pt(GetClientAreaOrigin());
163 /*
164 rect.bottom -= pt.y;
165 rect.right -= pt.x;
166
167 if ( x )
168 *x = rect.right;
169 if ( y )
170 *y = rect.bottom;
171 */
172 }
173
174 // Set the client size (i.e. leave the calculation of borders etc.
175 // to wxWindows)
176 void wxFrame::DoSetClientSize(int width, int height)
177 {
178 HWND hWnd = GetHwnd();
179
180 RECT rect;
181 // TODO: ::GetClientRect(hWnd, &rect);
182
183 RECT rect2;
184 //TODO: ::GetWindowRect(hWnd, &rect2);
185
186 // Find the difference between the entire window (title bar and all)
187 // and the client area; add this to the new client size to move the
188 // window
189 /*
190 int actual_width = rect2.right - rect2.left - rect.right + width;
191 int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
192 */
193 if ( GetStatusBar() )
194 {
195 int statusX, statusY;
196 GetStatusBar()->GetClientSize(&statusX, &statusY);
197 // actual_height += statusY;
198 }
199 /*
200 wxPoint pt(GetClientAreaOrigin());
201 actual_width += pt.y;
202 actual_height += pt.x;
203
204 POINT point;
205
206 point.x = rect2.left;
207 point.y = rect2.top;
208
209 MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
210 */
211 wxSizeEvent event(wxSize(width, height), m_windowId);
212 event.SetEventObject( this );
213 GetEventHandler()->ProcessEvent(event);
214 }
215
216 void wxFrame::DoGetSize(int *width, int *height) const
217 {
218 RECT rect;
219 // TODO: ::GetWindowRect(GetHwnd(), &rect);
220 // *width = rect.right - rect.left;
221 // *height = rect.bottom - rect.top;
222 }
223
224 void wxFrame::DoGetPosition(int *x, int *y) const
225 {
226 RECT rect;
227 // TODO: ::GetWindowRect(GetHwnd(), &rect);
228 POINTL point;
229 // point.x = rect.left;
230 // point.y = rect.top;
231
232 *x = point.x;
233 *y = point.y;
234 }
235
236 bool wxFrame::Show(bool show)
237 {
238 int cshow;
239 /*
240 if (show)
241 cshow = SW_SHOW;
242 else
243 cshow = SW_HIDE;
244 */
245 if (!show)
246 {
247 // Try to highlight the correct window (the parent)
248 HWND hWndParent = 0;
249 if (GetParent())
250 {
251 hWndParent = (HWND) GetParent()->GetHWND();
252 if (hWndParent)
253 // TODO: ::BringWindowToTop(hWndParent);
254 cshow = (int)show; // just to have something here, remove
255 }
256 }
257
258 // TODO: ::ShowWindow(GetHwnd(), (BOOL)cshow);
259 if (show)
260 {
261 // TODO: ::BringWindowToTop(GetHwnd());
262
263 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId);
264 event.SetEventObject( this );
265 GetEventHandler()->ProcessEvent(event);
266 }
267 return TRUE;
268 }
269
270 void wxFrame::Iconize(bool iconize)
271 {
272 if (!iconize)
273 Show(TRUE);
274
275 int cshow;
276 /*
277 if (iconize)
278 cshow = SW_MINIMIZE;
279 else
280 cshow = SW_RESTORE;
281 ShowWindow(GetHwnd(), (BOOL)cshow);
282 */
283 m_iconized = iconize;
284 }
285
286 // Equivalent to maximize/restore in Windows
287 void wxFrame::Maximize(bool maximize)
288 {
289 Show(TRUE);
290 int cshow;
291 /*
292 if (maximize)
293 cshow = SW_MAXIMIZE;
294 else
295 cshow = SW_RESTORE;
296 ShowWindow(GetHwnd(), cshow);
297 */
298 m_iconized = FALSE;
299 }
300
301 bool wxFrame::IsIconized() const
302 {
303 // TODO: ((wxFrame *)this)->m_iconized = (::IsIconic(GetHwnd()) != 0);
304 return m_iconized;
305 }
306
307 // Is it maximized?
308 bool wxFrame::IsMaximized() const
309 {
310 //TODO: return (::IsZoomed(GetHwnd()) != 0) ;
311 return FALSE; // remove
312 }
313
314 void wxFrame::SetIcon(const wxIcon& icon)
315 {
316 m_icon = icon;
317 }
318
319 #if wxUSE_STATUSBAR
320 wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
321 const wxString& name)
322 {
323 wxStatusBar *statusBar = NULL;
324
325 statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20),
326 style, name);
327
328 // Set the height according to the font and the border size
329 wxClientDC dc(statusBar);
330 dc.SetFont(statusBar->GetFont());
331
332 long x, y;
333 dc.GetTextExtent("X", &x, &y);
334
335 int height = (int)( (y * 1.1) + 2* statusBar->GetBorderY());
336 statusBar->SetSize(-1, -1, 100, height);
337 statusBar->SetFieldsCount(number);
338 return statusBar;
339 }
340
341 wxStatusBar* wxFrame::CreateStatusBar(int number, long style, wxWindowID id,
342 const wxString& name)
343 {
344 // VZ: calling CreateStatusBar twice is an error - why anyone would do it?
345 wxCHECK_MSG( m_frameStatusBar == NULL, FALSE,
346 wxT("recreating status bar in wxFrame") );
347
348 m_frameStatusBar = OnCreateStatusBar(number, style, id,
349 name);
350 if ( m_frameStatusBar )
351 {
352 PositionStatusBar();
353 return m_frameStatusBar;
354 }
355 else
356 return NULL;
357 }
358
359 void wxFrame::SetStatusText(const wxString& text, int number)
360 {
361 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
362
363 m_frameStatusBar->SetStatusText(text, number);
364 }
365
366 void wxFrame::SetStatusWidths(int n, const int widths_field[])
367 {
368 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set widths for") );
369
370 m_frameStatusBar->SetStatusWidths(n, widths_field);
371 PositionStatusBar();
372 }
373
374 void wxFrame::PositionStatusBar()
375 {
376 // native status bar positions itself
377 if (m_frameStatusBar)
378 {
379 int w, h;
380 GetClientSize(&w, &h);
381 int sw, sh;
382 m_frameStatusBar->GetSize(&sw, &sh);
383
384 // Since we wish the status bar to be directly under the client area,
385 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
386 m_frameStatusBar->SetSize(0, h, w, sh);
387 }
388 }
389 #endif // wxUSE_STATUSBAR
390
391 void wxFrame::DetachMenuBar()
392 {
393 if (m_frameMenuBar)
394 {
395 // Fix this in wxMenuBar m_frameMenuBar->Detach();
396 m_frameMenuBar = NULL;
397 }
398 }
399
400 void wxFrame::SetMenuBar(wxMenuBar *menu_bar)
401 {
402 if (!menu_bar)
403 {
404 DetachMenuBar();
405 return;
406 }
407
408 // Fix this in wxMenuBar wxCHECK_RET( !menu_bar->GetFrame(), wxT("this menubar is already attached") );
409
410 if (m_frameMenuBar)
411 delete m_frameMenuBar;
412
413 // Fix this in wxMenuBar m_hMenu = menu_bar->Create();
414
415 if ( !m_hMenu )
416 return;
417
418 InternalSetMenuBar();
419
420 m_frameMenuBar = menu_bar;
421 // Fix this in wxMenuBar menu_bar->Attach(this);
422 }
423
424 void wxFrame::InternalSetMenuBar()
425 {
426 // TODO:
427 /* if ( !::SetMenu(GetHwnd(), (HMENU)m_hMenu) )
428 {
429 wxLogLastError("SetMenu");
430 }
431 */
432 }
433
434 // Responds to colour changes, and passes event on to children.
435 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
436 {
437 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
438 Refresh();
439
440 if ( m_frameStatusBar )
441 {
442 wxSysColourChangedEvent event2;
443 event2.SetEventObject( m_frameStatusBar );
444 m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
445 }
446
447 // Propagate the event to the non-top-level children
448 wxWindow::OnSysColourChanged(event);
449 }
450
451 /*
452 * Frame window
453 *
454 */
455
456 bool wxFrame::OS2Create(int id, wxWindow *parent, const wxChar *wclass, wxWindow *wx_win, const wxChar *title,
457 int x, int y, int width, int height, long style)
458
459 {
460 m_defaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
461
462 // If child windows aren't properly drawn initially, WS_CLIPCHILDREN
463 // could be the culprit. But without it, you can get a lot of flicker.
464 // TODO:
465 /*
466 DWORD msflags = 0;
467 if ((style & wxCAPTION) == wxCAPTION)
468 msflags = WS_OVERLAPPED;
469 else
470 msflags = WS_POPUP;
471
472 if (style & wxMINIMIZE_BOX)
473 msflags |= WS_MINIMIZEBOX;
474 if (style & wxMAXIMIZE_BOX)
475 msflags |= WS_MAXIMIZEBOX;
476 if (style & wxTHICK_FRAME)
477 msflags |= WS_THICKFRAME;
478 if (style & wxSYSTEM_MENU)
479 msflags |= WS_SYSMENU;
480 if ((style & wxMINIMIZE) || (style & wxICONIZE))
481 msflags |= WS_MINIMIZE;
482 if (style & wxMAXIMIZE)
483 msflags |= WS_MAXIMIZE;
484 if (style & wxCAPTION)
485 msflags |= WS_CAPTION;
486 if (style & wxCLIP_CHILDREN)
487 msflags |= WS_CLIPCHILDREN;
488
489 // Keep this in wxFrame because it saves recoding this function
490 // in wxTinyFrame
491 #if wxUSE_ITSY_BITSY
492 if (style & wxTINY_CAPTION_VERT)
493 msflags |= IBS_VERTCAPTION;
494 if (style & wxTINY_CAPTION_HORIZ)
495 msflags |= IBS_HORZCAPTION;
496 #else
497 if (style & wxTINY_CAPTION_VERT)
498 msflags |= WS_CAPTION;
499 if (style & wxTINY_CAPTION_HORIZ)
500 msflags |= WS_CAPTION;
501 #endif
502 if ((style & wxTHICK_FRAME) == 0)
503 msflags |= WS_BORDER;
504
505 WXDWORD extendedStyle = MakeExtendedStyle(style);
506
507 #if !defined(__WIN16__) && !defined(__SC__)
508 if (style & wxFRAME_TOOL_WINDOW)
509 extendedStyle |= WS_EX_TOOLWINDOW;
510 #endif
511
512 if (style & wxSTAY_ON_TOP)
513 extendedStyle |= WS_EX_TOPMOST;
514
515 m_iconized = FALSE;
516 if ( !wxWindow::OS2Create(id, parent, wclass, wx_win, title, x, y, width, height,
517 msflags, NULL, extendedStyle) )
518 return FALSE;
519
520 // Seems to be necessary if we use WS_POPUP
521 // style instead of WS_OVERLAPPED
522 if (width > -1 && height > -1)
523 ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
524 */
525 return TRUE;
526 }
527
528 // Default resizing behaviour - if only ONE subwindow, resize to client
529 // rectangle size
530 void wxFrame::OnSize(wxSizeEvent& event)
531 {
532 // if we're using constraints - do use them
533 #if wxUSE_CONSTRAINTS
534 if ( GetAutoLayout() )
535 {
536 Layout();
537 return;
538 }
539 #endif
540
541 // do we have _exactly_ one child?
542 wxWindow *child = NULL;
543 for ( wxWindowList::Node *node = GetChildren().GetFirst();
544 node;
545 node = node->GetNext() )
546 {
547 wxWindow *win = node->GetData();
548 if ( !win->IsTopLevel()
549 #if wxUSE_STATUSBAR
550 && (win != GetStatusBar())
551 #endif // wxUSE_STATUSBAR
552 #if wxUSE_TOOLBAR
553 && (win != GetToolBar())
554 #endif // wxUSE_TOOLBAR
555 )
556 {
557 if ( child )
558 return; // it's our second subwindow - nothing to do
559 child = win;
560 }
561 }
562
563 if ( child ) {
564 // we have exactly one child - set it's size to fill the whole frame
565 int clientW, clientH;
566 GetClientSize(&clientW, &clientH);
567
568 int x = 0;
569 int y = 0;
570
571 child->SetSize(x, y, clientW, clientH);
572 }
573 }
574
575 // Default activation behaviour - set the focus for the first child
576 // subwindow found.
577 void wxFrame::OnActivate(wxActivateEvent& event)
578 {
579 for ( wxWindowList::Node *node = GetChildren().GetFirst();
580 node;
581 node = node->GetNext() )
582 {
583 // FIXME all this is totally bogus - we need to do the same as wxPanel,
584 // but how to do it without duplicating the code?
585
586 // restore focus
587 wxWindow *child = node->GetData();
588
589 if ( !child->IsTopLevel()
590 #if wxUSE_TOOLBAR
591 && !wxDynamicCast(child, wxToolBar)
592 #endif // wxUSE_TOOLBAR
593 #if wxUSE_STATUSBAR
594 && !wxDynamicCast(child, wxStatusBar)
595 #endif // wxUSE_STATUSBAR
596 )
597 {
598 child->SetFocus();
599 return;
600 }
601 }
602 }
603
604 // The default implementation for the close window event.
605 void wxFrame::OnCloseWindow(wxCloseEvent& event)
606 {
607 Destroy();
608 }
609
610 // Destroy the window (delayed, if a managed window)
611 bool wxFrame::Destroy()
612 {
613 if (!wxPendingDelete.Member(this))
614 wxPendingDelete.Append(this);
615 return TRUE;
616 }
617
618 // Default menu selection behaviour - display a help string
619 void wxFrame::OnMenuHighlight(wxMenuEvent& event)
620 {
621 if (GetStatusBar())
622 {
623 wxString help;
624 int menuId = event.GetMenuId();
625 if ( menuId != -1 )
626 {
627 wxMenuBar *menuBar = GetMenuBar();
628 // Fix this in wxMenuBar
629 /*
630 if (menuBar && menuBar->FindItem(menuId))
631 {
632 help = menuBar->GetHelpString(menuId);
633 }
634 */
635 }
636
637 // set status text even if the string is empty - this will at
638 // least remove the string from the item which was previously
639 // selected
640 SetStatusText(help);
641 }
642 }
643
644 wxMenuBar *wxFrame::GetMenuBar() const
645 {
646 return m_frameMenuBar;
647 }
648
649 bool wxFrame::ProcessCommand(int id)
650 {
651 wxMenuBar *bar = GetMenuBar() ;
652 if ( !bar )
653 return FALSE;
654
655 wxMenuItem *item = bar->FindItemForId(id);
656
657 if ( item && item->IsCheckable() )
658 {
659 bar->Check(id, !bar->IsChecked(id)) ;
660 }
661
662 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
663 commandEvent.SetInt( id );
664 commandEvent.SetEventObject( this );
665
666 return GetEventHandler()->ProcessEvent(commandEvent);
667 }
668
669 // Checks if there is a toolbar, and returns the first free client position
670 wxPoint wxFrame::GetClientAreaOrigin() const
671 {
672 wxPoint pt(0, 0);
673 #if wxUSE_TOOLBAR
674 if (GetToolBar())
675 {
676 int w, h;
677 GetToolBar()->GetSize(& w, & h);
678
679 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
680 {
681 pt.x += w;
682 }
683 else
684 {
685 pt.y += h;
686 }
687 }
688 #endif
689 return pt;
690 }
691
692 void wxFrame::DoScreenToClient(int *x, int *y) const
693 {
694 wxWindow::ScreenToClient(x, y);
695
696 // We may be faking the client origin.
697 // So a window that's really at (0, 30) may appear
698 // (to wxWin apps) to be at (0, 0).
699 wxPoint pt(GetClientAreaOrigin());
700 *x -= pt.x;
701 *y -= pt.y;
702 }
703
704 void wxFrame::DoClientToScreen(int *x, int *y) const
705 {
706 // We may be faking the client origin.
707 // So a window that's really at (0, 30) may appear
708 // (to wxWin apps) to be at (0, 0).
709 wxPoint pt1(GetClientAreaOrigin());
710 *x += pt1.x;
711 *y += pt1.y;
712
713 wxWindow::DoClientToScreen(x, y);
714 }
715
716 #if wxUSE_TOOLBAR
717 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
718 {
719 wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
720 wxT("recreating toolbar in wxFrame") );
721
722 wxToolBar* toolBar = OnCreateToolBar(style, id, name);
723 if (toolBar)
724 {
725 SetToolBar(toolBar);
726 PositionToolBar();
727 return toolBar;
728 }
729 else
730 {
731 return NULL;
732 }
733 }
734
735 wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
736 {
737 return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
738 }
739
740 void wxFrame::PositionToolBar()
741 {
742 RECT rect;
743 // TODO: ::GetClientRect(GetHwnd(), &rect);
744
745 if ( GetStatusBar() )
746 {
747 int statusX, statusY;
748 GetStatusBar()->GetClientSize(&statusX, &statusY);
749 // TODO: rect.bottom -= statusY;
750 }
751
752 if (GetToolBar())
753 {
754 int tw, th;
755 GetToolBar()->GetSize(& tw, & th);
756
757 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
758 {
759 // Use the 'real' MSW position
760 GetToolBar()->SetSize(0, 0, tw, rect.yBottom, wxSIZE_NO_ADJUSTMENTS);
761 }
762 else
763 {
764 // Use the 'real' MSW position
765 GetToolBar()->SetSize(0, 0, rect.xRight, th, wxSIZE_NO_ADJUSTMENTS);
766 }
767 }
768 }
769 #endif // wxUSE_TOOLBAR
770
771 // propagate our state change to all child frames: this allows us to emulate X
772 // Windows behaviour where child frames float independently of the parent one
773 // on the desktop, but are iconized/restored with it
774 void wxFrame::IconizeChildFrames(bool bIconize)
775 {
776 for ( wxWindowList::Node *node = GetChildren().GetFirst();
777 node;
778 node = node->GetNext() )
779 {
780 wxWindow *win = node->GetData();
781
782 if ( win->IsKindOf(CLASSINFO(wxFrame)) )
783 {
784 ((wxFrame *)win)->Iconize(bIconize);
785 }
786 }
787 }
788
789
790 // make the window modal (all other windows unresponsive)
791 void wxFrame::MakeModal(bool modal)
792 {
793 if (modal) {
794 wxEnableTopLevelWindows(FALSE);
795 Enable(TRUE); // keep this window enabled
796 }
797 else {
798 wxEnableTopLevelWindows(TRUE);
799 }
800 }
801
802
803 // ===========================================================================
804 // message processing
805 // ===========================================================================
806
807 // ---------------------------------------------------------------------------
808 // preprocessing
809 // ---------------------------------------------------------------------------
810
811 bool wxFrame::OS2TranslateMessage(WXMSG* pMsg)
812 {
813 // TODO: if ( wxWindow::OS2TranslateMessage(pMsg) )
814 // return TRUE;
815
816 // try the menu bar accels
817 wxMenuBar *menuBar = GetMenuBar();
818 if ( !menuBar )
819 return FALSE;
820
821 // TODO: const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
822 // return acceleratorTable.Translate(this, pMsg);
823 return TRUE;
824 }
825
826 // ---------------------------------------------------------------------------
827 // our private (non virtual) message handlers
828 // ---------------------------------------------------------------------------
829
830 bool wxFrame::HandlePaint()
831 {
832 RECT rect;
833 // TODO:
834 // if ( GetUpdateRect(GetHwnd(), &rect, FALSE) )
835 // {
836 // if ( m_iconized )
837 // {
838 // HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
839 // : (HICON)m_defaultIcon;
840 //
841 // Hold a pointer to the dc so long as the OnPaint() message
842 // is being processed
843 //
844 // PAINTSTRUCT ps;
845 // HDC hdc = ::BeginPaint(GetHwnd(), &ps);
846 // // Erase background before painting or we get white background
847 // OS2DefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L);
848 //
849 // if ( hIcon )
850 // {
851 // RECT rect;
852 // TODO: ::GetClientRect(GetHwnd(), &rect);
853
854 // FIXME: why hardcoded?
855 // static const int icon_width = 32;
856 // static const int icon_height = 32;
857 //
858 // int icon_x = (int)((rect.right - icon_width)/2);
859 // int icon_y = (int)((rect.bottom - icon_height)/2);
860 //
861 // TODO: ::DrawIcon(hdc, icon_x, icon_y, hIcon);
862 // }
863 //
864 // TODO: ::EndPaint(GetHwnd(), &ps);
865 //
866 // return TRUE;
867 // }
868 // else
869 // {
870 // return wxWindow::HandlePaint();
871 // }
872 // }
873 // else
874 // {
875 // // nothing to paint - processed
876 // return TRUE;
877 // }
878 return TRUE;
879 }
880
881 bool wxFrame::HandleSize(int x, int y, WXUINT id)
882 {
883 bool processed = FALSE;
884
885 /* switch ( id )
886 {
887 case SIZENORMAL:
888 // only do it it if we were iconized before, otherwise resizing the
889 // parent frame has a curious side effect of bringing it under it's
890 // children
891 if ( !m_iconized )
892 break;
893
894 // restore all child frames too
895 IconizeChildFrames(FALSE);
896
897 // fall through
898
899 case SIZEFULLSCREEN:
900 m_iconized = FALSE;
901 break;
902
903 case SIZEICONIC:
904 // iconize all child frames too
905 IconizeChildFrames(TRUE);
906
907 m_iconized = TRUE;
908 break;
909 }
910 */
911 if ( !m_iconized )
912 {
913 PositionStatusBar();
914 #if wxUSE_TOOLBAR
915 PositionToolBar();
916 #endif
917
918 wxSizeEvent event(wxSize(x, y), m_windowId);
919 event.SetEventObject( this );
920 processed = GetEventHandler()->ProcessEvent(event);
921 }
922
923 return processed;
924 }
925
926 bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
927 {
928 if ( control )
929 {
930 // In case it's e.g. a toolbar.
931 wxWindow *win = wxFindWinFromHandle(control);
932 if ( win )
933 // TODO: return win->OS2Command(cmd, id);
934 return TRUE;
935 }
936
937 // handle here commands from menus and accelerators
938 if ( cmd == 0 || cmd == 1 )
939 {
940 if ( wxCurrentPopupMenu )
941 {
942 wxMenu *popupMenu = wxCurrentPopupMenu;
943 wxCurrentPopupMenu = NULL;
944
945 // return popupMenu->OS2Command(cmd, id);
946 return TRUE;
947 }
948
949 if ( ProcessCommand(id) )
950 {
951 return TRUE;
952 }
953 }
954
955 return FALSE;
956 }
957
958 bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
959 {
960 int item;
961 if ( flags == 0xFFFF && hMenu == 0 )
962 {
963 // menu was removed from screen
964 item = -1;
965 }
966 /*
967 else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) )
968 {
969 item = nItem;
970 }
971 */
972 else
973 {
974 // don't give hints for separators (doesn't make sense) nor for the
975 // items opening popup menus (they don't have them anyhow)
976 return FALSE;
977 }
978
979 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
980 event.SetEventObject( this );
981
982 return GetEventHandler()->ProcessEvent(event);
983 }
984
985 // ---------------------------------------------------------------------------
986 // the window proc for wxFrame
987 // ---------------------------------------------------------------------------
988
989 MRESULT wxFrame::OS2WindowProc(HWND hwnd, WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
990 {
991 MRESULT rc = 0;
992 bool processed = FALSE;
993
994 // TODO:
995 /*
996 switch ( message )
997 {
998 case WM_CLOSE:
999 // if we can't close, tell the system that we processed the
1000 // message - otherwise it would close us
1001 processed = !Close();
1002 break;
1003
1004 case WM_COMMAND:
1005 {
1006 WORD id, cmd;
1007 WXHWND hwnd;
1008 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
1009 &id, &hwnd, &cmd);
1010
1011 processed = HandleCommand(id, cmd, (WXHWND)hwnd);
1012 }
1013 break;
1014
1015 case WM_MENUSELECT:
1016 {
1017 WXWORD item, flags;
1018 WXHMENU hmenu;
1019 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
1020
1021 processed = HandleMenuSelect(item, flags, hmenu);
1022 }
1023 break;
1024
1025 case WM_PAINT:
1026 processed = HandlePaint();
1027 break;
1028
1029 case WM_QUERYDRAGICON:
1030 {
1031 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
1032 : (HICON)(m_defaultIcon);
1033 rc = (long)hIcon;
1034 processed = rc != 0;
1035 }
1036 break;
1037
1038 case WM_SIZE:
1039 processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
1040 break;
1041 }
1042 */
1043 if ( !processed )
1044 rc = wxWindow::OS2WindowProc(hwnd, message, wParam, lParam);
1045
1046 return rc;
1047 }
1048