no message
[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[10];
808 RECTL vRect[10];
809 USHORT uCtlCount;
810
811 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
812
813 if (pParent)
814 hParent = GetWinHwnd(pParent);
815 else
816 hParent = HWND_DESKTOP;
817
818 if (ulStyle == wxDEFAULT_FRAME_STYLE)
819 ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
820 FCF_MINMAX | FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_TASKLIST;
821 else
822 {
823 if ((ulStyle & wxCAPTION) == wxCAPTION)
824 ulCreateFlags = FCF_TASKLIST;
825 else
826 ulCreateFlags = FCF_NOMOVEWITHOWNER;
827
828 if (ulStyle & wxMINIMIZE_BOX)
829 ulCreateFlags |= FCF_MINBUTTON;
830 if (ulStyle & wxMAXIMIZE_BOX)
831 ulCreateFlags |= FCF_MAXBUTTON;
832 if (ulStyle & wxTHICK_FRAME)
833 ulCreateFlags |= FCF_DLGBORDER;
834 if (ulStyle & wxSYSTEM_MENU)
835 ulCreateFlags |= FCF_SYSMENU;
836 if (ulStyle & wxCAPTION)
837 ulCreateFlags |= FCF_TASKLIST;
838 if (ulStyle & wxCLIP_CHILDREN)
839 {
840 // Invalid for frame windows under PM
841 }
842
843 if (ulStyle & wxTINY_CAPTION_VERT)
844 ulCreateFlags |= FCF_TASKLIST;
845 if (ulStyle & wxTINY_CAPTION_HORIZ)
846 ulCreateFlags |= FCF_TASKLIST;
847
848 if ((ulStyle & wxTHICK_FRAME) == 0)
849 ulCreateFlags |= FCF_BORDER;
850 if (ulStyle & wxFRAME_TOOL_WINDOW)
851 ulExtraFlags = kFrameToolWindow;
852
853 if (ulStyle & wxSTAY_ON_TOP)
854 ulCreateFlags |= FCF_SYSMODAL;
855 }
856 if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
857 ulStyleFlags |= WS_MINIMIZED;
858 if (ulStyle & wxMAXIMIZE)
859 ulStyleFlags |= WS_MAXIMIZED;
860
861 //
862 // Clear the visible flag, we always call show
863 //
864 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
865 m_bIconized = FALSE;
866
867 //
868 // Set the frame control block
869 //
870 vFrameCtlData.cb = sizeof(vFrameCtlData);
871 vFrameCtlData.flCreateFlags = ulCreateFlags;
872 vFrameCtlData.hmodResources = 0L;
873 vFrameCtlData.idResources = 0;
874
875 //
876 // Create the frame window
877 //
878 if ((m_hFrame = ::WinCreateWindow( hParent // Frame is parent
879 ,WC_FRAME // standard frame class
880 ,(PSZ)zTitle // Window title
881 ,0 // No styles
882 ,0, 0, 0, 0 // Window position
883 ,NULLHANDLE // Owner
884 ,HWND_TOP // Sibling
885 ,(ULONG)nId // ID
886 ,(PVOID)&vFrameCtlData // Creation data
887 ,NULL // Window Pres Params
888 )) == 0L)
889 {
890 return FALSE;
891 }
892
893 if (!wxWindow::OS2Create( m_hFrame
894 ,wxFrameClassName
895 ,NULL
896 ,0L
897 ,0L
898 ,0L
899 ,0L
900 ,0L
901 ,NULLHANDLE
902 ,HWND_TOP
903 ,(unsigned long)FID_CLIENT
904 ,NULL
905 ,NULL
906 ))
907 {
908 return FALSE;
909 }
910
911 //
912 // Now size everything. If adding a menu the client will need to be resized.
913 //
914 if (!::WinSetWindowPos( m_hFrame
915 ,HWND_TOP
916 ,nX
917 ,nY
918 ,nWidth
919 ,nHeight
920 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
921 ))
922 return FALSE;
923
924 uCtlCount = SHORT1FROMMP(::WinSendMsg(m_hFrame, WM_FORMATFRAME, (MPARAM)vSwp, (MPARAM)vRect));
925 for (int i = 0; i < uCtlCount; i++)
926 {
927 if (vSwp[i].hwnd == m_hFrame)
928 memcpy(&m_vSwp, &vSwp[i], sizeof(SWP));
929 else if (vSwp[i].hwnd == m_hVScroll)
930 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
931 else if (vSwp[i].hwnd == m_hHScroll)
932 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
933 else if (vSwp[i].hwnd == m_hTitleBar)
934 memcpy(&m_vSwpTitleBar, &vSwp[i], sizeof(SWP));
935 }
936
937 //
938 // Now set the size of the client
939 //
940 WinSetWindowPos( hClient
941 ,HWND_TOP
942 ,SV_CXSIZEBORDER/2
943 ,(SV_CYSIZEBORDER/2) + m_vSwpHScroll.cy/2
944 ,m_vSwp.cx - ((SV_CXSIZEBORDER + 1) + m_vSwpVScroll.cx)
945 ,m_vSwp.cy - ((SV_CYSIZEBORDER + 1) + m_vSwpTitleBar.cy + m_vSwpHScroll.cy/2)
946 ,SWP_SIZE | SWP_MOVE
947 );
948
949 //
950 // Set the client window's background, otherwise it is transparent!
951 //
952 return TRUE;
953 } // end of wxFrame::OS2Create
954
955 //
956 // Default activation behaviour - set the focus for the first child
957 // subwindow found.
958 //
959 void wxFrame::OnActivate(
960 wxActivateEvent& rEvent
961 )
962 {
963 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
964 pNode;
965 pNode = pNode->GetNext())
966 {
967 // FIXME all this is totally bogus - we need to do the same as wxPanel,
968 // but how to do it without duplicating the code?
969
970 // restore focus
971 wxWindow* pChild = pNode->GetData();
972
973 if (!pChild->IsTopLevel()
974 #if wxUSE_TOOLBAR
975 && !wxDynamicCast(pChild, wxToolBar)
976 #endif // wxUSE_TOOLBAR
977 #if wxUSE_STATUSBAR
978 && !wxDynamicCast(pChild, wxStatusBar)
979 #endif // wxUSE_STATUSBAR
980 )
981 {
982 pChild->SetFocus();
983 return;
984 }
985 }
986 } // end of wxFrame::OnActivate
987
988 // ----------------------------------------------------------------------------
989 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
990 // from the client area, so the client area is what's really available for the
991 // frame contents
992 // ----------------------------------------------------------------------------
993
994 // Checks if there is a toolbar, and returns the first free client position
995 wxPoint wxFrame::GetClientAreaOrigin() const
996 {
997 wxPoint vPoint(0, 0);
998
999 if (GetToolBar())
1000 {
1001 int nWidth;
1002 int nHeight;
1003
1004 GetToolBar()->GetSize( &nWidth
1005 ,&nHeight
1006 );
1007
1008 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1009 {
1010 vPoint.x += nWidth;
1011 }
1012 else
1013 {
1014 // PM is backwards from windows
1015 vPoint.y += nHeight;
1016 }
1017 }
1018 return vPoint;
1019 } // end of wxFrame::GetClientAreaOrigin
1020
1021 // ----------------------------------------------------------------------------
1022 // tool/status bar stuff
1023 // ----------------------------------------------------------------------------
1024
1025 #if wxUSE_TOOLBAR
1026
1027 wxToolBar* wxFrame::CreateToolBar(
1028 long lStyle
1029 , wxWindowID vId
1030 , const wxString& rName
1031 )
1032 {
1033 if (wxFrameBase::CreateToolBar( lStyle
1034 ,vId
1035 ,rName
1036 ))
1037 {
1038 PositionToolBar();
1039 }
1040 return m_frameToolBar;
1041 } // end of wxFrame::CreateToolBar
1042
1043 void wxFrame::PositionToolBar()
1044 {
1045 HWND hWndClient;
1046 RECTL vRect;
1047
1048 ::WinQueryWindowRect(GetHwnd(), &vRect);
1049
1050 #if wxUSE_STATUSBAR
1051 if (GetStatusBar())
1052 {
1053 int nStatusX;
1054 int nStatusY;
1055
1056 GetStatusBar()->GetClientSize( &nStatusX
1057 ,&nStatusY
1058 );
1059 // PM is backwards from windows
1060 vRect.yBottom += nStatusY;
1061 }
1062 #endif // wxUSE_STATUSBAR
1063
1064 if ( GetToolBar() )
1065 {
1066 int nToolbarWidth;
1067 int nToolbarHeight;
1068
1069 GetToolBar()->GetSize( &nToolbarWidth
1070 ,&nToolbarHeight
1071 );
1072
1073 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1074 {
1075 nToolbarHeight = vRect.yBottom;
1076 }
1077 else
1078 {
1079 nToolbarWidth = vRect.xRight;
1080 }
1081
1082 //
1083 // Use the 'real' PM position here
1084 //
1085 GetToolBar()->SetSize( 0
1086 ,0
1087 ,nToolbarWidth
1088 ,nToolbarHeight
1089 ,wxSIZE_NO_ADJUSTMENTS
1090 );
1091 }
1092 } // end of wxFrame::PositionToolBar
1093 #endif // wxUSE_TOOLBAR
1094
1095 // ----------------------------------------------------------------------------
1096 // frame state (iconized/maximized/...)
1097 // ----------------------------------------------------------------------------
1098
1099 //
1100 // propagate our state change to all child frames: this allows us to emulate X
1101 // Windows behaviour where child frames float independently of the parent one
1102 // on the desktop, but are iconized/restored with it
1103 //
1104 void wxFrame::IconizeChildFrames(
1105 bool bIconize
1106 )
1107 {
1108 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1109 pNode;
1110 pNode = pNode->GetNext() )
1111 {
1112 wxWindow* pWin = pNode->GetData();
1113
1114 if (pWin->IsKindOf(CLASSINFO(wxFrame)) )
1115 {
1116 ((wxFrame *)pWin)->Iconize(bIconize);
1117 }
1118 }
1119 } // end of wxFrame::IconizeChildFrames
1120
1121 // ===========================================================================
1122 // message processing
1123 // ===========================================================================
1124
1125 // ---------------------------------------------------------------------------
1126 // preprocessing
1127 // ---------------------------------------------------------------------------
1128 bool wxFrame::OS2TranslateMessage(
1129 WXMSG* pMsg
1130 )
1131 {
1132 if (wxWindow::OS2TranslateMessage(pMsg))
1133 return TRUE;
1134 //
1135 // try the menu bar accels
1136 //
1137 wxMenuBar* pMenuBar = GetMenuBar();
1138
1139 if (!pMenuBar )
1140 return FALSE;
1141
1142 const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
1143 return rAcceleratorTable.Translate(this, pMsg);
1144 } // end of wxFrame::OS2TranslateMessage
1145
1146 // ---------------------------------------------------------------------------
1147 // our private (non virtual) message handlers
1148 // ---------------------------------------------------------------------------
1149 bool wxFrame::HandlePaint()
1150 {
1151 RECTL vRect;
1152
1153 if (::WinQueryUpdateRect(m_hFrame, &vRect))
1154 {
1155 if (m_bIconized)
1156 {
1157 //
1158 // Icons in PM are the same as "pointers"
1159 //
1160 HPOINTER hIcon;
1161
1162 if (m_icon.Ok())
1163 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
1164 else
1165 hIcon = (HPOINTER)m_hDefaultIcon;
1166
1167 //
1168 // Hold a pointer to the dc so long as the OnPaint() message
1169 // is being processed
1170 //
1171 RECTL vRect2;
1172 HPS hPs = ::WinBeginPaint(m_hFrame, NULLHANDLE, &vRect2);
1173
1174 //
1175 // Erase background before painting or we get white background
1176 //
1177 OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
1178
1179 if (hIcon)
1180 {
1181 HWND hWndClient;
1182 RECTL vRect3;
1183
1184 ::WinQueryWindowRect(GetHwnd(), &vRect3);
1185
1186 static const int nIconWidth = 32;
1187 static const int nIconHeight = 32;
1188 int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
1189 int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
1190
1191 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
1192 }
1193 ::WinEndPaint(hPs);
1194 return TRUE;
1195 }
1196 else
1197 {
1198 return wxWindow::HandlePaint();
1199 }
1200 }
1201 else
1202 {
1203 // nothing to paint - processed
1204 return TRUE;
1205 }
1206 return FALSE;
1207 } // end of wxFrame::HandlePaint
1208
1209 bool wxFrame::HandleSize(
1210 int nX
1211 , int nY
1212 , WXUINT nId
1213 )
1214 {
1215 bool bProcessed = FALSE;
1216
1217 switch (nId)
1218 {
1219 case kSizeNormal:
1220 //
1221 // Only do it it if we were iconized before, otherwise resizing the
1222 // parent frame has a curious side effect of bringing it under it's
1223 // children
1224 if (!m_bIconized )
1225 break;
1226
1227 //
1228 // restore all child frames too
1229 //
1230 IconizeChildFrames(FALSE);
1231
1232 //
1233 // fall through
1234 //
1235
1236 case kSizeMax:
1237 m_bIconized = FALSE;
1238 break;
1239
1240 case kSizeMin:
1241 //
1242 // Iconize all child frames too
1243 //
1244 IconizeChildFrames(TRUE);
1245 m_bIconized = TRUE;
1246 break;
1247 }
1248
1249 if (!m_bIconized)
1250 {
1251 //
1252 // forward WM_SIZE to status bar control
1253 //
1254 #if wxUSE_NATIVE_STATUSBAR
1255 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
1256 {
1257 wxSizeEvent vEvent( wxSize( nX
1258 ,nY
1259 )
1260 ,m_frameStatusBar->GetId()
1261 );
1262
1263 vEvent.SetEventObject(m_frameStatusBar);
1264 m_frameStatusBar->OnSize(vEvent);
1265 }
1266 #endif // wxUSE_NATIVE_STATUSBAR
1267
1268 PositionStatusBar();
1269 PositionToolBar();
1270 wxSizeEvent vEvent( wxSize( nX
1271 ,nY
1272 )
1273 ,m_windowId
1274 );
1275
1276 vEvent.SetEventObject(this);
1277 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
1278 }
1279 return bProcessed;
1280 } // end of wxFrame::HandleSize
1281
1282 bool wxFrame::HandleCommand(
1283 WXWORD nId
1284 , WXWORD nCmd
1285 , WXHWND hControl
1286 )
1287 {
1288 if (hControl)
1289 {
1290 //
1291 // In case it's e.g. a toolbar.
1292 //
1293 wxWindow* pWin = wxFindWinFromHandle(hControl);
1294
1295 if (pWin)
1296 return pWin->OS2Command( nCmd
1297 ,nId
1298 );
1299 }
1300
1301 //
1302 // Handle here commands from menus and accelerators
1303 //
1304 if (nCmd == 0 || nCmd == 1)
1305 {
1306 if (wxCurrentPopupMenu)
1307 {
1308 wxMenu* pPopupMenu = wxCurrentPopupMenu;
1309
1310 wxCurrentPopupMenu = NULL;
1311
1312 return pPopupMenu->OS2Command( nCmd
1313 ,nId
1314 );
1315 }
1316
1317 if (ProcessCommand(nId))
1318 {
1319 return TRUE;
1320 }
1321 }
1322 return FALSE;
1323 } // end of wxFrame::HandleCommand
1324
1325 bool wxFrame::HandleMenuSelect(
1326 WXWORD nItem
1327 , WXWORD nFlags
1328 , WXHMENU hMenu
1329 )
1330 {
1331 int nMenuItem;
1332
1333 if (nFlags == 0xFFFF && hMenu == 0)
1334 {
1335 //
1336 // Menu was removed from screen
1337 //
1338 nMenuItem = -1;
1339 }
1340 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1341 {
1342 nMenuItem = nItem;
1343 }
1344 else
1345 {
1346 //
1347 // Don't give hints for separators (doesn't make sense) nor for the
1348 // items opening popup menus (they don't have them anyhow)
1349 //
1350 return FALSE;
1351 }
1352 wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nMenuItem);
1353
1354 vEvent.SetEventObject(this);
1355 return GetEventHandler()->ProcessEvent(vEvent);
1356 } // end of wxFrame::HandleMenuSelect
1357
1358 // ---------------------------------------------------------------------------
1359 // the window proc for wxFrame
1360 // ---------------------------------------------------------------------------
1361
1362 MRESULT wxFrame::OS2WindowProc(
1363 WXUINT uMessage
1364 , WXWPARAM wParam
1365 , WXLPARAM lParam
1366 )
1367 {
1368 MRESULT mRc = 0L;
1369 bool bProcessed = FALSE;
1370
1371 switch (uMessage)
1372 {
1373 case WM_CLOSE:
1374 //
1375 // If we can't close, tell the system that we processed the
1376 // message - otherwise it would close us
1377 //
1378 bProcessed = !Close();
1379 break;
1380
1381 case WM_COMMAND:
1382 {
1383 WORD wId;
1384 WORD wCmd;
1385 WXHWND hWnd;
1386
1387 UnpackCommand( (WXWPARAM)wParam
1388 ,(WXLPARAM)lParam
1389 ,&wId
1390 ,&hWnd
1391 ,&wCmd
1392 );
1393 bProcessed = HandleCommand( wId
1394 ,wCmd
1395 ,(WXHWND)hWnd
1396 );
1397 }
1398 break;
1399
1400 case WM_MENUSELECT:
1401 {
1402 WXWORD wItem;
1403 WXWORD wFlags;
1404 WXHMENU hMenu;
1405
1406 UnpackMenuSelect( wParam
1407 ,lParam
1408 ,&wItem
1409 ,&wFlags
1410 ,&hMenu
1411 );
1412 bProcessed = HandleMenuSelect( wItem
1413 ,wFlags
1414 ,hMenu
1415 );
1416 }
1417 break;
1418
1419 case WM_PAINT:
1420 bProcessed = HandlePaint();
1421 break;
1422
1423 case WM_ERASEBACKGROUND:
1424 //
1425 // Return TRUE to request PM to paint the window background
1426 // in SYSCLR_WINDOW.
1427 //
1428 bProcessed = TRUE;
1429 mRc = (MRESULT)(TRUE);
1430 break;
1431
1432 case CM_QUERYDRAGIMAGE:
1433 {
1434 HPOINTER hIcon;
1435
1436 if (m_icon.Ok())
1437 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
1438 else
1439 hIcon = (HPOINTER)m_hDefaultIcon;
1440 mRc = (MRESULT)hIcon;
1441 bProcessed = mRc != 0;
1442 }
1443 break;
1444
1445 case WM_SIZE:
1446 bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1447 break;
1448 }
1449
1450 if (!bProcessed )
1451 mRc = wxWindow::OS2WindowProc( uMessage
1452 ,wParam
1453 ,lParam
1454 );
1455 return (MRESULT)0;
1456 } // wxFrame::OS2WindowProc
1457