Reworked Frame class
[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 #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
28 #if wxUSE_STATUSBAR
29 #include "wx/statusbr.h"
30 #include "wx/generic/statusbr.h"
31 #endif // wxUSE_STATUSBAR
32
33 #if wxUSE_TOOLBAR
34 #include "wx/toolbar.h"
35 #endif // wxUSE_TOOLBAR
36
37 #include "wx/menuitem.h"
38 #include "wx/log.h"
39
40 // ----------------------------------------------------------------------------
41 // globals
42 // ----------------------------------------------------------------------------
43
44 extern wxWindowList wxModelessWindows;
45 extern wxList WXDLLEXPORT wxPendingDelete;
46 extern wxChar wxFrameClassName[];
47 extern wxMenu *wxCurrentPopupMenu;
48
49 // ----------------------------------------------------------------------------
50 // event tables
51 // ----------------------------------------------------------------------------
52
53 BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
54 EVT_ACTIVATE(wxFrame::OnActivate)
55 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
56 END_EVENT_TABLE()
57
58 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
59
60 // ============================================================================
61 // implementation
62 // ============================================================================
63
64 // ----------------------------------------------------------------------------
65 // static class members
66 // ----------------------------------------------------------------------------
67
68 #if wxUSE_NATIVE_STATUSBAR
69 bool wxFrame::m_bUseNativeStatusBar = TRUE;
70 #else
71 bool wxFrame::m_bUseNativeStatusBar = FALSE;
72 #endif
73
74 // ----------------------------------------------------------------------------
75 // creation/destruction
76 // ----------------------------------------------------------------------------
77
78 void wxFrame::Init()
79 {
80 m_bIconized = FALSE;
81
82 #if wxUSE_TOOLTIPS
83 m_hWndToolTip = 0;
84 #endif
85 // Data to save/restore when calling ShowFullScreen
86 m_lFsStyle = 0L;
87 m_lFsOldWindowStyle = 0L;
88 m_nFsStatusBarFields = 0;
89 m_nFsStatusBarHeight = 0;
90 m_nFsToolBarHeight = 0;
91 m_bFsIsMaximized = FALSE;
92 m_bFsIsShowing = FALSE;
93
94 //
95 // Initialize SWP's
96 //
97 memset(&m_vSwp, 0, sizeof(SWP));
98 memset(&m_vSwpClient, 0, sizeof(SWP));
99 memset(&m_vSwpTitleBar, 0, sizeof(SWP));
100 memset(&m_vSwpMenuBar, 0, sizeof(SWP));
101 memset(&m_vSwpHScroll, 0, sizeof(SWP));
102 memset(&m_vSwpVScroll, 0, sizeof(SWP));
103 memset(&m_vSwpStatusBar, 0, sizeof(SWP));
104 memset(&m_vSwpToolBar, 0, sizeof(SWP));
105 } // end of wxFrame::Init
106
107 bool wxFrame::Create(
108 wxWindow* pParent
109 , wxWindowID vId
110 , const wxString& rsTitle
111 , const wxPoint& rPos
112 , const wxSize& rSize
113 , long lulStyle
114 , const wxString& rsName
115 )
116 {
117 int nX = rPos.x;
118 int nY = rPos.y;
119 int nWidth = rSize.x;
120 int nHeight = rSize.y;
121
122 SetName(rsName);
123 m_windowStyle = lulStyle;
124 m_frameMenuBar = NULL;
125 m_frameToolBar = NULL;
126 m_frameStatusBar = NULL;
127
128 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
129
130 if (vId > -1 )
131 m_windowId = vId;
132 else
133 m_windowId = (int)NewControlId();
134
135 if (pParent)
136 pParent->AddChild(this);
137
138 m_bIconized = FALSE;
139
140 if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
141 pParent = NULL;
142
143 if (!pParent)
144 wxTopLevelWindows.Append(this);
145
146 OS2Create( m_windowId
147 ,pParent
148 ,wxFrameClassName
149 ,this
150 ,rsTitle
151 ,nX
152 ,nY
153 ,nWidth
154 ,nHeight
155 ,lulStyle
156 );
157
158 wxModelessWindows.Append(this);
159 return TRUE;
160 } // end of wxFrame::Create
161
162 wxFrame::~wxFrame()
163 {
164 m_isBeingDeleted = TRUE;
165 wxTopLevelWindows.DeleteObject(this);
166
167 DeleteAllBars();
168
169 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
170 {
171 wxTheApp->SetTopWindow(NULL);
172
173 if (wxTheApp->GetExitOnFrameDelete())
174 {
175 ::WinPostMsg(m_hFrame, WM_QUIT, 0, 0);
176 }
177 }
178 wxModelessWindows.DeleteObject(this);
179
180 //
181 // For some reason, wxWindows can activate another task altogether
182 // when a frame is destroyed after a modal dialog has been invoked.
183 // Try to bring the parent to the top.
184 //
185 // MT:Only do this if this frame is currently the active window, else weird
186 // things start to happen.
187 //
188 if (wxGetActiveWindow() == this)
189 {
190 if (GetParent() && GetParent()->GetHWND())
191 {
192 ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
193 ,HWND_TOP
194 ,0
195 ,0
196 ,0
197 ,0
198 ,SWP_ZORDER
199 );
200 }
201 }
202 } // end of wxFrame::~wxFrame
203
204 //
205 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
206 //
207 void wxFrame::DoGetClientSize(
208 int* pX
209 , int* pY
210 ) const
211 {
212 //
213 // OS/2 PM's coordinates go from bottom-left not
214 // top-left thus the += instead of the -=
215 //
216 RECTL vRect;
217
218 //
219 // PM has no GetClientRect that inherantly knows about the client window
220 // We have to explicitly go fetch it!
221 //
222 ::WinQueryWindowRect(GetHwnd(), &vRect);
223
224 #if wxUSE_STATUSBAR
225 if ( GetStatusBar() )
226 {
227 int nStatusX;
228 int nStatusY;
229
230 GetStatusBar()->GetClientSize( &nStatusX
231 ,&nStatusY
232 );
233 vRect.yBottom += nStatusY;
234 }
235 #endif // wxUSE_STATUSBAR
236
237 wxPoint vPoint(GetClientAreaOrigin());
238
239 vRect.yBottom += vPoint.y;
240 vRect.xRight -= vPoint.x;
241
242 if (pX)
243 *pX = vRect.xRight;
244 if (pY)
245 *pY = vRect.yBottom;
246 } // end of wxFrame::DoGetClientSize
247
248 //
249 // Set the client size (i.e. leave the calculation of borders etc.
250 // to wxWindows)
251 //
252 void wxFrame::DoSetClientSize(
253 int nWidth
254 , int nHeight
255 )
256 {
257 HWND hWnd = GetHwnd();
258 RECTL vRect;
259 RECTL vRect2;
260
261 ::WinQueryWindowRect(GetHwnd(), &vRect);
262
263 ::WinQueryWindowRect(m_hFrame, &vRect2);
264
265 //
266 // Find the difference between the entire window (title bar and all)
267 // and the client area; add this to the new client size to move the
268 // window. Remember OS/2's backwards y coord system!
269 //
270 int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
271 int nActualHeight = vRect2.yTop + vRect2.yTop - vRect.yTop + nHeight;
272
273 #if wxUSE_STATUSBAR
274 if ( GetStatusBar() )
275 {
276 int nStatusX;
277 int nStatusY;
278
279 GetStatusBar()->GetClientSize( &nStatusX
280 ,&nStatusY
281 );
282 nActualHeight += nStatusY;
283 }
284 #endif // wxUSE_STATUSBAR
285
286 wxPoint vPoint(GetClientAreaOrigin());
287 nActualWidth += vPoint.y;
288 nActualHeight += vPoint.x;
289
290 POINTL vPointl;
291
292 vPointl.x = vRect2.xLeft;
293 vPoint.y = vRect2.yTop;
294
295 ::WinSetWindowPos( m_hFrame
296 ,HWND_TOP
297 ,vPointl.x
298 ,vPointl.y
299 ,nActualWidth
300 ,nActualHeight
301 ,SWP_MOVE | SWP_SIZE | SWP_SHOW
302 );
303
304 wxSizeEvent vEvent( wxSize( nWidth
305 ,nHeight
306 )
307 ,m_windowId
308 );
309 vEvent.SetEventObject(this);
310 GetEventHandler()->ProcessEvent(vEvent);
311 } // end of wxFrame::DoSetClientSize
312
313 void wxFrame::DoGetSize(
314 int* pWidth
315 , int* pHeight
316 ) const
317 {
318 RECTL vRect;
319
320 ::WinQueryWindowRect(m_hFrame, &vRect);
321 *pWidth = vRect.xRight - vRect.xLeft;
322 *pHeight = vRect.yTop - vRect.yBottom;
323 } // end of wxFrame::DoGetSize
324
325 void wxFrame::DoGetPosition(
326 int* pX
327 , int* pY
328 ) const
329 {
330 RECTL vRect;
331 POINTL vPoint;
332
333 ::WinQueryWindowRect(m_hFrame, &vRect);
334 vPoint.x = vRect.xLeft;
335
336 //
337 // OS/2 is backwards [WIN32 it is vRect.yTop]
338 //
339 vPoint.y = vRect.yBottom;
340
341 *pX = vPoint.x;
342 *pY = vPoint.y;
343 } // end of wxFrame::DoGetPosition
344
345 // ----------------------------------------------------------------------------
346 // variations around ::ShowWindow()
347 // ----------------------------------------------------------------------------
348
349 void wxFrame::DoShowWindow(
350 int bShowCmd
351 )
352 {
353 HWND hClient = NULLHANDLE;
354 SWP vSwp;
355
356 //
357 // Reset the window position
358 //
359 WinQueryWindowPos(m_hFrame, &vSwp);
360 WinSetWindowPos( GetHwnd()
361 ,HWND_TOP
362 ,vSwp.x
363 ,vSwp.y
364 ,vSwp.cx
365 ,vSwp.cy
366 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
367 );
368 ::WinShowWindow(m_hFrame, (BOOL)bShowCmd);
369 ::WinShowWindow(GetHwnd(), (BOOL)bShowCmd);
370 } // end of wxFrame::DoShowWindow
371
372 bool wxFrame::Show(
373 bool bShow
374 )
375 {
376 SWP vSwp;
377
378 DoShowWindow((int)bShow);
379
380 if (bShow)
381 {
382 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
383
384 ::WinQueryWindowPos(m_hFrame, &vSwp);
385 m_bIconized = vSwp.fl & SWP_MINIMIZE;
386 ::WinEnableWindow(m_hFrame, TRUE);
387 vEvent.SetEventObject(this);
388 GetEventHandler()->ProcessEvent(vEvent);
389 }
390 else
391 {
392 //
393 // Try to highlight the correct window (the parent)
394 //
395 if (GetParent())
396 {
397 HWND hWndParent = GetHwndOf(GetParent());
398
399 ::WinQueryWindowPos(hWndParent, &vSwp);
400 m_bIconized = vSwp.fl & SWP_MINIMIZE;
401 if (hWndParent)
402 ::WinSetWindowPos( hWndParent
403 ,HWND_TOP
404 ,vSwp.x
405 ,vSwp.y
406 ,vSwp.cx
407 ,vSwp.cy
408 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
409 );
410 ::WinEnableWindow(hWndParent, TRUE);
411 }
412 }
413 return TRUE;
414 } // end of wxFrame::Show
415
416 void wxFrame::Iconize(
417 bool bIconize
418 )
419 {
420 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
421 } // end of wxFrame::Iconize
422
423 void wxFrame::Maximize(
424 bool bMaximize)
425 {
426 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
427 } // end of wxFrame::Maximize
428
429 void wxFrame::Restore()
430 {
431 DoShowWindow(SWP_RESTORE);
432 } // end of wxFrame::Restore
433
434 bool wxFrame::IsIconized() const
435 {
436 SWP vSwp;
437 bool bIconic;
438
439 ::WinQueryWindowPos(GetHwnd(), &vSwp);
440
441 if (vSwp.fl & SWP_MINIMIZE)
442 ((wxFrame*)this)->m_bIconized = TRUE;
443 else
444 ((wxFrame*)this)->m_bIconized = FALSE;
445 return m_bIconized;
446 } // end of wxFrame::IsIconized
447
448 // Is it maximized?
449 bool wxFrame::IsMaximized() const
450 {
451 SWP vSwp;
452 bool bIconic;
453
454 ::WinQueryWindowPos(m_hFrame, &vSwp);
455 return (vSwp.fl & SWP_MAXIMIZE);
456 } // end of wxFrame::IsMaximized
457
458 void wxFrame::SetIcon(
459 const wxIcon& rIcon
460 )
461 {
462 wxFrameBase::SetIcon(rIcon);
463
464 if ((m_icon.GetHICON()) != NULLHANDLE)
465 {
466 ::WinSendMsg( m_hFrame
467 ,WM_SETICON
468 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
469 ,NULL
470 );
471 ::WinSendMsg( m_hFrame
472 ,WM_UPDATEFRAME
473 ,(MPARAM)FCF_ICON
474 ,(MPARAM)0
475 );
476 }
477 } // end of wxFrame::SetIcon
478
479 #if wxUSE_STATUSBAR
480 wxStatusBar* wxFrame::OnCreateStatusBar(
481 int nNumber
482 , long lulStyle
483 , wxWindowID vId
484 , const wxString& rName
485 )
486 {
487 wxStatusBar* pStatusBar = NULL;
488
489 pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
490 ,lulStyle
491 ,vId
492 ,rName
493 );
494 return pStatusBar;
495 } // end of wxFrame::OnCreateStatusBar
496
497 void wxFrame::PositionStatusBar()
498 {
499 //
500 // Native status bar positions itself
501 //
502 if (m_frameStatusBar)
503 {
504 int nWidth;
505 int nHeight;
506 int nStatbarWidth;
507 int nStatbarHeight;
508 HWND hWndClient;
509 RECTL vRect;
510
511 ::WinQueryWindowRect(GetHwnd(), &vRect);
512 nWidth = vRect.xRight - vRect.xLeft;
513 nHeight = vRect.yTop - vRect.yBottom;
514
515 m_frameStatusBar->GetSize( &nStatbarWidth
516 ,&nStatbarHeight
517 );
518
519 //
520 // Since we wish the status bar to be directly under the client area,
521 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
522 //
523 m_frameStatusBar->SetSize( 0
524 ,nHeight
525 ,nWidth
526 ,nStatbarHeight
527 );
528 }
529 } // end of wxFrame::PositionStatusBar
530 #endif // wxUSE_STATUSBAR
531
532 void wxFrame::DetachMenuBar()
533 {
534 if (m_frameMenuBar)
535 {
536 m_frameMenuBar->Detach();
537 m_frameMenuBar = NULL;
538 }
539 } // end of wxFrame::DetachMenuBar
540
541 void wxFrame::SetMenuBar(
542 wxMenuBar* pMenuBar
543 )
544 {
545 ERRORID vError;
546 wxString sError;
547 HWND hClient = NULLHANDLE;
548 HWND hFrame = NULLHANDLE;
549 HWND hTitlebar = NULLHANDLE;
550 HWND hHScroll = NULLHANDLE;
551 HWND hVScroll = NULLHANDLE;
552 HWND hMenuBar = NULLHANDLE;
553 SWP vSwp;
554 SWP vSwpTitlebar;
555 SWP vSwpVScroll;
556 SWP vSwpHScroll;
557 SWP vSwpMenu;
558
559 if (!pMenuBar)
560 {
561 DetachMenuBar();
562 return;
563 }
564
565 m_frameMenuBar = NULL;
566
567 // Can set a menubar several times.
568 // TODO: how to prevent a memory leak if you have a currently-unattached
569 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
570 // there are problems for MDI).
571 if (pMenuBar->GetHMenu())
572 {
573 m_hMenu = pMenuBar->GetHMenu();
574 }
575 else
576 {
577 pMenuBar->Detach();
578
579 m_hMenu = pMenuBar->Create();
580
581 if (!m_hMenu)
582 return;
583 }
584
585 //
586 // Set the parent and owner of the menubar to be the frame
587 //
588 if (!::WinSetParent(m_hMenu, m_hFrame, FALSE))
589 {
590 vError = ::WinGetLastError(vHabmain);
591 sError = wxPMErrorToStr(vError);
592 wxLogError("Error setting parent for submenu. Error: %s\n", sError);
593 }
594
595 if (!::WinSetOwner(m_hMenu, m_hFrame))
596 {
597 vError = ::WinGetLastError(vHabmain);
598 sError = wxPMErrorToStr(vError);
599 wxLogError("Error setting parent for submenu. Error: %s\n", sError);
600 }
601 InternalSetMenuBar();
602
603 m_frameMenuBar = pMenuBar;
604 pMenuBar->Attach(this);
605
606 //
607 // Now resize the client to fit the new frame
608 //
609 WinQueryWindowPos(m_hFrame, &vSwp);
610 hTitlebar = WinWindowFromID(m_hFrame, FID_TITLEBAR);
611 WinQueryWindowPos(hTitlebar, &vSwpTitlebar);
612 hHScroll = WinWindowFromID(m_hFrame, FID_HORZSCROLL);
613 WinQueryWindowPos(hHScroll, &vSwpHScroll);
614 hVScroll = WinWindowFromID(m_hFrame, FID_VERTSCROLL);
615 WinQueryWindowPos(hVScroll, &vSwpVScroll);
616 hMenuBar = WinWindowFromID(m_hFrame, FID_MENU);
617 WinQueryWindowPos(hMenuBar, &vSwpMenu);
618 WinSetWindowPos( GetHwnd()
619 ,HWND_TOP
620 ,SV_CXSIZEBORDER/2
621 ,(SV_CYSIZEBORDER/2) + vSwpHScroll.cy/2
622 ,vSwp.cx - ((SV_CXSIZEBORDER + 1) + vSwpVScroll.cx)
623 ,vSwp.cy - ((SV_CYSIZEBORDER + 1) + vSwpTitlebar.cy + vSwpMenu.cy + vSwpHScroll.cy/2)
624 ,SWP_SIZE | SWP_MOVE
625 );
626 } // end of wxFrame::SetMenuBar
627
628 void wxFrame::InternalSetMenuBar()
629 {
630 WinSendMsg((HWND)m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
631 } // end of wxFrame::InternalSetMenuBar
632
633 //
634 // Responds to colour changes, and passes event on to children
635 //
636 void wxFrame::OnSysColourChanged(
637 wxSysColourChangedEvent& rEvent
638 )
639 {
640 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
641 Refresh();
642
643 if (m_frameStatusBar)
644 {
645 wxSysColourChangedEvent vEvent2;
646
647 vEvent2.SetEventObject(m_frameStatusBar);
648 m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
649 }
650
651 //
652 // Propagate the event to the non-top-level children
653 //
654 wxWindow::OnSysColourChanged(rEvent);
655 } // end of wxFrame::OnSysColourChanged
656
657 // Pass TRUE to show full screen, FALSE to restore.
658 bool wxFrame::ShowFullScreen(
659 bool bShow
660 , long lStyle
661 )
662 {
663 /*
664 // TODO
665 if (show)
666 {
667 if (IsFullScreen())
668 return FALSE;
669
670 m_fsIsShowing = TRUE;
671 m_fsStyle = style;
672
673 wxToolBar *theToolBar = GetToolBar();
674 wxStatusBar *theStatusBar = GetStatusBar();
675
676 int dummyWidth;
677
678 if (theToolBar)
679 theToolBar->GetSize(&dummyWidth, &m_fsToolBarHeight);
680 if (theStatusBar)
681 theStatusBar->GetSize(&dummyWidth, &m_fsStatusBarHeight);
682
683 // zap the toolbar, menubar, and statusbar
684
685 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
686 {
687 theToolBar->SetSize(-1,0);
688 theToolBar->Show(FALSE);
689 }
690
691 if (style & wxFULLSCREEN_NOMENUBAR)
692 SetMenu((HWND)GetHWND(), (HMENU) NULL);
693
694 // Save the number of fields in the statusbar
695 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
696 {
697 m_fsStatusBarFields = theStatusBar->GetFieldsCount();
698 SetStatusBar((wxStatusBar*) NULL);
699 delete theStatusBar;
700 }
701 else
702 m_fsStatusBarFields = 0;
703
704 // zap the frame borders
705
706 // save the 'normal' window style
707 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
708
709 // save the old position, width & height, maximize state
710 m_fsOldSize = GetRect();
711 m_fsIsMaximized = IsMaximized();
712
713 // decide which window style flags to turn off
714 LONG newStyle = m_fsOldWindowStyle;
715 LONG offFlags = 0;
716
717 if (style & wxFULLSCREEN_NOBORDER)
718 offFlags |= WS_BORDER;
719 if (style & wxFULLSCREEN_NOCAPTION)
720 offFlags |= (WS_CAPTION | WS_SYSMENU);
721
722 newStyle &= (~offFlags);
723
724 // change our window style to be compatible with full-screen mode
725 SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
726
727 // resize to the size of the desktop
728 int width, height;
729
730 RECT rect;
731 ::GetWindowRect(GetDesktopWindow(), &rect);
732 width = rect.right - rect.left;
733 height = rect.bottom - rect.top;
734
735 SetSize(width, height);
736
737 // now flush the window style cache and actually go full-screen
738 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
739
740 wxSizeEvent event(wxSize(width, height), GetId());
741 GetEventHandler()->ProcessEvent(event);
742
743 return TRUE;
744 }
745 else
746 {
747 if (!IsFullScreen())
748 return FALSE;
749
750 m_fsIsShowing = FALSE;
751
752 wxToolBar *theToolBar = GetToolBar();
753
754 // restore the toolbar, menubar, and statusbar
755 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
756 {
757 theToolBar->SetSize(-1, m_fsToolBarHeight);
758 theToolBar->Show(TRUE);
759 }
760
761 if ((m_fsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_fsStatusBarFields > 0))
762 {
763 CreateStatusBar(m_fsStatusBarFields);
764 PositionStatusBar();
765 }
766
767 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
768 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
769
770 Maximize(m_fsIsMaximized);
771 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
772 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
773 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
774
775 return TRUE;
776 }
777 */
778 return TRUE;
779 } // end of wxFrame::ShowFullScreen
780
781 //
782 // Frame window
783 //
784 bool wxFrame::OS2Create(
785 int nId
786 , wxWindow* pParent
787 , const wxChar* zWclass
788 , wxWindow* pWxWin
789 , const wxChar* zTitle
790 , int nX
791 , int nY
792 , int nWidth
793 , int nHeight
794 , long ulStyle
795 )
796 {
797 ULONG ulCreateFlags = 0L;
798 ULONG ulStyleFlags = 0L;
799 ULONG ulExtraFlags = 0L;
800 FRAMECDATA vFrameCtlData;
801 HWND hParent = NULLHANDLE;
802 HWND hClient = NULLHANDLE;
803 HWND hFrame = NULLHANDLE;
804 HWND hTitlebar = NULLHANDLE;
805 HWND hHScroll = NULLHANDLE;
806 HWND hVScroll = NULLHANDLE;
807 SWP vSwp;
808 SWP vSwpClient;
809 SWP vSwpTitlebar;
810 SWP vSwpVScroll;
811 SWP vSwpHScroll;
812 USHORT uCtlCount;
813
814 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
815
816 if (pParent)
817 hParent = GetWinHwnd(pParent);
818 else
819 hParent = HWND_DESKTOP;
820
821 if (ulStyle == wxDEFAULT_FRAME_STYLE)
822 ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
823 FCF_MINMAX | FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_TASKLIST;
824 else
825 {
826 if ((ulStyle & wxCAPTION) == wxCAPTION)
827 ulCreateFlags = FCF_TASKLIST;
828 else
829 ulCreateFlags = FCF_NOMOVEWITHOWNER;
830
831 if (ulStyle & wxMINIMIZE_BOX)
832 ulCreateFlags |= FCF_MINBUTTON;
833 if (ulStyle & wxMAXIMIZE_BOX)
834 ulCreateFlags |= FCF_MAXBUTTON;
835 if (ulStyle & wxTHICK_FRAME)
836 ulCreateFlags |= FCF_DLGBORDER;
837 if (ulStyle & wxSYSTEM_MENU)
838 ulCreateFlags |= FCF_SYSMENU;
839 if (ulStyle & wxCAPTION)
840 ulCreateFlags |= FCF_TASKLIST;
841 if (ulStyle & wxCLIP_CHILDREN)
842 {
843 // Invalid for frame windows under PM
844 }
845
846 if (ulStyle & wxTINY_CAPTION_VERT)
847 ulCreateFlags |= FCF_TASKLIST;
848 if (ulStyle & wxTINY_CAPTION_HORIZ)
849 ulCreateFlags |= FCF_TASKLIST;
850
851 if ((ulStyle & wxTHICK_FRAME) == 0)
852 ulCreateFlags |= FCF_BORDER;
853 if (ulStyle & wxFRAME_TOOL_WINDOW)
854 ulExtraFlags = kFrameToolWindow;
855
856 if (ulStyle & wxSTAY_ON_TOP)
857 ulCreateFlags |= FCF_SYSMODAL;
858 }
859 if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
860 ulStyleFlags |= WS_MINIMIZED;
861 if (ulStyle & wxMAXIMIZE)
862 ulStyleFlags |= WS_MAXIMIZED;
863
864 //
865 // Clear the visible flag, we always call show
866 //
867 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
868 m_bIconized = FALSE;
869
870 //
871 // Set the frame control block
872 //
873 vFrameCtlData.cb = sizeof(vFrameCtlData);
874 vFrameCtlData.flCreateFlags = ulCreateFlags;
875 vFrameCtlData.hmodResources = 0L;
876 vFrameCtlData.idResources = 0;
877
878 //
879 // Create the frame window
880 //
881 if ((m_hFrame = ::WinCreateWindow( hParent // Frame is parent
882 ,WC_FRAME // standard frame class
883 ,(PSZ)zTitle // Window title
884 ,0 // No styles
885 ,0, 0, 0, 0 // Window position
886 ,NULLHANDLE // Owner
887 ,HWND_TOP // Sibling
888 ,(ULONG)nId // ID
889 ,(PVOID)&flFrameCtlData // Creation data
890 ,NULL // Window Pres Params
891 )) == 0L)
892 {
893 return FALSE;
894 }
895
896 if (!wxWindow::OS2Create( m_hFrame
897 ,wxFrameClassName
898 ,NULL
899 ,0L
900 ,0L
901 ,0L
902 ,0L
903 ,0L
904 ,NULLHANDLE
905 ,HWND_TOP
906 ,(unsigned long)FID_CLIENT
907 ,NULL
908 ,NULL
909 ))
910 {
911 return FALSE;
912 }
913
914 //
915 // Now size everything. If adding a menu the client will need to be resized.
916 //
917 if (!::WinSetWindowPos( m_hFrame
918 ,HWND_TOP
919 ,nX
920 ,nY
921 ,nWidth
922 ,nHeight
923 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
924 ))
925 return FALSE;
926
927 uCtlCount = ::WinSendMsg(m_hFrame, WM_FORMATFRAME, (MPARAM)pSwp, (MPARAM)pRect);
928 for (int i = 0; i < uCtlCount; i++)
929 {
930 if (pSwp[i].hwnd == m_hFrame)
931 memcpy(m_vSwp, pSwp[i], sizeof(SWP));
932 else if (pSwp[i].hwnd == m_hVScroll)
933 memcpy(m_vSwpVScroll, pSwp[i], sizeof(SWP));
934 else if (pSwp[i].hwnd == m_hHScroll)
935 memcpy(m_vSwpVScroll, pSwp[i], sizeof(SWP));
936 else if (pSwp[i].hwnd == m_hTitleBar)
937 memcpy(m_vSwpTitleBar, pSwp[i], sizeof(SWP));
938 }
939
940 //
941 // Now set the size of the client
942 //
943 WinSetWindowPos( hClient
944 ,HWND_TOP
945 ,SV_CXSIZEBORDER/2
946 ,(SV_CYSIZEBORDER/2) + m_vSwpHScroll.cy/2
947 ,m_vSwp.cx - ((SV_CXSIZEBORDER + 1) + m_vSwpVScroll.cx)
948 ,m_vSwp.cy - ((SV_CYSIZEBORDER + 1) + m_vSwpTitlebar.cy + m_vSwpHScroll.cy/2)
949 ,SWP_SIZE | SWP_MOVE
950 );
951
952 //
953 // Set the client window's background, otherwise it is transparent!
954 //
955 return TRUE;
956 } // end of wxFrame::OS2Create
957
958 //
959 // Default activation behaviour - set the focus for the first child
960 // subwindow found.
961 //
962 void wxFrame::OnActivate(
963 wxActivateEvent& rEvent
964 )
965 {
966 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
967 pNode;
968 pNode = pNode->GetNext())
969 {
970 // FIXME all this is totally bogus - we need to do the same as wxPanel,
971 // but how to do it without duplicating the code?
972
973 // restore focus
974 wxWindow* pChild = pNode->GetData();
975
976 if (!pChild->IsTopLevel()
977 #if wxUSE_TOOLBAR
978 && !wxDynamicCast(pChild, wxToolBar)
979 #endif // wxUSE_TOOLBAR
980 #if wxUSE_STATUSBAR
981 && !wxDynamicCast(pChild, wxStatusBar)
982 #endif // wxUSE_STATUSBAR
983 )
984 {
985 pChild->SetFocus();
986 return;
987 }
988 }
989 } // end of wxFrame::OnActivate
990
991 // ----------------------------------------------------------------------------
992 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
993 // from the client area, so the client area is what's really available for the
994 // frame contents
995 // ----------------------------------------------------------------------------
996
997 // Checks if there is a toolbar, and returns the first free client position
998 wxPoint wxFrame::GetClientAreaOrigin() const
999 {
1000 wxPoint vPoint(0, 0);
1001
1002 if (GetToolBar())
1003 {
1004 int nWidth;
1005 int nHeight;
1006
1007 GetToolBar()->GetSize( &nWidth
1008 ,&nHeight
1009 );
1010
1011 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1012 {
1013 vPoint.x += nWidth;
1014 }
1015 else
1016 {
1017 // PM is backwards from windows
1018 vPoint.y += nHeight;
1019 }
1020 }
1021 return vPoint;
1022 } // end of wxFrame::GetClientAreaOrigin
1023
1024 // ----------------------------------------------------------------------------
1025 // tool/status bar stuff
1026 // ----------------------------------------------------------------------------
1027
1028 #if wxUSE_TOOLBAR
1029
1030 wxToolBar* wxFrame::CreateToolBar(
1031 long lStyle
1032 , wxWindowID vId
1033 , const wxString& rName
1034 )
1035 {
1036 if (wxFrameBase::CreateToolBar( lStyle
1037 ,vId
1038 ,rName
1039 ))
1040 {
1041 PositionToolBar();
1042 }
1043 return m_frameToolBar;
1044 } // end of wxFrame::CreateToolBar
1045
1046 void wxFrame::PositionToolBar()
1047 {
1048 HWND hWndClient;
1049 RECTL vRect;
1050
1051 ::WinQueryWindowRect(GetHwnd(), &vRect);
1052
1053 #if wxUSE_STATUSBAR
1054 if (GetStatusBar())
1055 {
1056 int nStatusX;
1057 int nStatusY;
1058
1059 GetStatusBar()->GetClientSize( &nStatusX
1060 ,&nStatusY
1061 );
1062 // PM is backwards from windows
1063 vRect.yBottom += nStatusY;
1064 }
1065 #endif // wxUSE_STATUSBAR
1066
1067 if ( GetToolBar() )
1068 {
1069 int nToolbarWidth;
1070 int nToolbarHeight;
1071
1072 GetToolBar()->GetSize( &nToolbarWidth
1073 ,&nToolbarHeight
1074 );
1075
1076 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1077 {
1078 nToolbarHeight = vRect.yBottom;
1079 }
1080 else
1081 {
1082 nToolbarWidth = vRect.xRight;
1083 }
1084
1085 //
1086 // Use the 'real' PM position here
1087 //
1088 GetToolBar()->SetSize( 0
1089 ,0
1090 ,nToolbarWidth
1091 ,nToolbarHeight
1092 ,wxSIZE_NO_ADJUSTMENTS
1093 );
1094 }
1095 } // end of wxFrame::PositionToolBar
1096 #endif // wxUSE_TOOLBAR
1097
1098 // ----------------------------------------------------------------------------
1099 // frame state (iconized/maximized/...)
1100 // ----------------------------------------------------------------------------
1101
1102 //
1103 // propagate our state change to all child frames: this allows us to emulate X
1104 // Windows behaviour where child frames float independently of the parent one
1105 // on the desktop, but are iconized/restored with it
1106 //
1107 void wxFrame::IconizeChildFrames(
1108 bool bIconize
1109 )
1110 {
1111 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1112 pNode;
1113 pNode = pNode->GetNext() )
1114 {
1115 wxWindow* pWin = pNode->GetData();
1116
1117 if (pWin->IsKindOf(CLASSINFO(wxFrame)) )
1118 {
1119 ((wxFrame *)pWin)->Iconize(bIconize);
1120 }
1121 }
1122 } // end of wxFrame::IconizeChildFrames
1123
1124 // ===========================================================================
1125 // message processing
1126 // ===========================================================================
1127
1128 // ---------------------------------------------------------------------------
1129 // preprocessing
1130 // ---------------------------------------------------------------------------
1131 bool wxFrame::OS2TranslateMessage(
1132 WXMSG* pMsg
1133 )
1134 {
1135 if (wxWindow::OS2TranslateMessage(pMsg))
1136 return TRUE;
1137 //
1138 // try the menu bar accels
1139 //
1140 wxMenuBar* pMenuBar = GetMenuBar();
1141
1142 if (!pMenuBar )
1143 return FALSE;
1144
1145 const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
1146 return rAcceleratorTable.Translate(this, pMsg);
1147 } // end of wxFrame::OS2TranslateMessage
1148
1149 // ---------------------------------------------------------------------------
1150 // our private (non virtual) message handlers
1151 // ---------------------------------------------------------------------------
1152 bool wxFrame::HandlePaint()
1153 {
1154 RECTL vRect;
1155
1156 if (::WinQueryUpdateRect(m_hFrame, &vRect))
1157 {
1158 if (m_bIconized)
1159 {
1160 //
1161 // Icons in PM are the same as "pointers"
1162 //
1163 HPOINTER hIcon;
1164
1165 if (m_icon.Ok())
1166 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
1167 else
1168 hIcon = (HPOINTER)m_hDefaultIcon;
1169
1170 //
1171 // Hold a pointer to the dc so long as the OnPaint() message
1172 // is being processed
1173 //
1174 RECTL vRect2;
1175 HPS hPs = ::WinBeginPaint(m_hFrame, NULLHANDLE, &vRect2);
1176
1177 //
1178 // Erase background before painting or we get white background
1179 //
1180 OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
1181
1182 if (hIcon)
1183 {
1184 HWND hWndClient;
1185 RECTL vRect3;
1186
1187 ::WinQueryWindowRect(GetHwnd(), &vRect3);
1188
1189 static const int nIconWidth = 32;
1190 static const int nIconHeight = 32;
1191 int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
1192 int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
1193
1194 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
1195 }
1196 ::WinEndPaint(hPs);
1197 return TRUE;
1198 }
1199 else
1200 {
1201 return wxWindow::HandlePaint();
1202 }
1203 }
1204 else
1205 {
1206 // nothing to paint - processed
1207 return TRUE;
1208 }
1209 return FALSE;
1210 } // end of wxFrame::HandlePaint
1211
1212 bool wxFrame::HandleSize(
1213 int nX
1214 , int nY
1215 , WXUINT nId
1216 )
1217 {
1218 bool bProcessed = FALSE;
1219
1220 switch (nId)
1221 {
1222 case kSizeNormal:
1223 //
1224 // Only do it it if we were iconized before, otherwise resizing the
1225 // parent frame has a curious side effect of bringing it under it's
1226 // children
1227 if (!m_bIconized )
1228 break;
1229
1230 //
1231 // restore all child frames too
1232 //
1233 IconizeChildFrames(FALSE);
1234
1235 //
1236 // fall through
1237 //
1238
1239 case kSizeMax:
1240 m_bIconized = FALSE;
1241 break;
1242
1243 case kSizeMin:
1244 //
1245 // Iconize all child frames too
1246 //
1247 IconizeChildFrames(TRUE);
1248 m_bIconized = TRUE;
1249 break;
1250 }
1251
1252 if (!m_bIconized)
1253 {
1254 //
1255 // forward WM_SIZE to status bar control
1256 //
1257 #if wxUSE_NATIVE_STATUSBAR
1258 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
1259 {
1260 wxSizeEvent vEvent( wxSize( nX
1261 ,nY
1262 )
1263 ,m_frameStatusBar->GetId()
1264 );
1265
1266 vEvent.SetEventObject(m_frameStatusBar);
1267 m_frameStatusBar->OnSize(vEvent);
1268 }
1269 #endif // wxUSE_NATIVE_STATUSBAR
1270
1271 PositionStatusBar();
1272 PositionToolBar();
1273 wxSizeEvent vEvent( wxSize( nX
1274 ,nY
1275 )
1276 ,m_windowId
1277 );
1278
1279 vEvent.SetEventObject(this);
1280 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
1281 }
1282 return bProcessed;
1283 } // end of wxFrame::HandleSize
1284
1285 bool wxFrame::HandleCommand(
1286 WXWORD nId
1287 , WXWORD nCmd
1288 , WXHWND hControl
1289 )
1290 {
1291 if (hControl)
1292 {
1293 //
1294 // In case it's e.g. a toolbar.
1295 //
1296 wxWindow* pWin = wxFindWinFromHandle(hControl);
1297
1298 if (pWin)
1299 return pWin->OS2Command( nCmd
1300 ,nId
1301 );
1302 }
1303
1304 //
1305 // Handle here commands from menus and accelerators
1306 //
1307 if (nCmd == 0 || nCmd == 1)
1308 {
1309 if (wxCurrentPopupMenu)
1310 {
1311 wxMenu* pPopupMenu = wxCurrentPopupMenu;
1312
1313 wxCurrentPopupMenu = NULL;
1314
1315 return pPopupMenu->OS2Command( nCmd
1316 ,nId
1317 );
1318 }
1319
1320 if (ProcessCommand(nId))
1321 {
1322 return TRUE;
1323 }
1324 }
1325 return FALSE;
1326 } // end of wxFrame::HandleCommand
1327
1328 bool wxFrame::HandleMenuSelect(
1329 WXWORD nItem
1330 , WXWORD nFlags
1331 , WXHMENU hMenu
1332 )
1333 {
1334 int nMenuItem;
1335
1336 if (nFlags == 0xFFFF && hMenu == 0)
1337 {
1338 //
1339 // Menu was removed from screen
1340 //
1341 nMenuItem = -1;
1342 }
1343 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1344 {
1345 nMenuItem = nItem;
1346 }
1347 else
1348 {
1349 //
1350 // Don't give hints for separators (doesn't make sense) nor for the
1351 // items opening popup menus (they don't have them anyhow)
1352 //
1353 return FALSE;
1354 }
1355 wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nMenuItem);
1356
1357 vEvent.SetEventObject(this);
1358 return GetEventHandler()->ProcessEvent(vEvent);
1359 } // end of wxFrame::HandleMenuSelect
1360
1361 // ---------------------------------------------------------------------------
1362 // the window proc for wxFrame
1363 // ---------------------------------------------------------------------------
1364
1365 MRESULT wxFrame::OS2WindowProc(
1366 WXUINT uMessage
1367 , WXWPARAM wParam
1368 , WXLPARAM lParam
1369 )
1370 {
1371 MRESULT mRc = 0L;
1372 bool bProcessed = FALSE;
1373
1374 switch (uMessage)
1375 {
1376 case WM_CLOSE:
1377 //
1378 // If we can't close, tell the system that we processed the
1379 // message - otherwise it would close us
1380 //
1381 bProcessed = !Close();
1382 break;
1383
1384 case WM_COMMAND:
1385 {
1386 WORD wId;
1387 WORD wCmd;
1388 WXHWND hWnd;
1389
1390 UnpackCommand( (WXWPARAM)wParam
1391 ,(WXLPARAM)lParam
1392 ,&wId
1393 ,&hWnd
1394 ,&wCmd
1395 );
1396 bProcessed = HandleCommand( wId
1397 ,wCmd
1398 ,(WXHWND)hWnd
1399 );
1400 }
1401 break;
1402
1403 case WM_MENUSELECT:
1404 {
1405 WXWORD wItem;
1406 WXWORD wFlags;
1407 WXHMENU hMenu;
1408
1409 UnpackMenuSelect( wParam
1410 ,lParam
1411 ,&wItem
1412 ,&wFlags
1413 ,&hMenu
1414 );
1415 bProcessed = HandleMenuSelect( wItem
1416 ,wFlags
1417 ,hMenu
1418 );
1419 }
1420 break;
1421
1422 case WM_PAINT:
1423 bProcessed = HandlePaint();
1424 break;
1425
1426 case WM_ERASEBACKGROUND:
1427 //
1428 // Return TRUE to request PM to paint the window background
1429 // in SYSCLR_WINDOW.
1430 //
1431 bProcessed = TRUE;
1432 mRc = (MRESULT)(TRUE);
1433 break;
1434
1435 case CM_QUERYDRAGIMAGE:
1436 {
1437 HPOINTER hIcon;
1438
1439 if (m_icon.Ok())
1440 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
1441 else
1442 hIcon = (HPOINTER)m_hDefaultIcon;
1443 mRc = (MRESULT)hIcon;
1444 bProcessed = mRc != 0;
1445 }
1446 break;
1447
1448 case WM_SIZE:
1449 bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1450 break;
1451 }
1452
1453 if (!bProcessed )
1454 mRc = wxWindow::OS2WindowProc( uMessage
1455 ,wParam
1456 ,lParam
1457 );
1458 return (MRESULT)0;
1459 } // wxFrame::OS2WindowProc
1460