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