1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
21 #include "wx/dialog.h"
22 #include "wx/settings.h"
23 #include "wx/dcclient.h"
26 #include "wx/os2/private.h"
29 #include "wx/statusbr.h"
30 #include "wx/generic/statusbr.h"
31 #endif // wxUSE_STATUSBAR
34 #include "wx/toolbar.h"
35 #endif // wxUSE_TOOLBAR
37 #include "wx/menuitem.h"
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 extern wxWindowList wxModelessWindows
;
45 extern wxList WXDLLEXPORT wxPendingDelete
;
46 extern wxChar wxFrameClassName
[];
47 extern wxMenu
*wxCurrentPopupMenu
;
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
)
54 EVT_ACTIVATE(wxFrame::OnActivate
)
55 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
)
58 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
60 // ============================================================================
62 // ============================================================================
64 // ----------------------------------------------------------------------------
65 // static class members
66 // ----------------------------------------------------------------------------
68 #if wxUSE_NATIVE_STATUSBAR
69 bool wxFrame::m_bUseNativeStatusBar
= TRUE
;
71 bool wxFrame::m_bUseNativeStatusBar
= FALSE
;
74 // ----------------------------------------------------------------------------
75 // creation/destruction
76 // ----------------------------------------------------------------------------
85 // Data to save/restore when calling ShowFullScreen
87 m_lFsOldWindowStyle
= 0L;
88 m_nFsStatusBarFields
= 0;
89 m_nFsStatusBarHeight
= 0;
90 m_nFsToolBarHeight
= 0;
91 m_bFsIsMaximized
= FALSE
;
92 m_bFsIsShowing
= FALSE
;
94 m_pWinLastFocused
= (wxWindow
*)NULL
;
99 memset(&m_vSwp
, 0, sizeof(SWP
));
100 memset(&m_vSwpClient
, 0, sizeof(SWP
));
101 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
102 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
103 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
104 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
105 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
106 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
107 } // end of wxFrame::Init
109 bool wxFrame::Create(
112 , const wxString
& rsTitle
113 , const wxPoint
& rPos
114 , const wxSize
& rSize
116 , const wxString
& rsName
121 int nWidth
= rSize
.x
;
122 int nHeight
= rSize
.y
;
125 m_windowStyle
= lulStyle
;
126 m_frameMenuBar
= NULL
;
127 m_frameToolBar
= NULL
;
128 m_frameStatusBar
= NULL
;
130 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
135 m_windowId
= (int)NewControlId();
138 pParent
->AddChild(this);
142 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
146 wxTopLevelWindows
.Append(this);
148 OS2Create( m_windowId
160 wxModelessWindows
.Append(this);
162 } // end of wxFrame::Create
166 m_isBeingDeleted
= TRUE
;
167 wxTopLevelWindows
.DeleteObject(this);
171 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
173 wxTheApp
->SetTopWindow(NULL
);
175 if (wxTheApp
->GetExitOnFrameDelete())
177 ::WinPostMsg(m_hFrame
, WM_QUIT
, 0, 0);
180 wxModelessWindows
.DeleteObject(this);
183 // For some reason, wxWindows can activate another task altogether
184 // when a frame is destroyed after a modal dialog has been invoked.
185 // Try to bring the parent to the top.
187 // MT:Only do this if this frame is currently the active window, else weird
188 // things start to happen.
190 if (wxGetActiveWindow() == this)
192 if (GetParent() && GetParent()->GetHWND())
194 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
204 } // end of wxFrame::~wxFrame
207 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
209 void wxFrame::DoGetClientSize(
215 // OS/2 PM's coordinates go from bottom-left not
216 // top-left thus the += instead of the -=
221 // PM has no GetClientRect that inherantly knows about the client window
222 // We have to explicitly go fetch it!
224 ::WinQueryWindowRect(GetHwnd(), &vRect
);
227 if ( GetStatusBar() )
232 GetStatusBar()->GetClientSize( &nStatusX
235 vRect
.yBottom
+= nStatusY
;
237 #endif // wxUSE_STATUSBAR
239 wxPoint
vPoint(GetClientAreaOrigin());
241 vRect
.yBottom
+= vPoint
.y
;
242 vRect
.xRight
-= vPoint
.x
;
248 } // end of wxFrame::DoGetClientSize
251 // Set the client size (i.e. leave the calculation of borders etc.
254 void wxFrame::DoSetClientSize(
259 HWND hWnd
= GetHwnd();
263 ::WinQueryWindowRect(GetHwnd(), &vRect
);
265 ::WinQueryWindowRect(m_hFrame
, &vRect2
);
268 // Find the difference between the entire window (title bar and all)
269 // and the client area; add this to the new client size to move the
270 // window. Remember OS/2's backwards y coord system!
272 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
273 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
276 if ( GetStatusBar() )
281 GetStatusBar()->GetClientSize( &nStatusX
284 nActualHeight
+= nStatusY
;
286 #endif // wxUSE_STATUSBAR
288 wxPoint
vPoint(GetClientAreaOrigin());
289 nActualWidth
+= vPoint
.y
;
290 nActualHeight
+= vPoint
.x
;
294 vPointl
.x
= vRect2
.xLeft
;
295 vPointl
.y
= vRect2
.yTop
;
297 ::WinSetWindowPos( hWnd
303 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
306 wxSizeEvent
vEvent( wxSize( nWidth
311 vEvent
.SetEventObject(this);
312 GetEventHandler()->ProcessEvent(vEvent
);
313 } // end of wxFrame::DoSetClientSize
315 void wxFrame::DoGetSize(
322 ::WinQueryWindowRect(m_hFrame
, &vRect
);
323 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
324 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
325 } // end of wxFrame::DoGetSize
327 void wxFrame::DoGetPosition(
335 ::WinQueryWindowRect(m_hFrame
, &vRect
);
336 vPoint
.x
= vRect
.xLeft
;
339 // OS/2 is backwards [WIN32 it is vRect.yTop]
341 vPoint
.y
= vRect
.yBottom
;
345 } // end of wxFrame::DoGetPosition
347 // ----------------------------------------------------------------------------
348 // variations around ::ShowWindow()
349 // ----------------------------------------------------------------------------
351 void wxFrame::DoShowWindow(
355 ::WinShowWindow(m_hFrame
, (BOOL
)bShowCmd
);
356 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
357 } // end of wxFrame::DoShowWindow
365 DoShowWindow((int)bShow
);
369 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
371 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
372 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
373 ::WinEnableWindow(m_hFrame
, TRUE
);
374 vEvent
.SetEventObject(this);
375 GetEventHandler()->ProcessEvent(vEvent
);
380 // Try to highlight the correct window (the parent)
384 HWND hWndParent
= GetHwndOf(GetParent());
386 ::WinQueryWindowPos(hWndParent
, &vSwp
);
387 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
389 ::WinSetWindowPos( hWndParent
395 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
397 ::WinEnableWindow(hWndParent
, TRUE
);
401 } // end of wxFrame::Show
403 void wxFrame::Iconize(
407 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
408 } // end of wxFrame::Iconize
410 void wxFrame::Maximize(
413 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
414 } // end of wxFrame::Maximize
416 void wxFrame::Restore()
418 DoShowWindow(SWP_RESTORE
);
419 } // end of wxFrame::Restore
421 bool wxFrame::IsIconized() const
425 ::WinQueryWindowPos(GetHwnd(), &vSwp
);
427 if (vSwp
.fl
& SWP_MINIMIZE
)
428 ((wxFrame
*)this)->m_bIconized
= TRUE
;
430 ((wxFrame
*)this)->m_bIconized
= FALSE
;
432 } // end of wxFrame::IsIconized
435 bool wxFrame::IsMaximized() const
440 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
441 return (vSwp
.fl
& SWP_MAXIMIZE
);
442 } // end of wxFrame::IsMaximized
444 void wxFrame::SetIcon(
448 wxFrameBase::SetIcon(rIcon
);
450 if ((m_icon
.GetHICON()) != NULLHANDLE
)
452 ::WinSendMsg( m_hFrame
454 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
457 ::WinSendMsg( m_hFrame
463 } // end of wxFrame::SetIcon
466 wxStatusBar
* wxFrame::OnCreateStatusBar(
470 , const wxString
& rName
473 wxStatusBar
* pStatusBar
= NULL
;
479 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
485 // The default parent set for the Statusbar is m_hWnd which, of course,
486 // is the handle to the client window of the frame. We don't want that,
487 // so we have to set the parent to actually be the Frame.
489 hWnd
= pStatusBar
->GetHWND();
490 if (!::WinSetParent(hWnd
, m_hFrame
, FALSE
))
492 vError
= ::WinGetLastError(vHabmain
);
493 sError
= wxPMErrorToStr(vError
);
494 wxLogError("Error setting parent for statusbar. Error: %s\n", sError
);
499 // Also we need to reset it positioning to enable the SHOW attribute
501 if (!::WinQueryWindowPos((HWND
)pStatusBar
->GetHWND(), &vSwp
))
503 vError
= ::WinGetLastError(vHabmain
);
504 sError
= wxPMErrorToStr(vError
);
505 wxLogError("Error querying frame for statusbar position. Error: %s\n", sError
);
508 if (!::WinSetWindowPos( (HWND
)pStatusBar
->GetHWND()
514 ,SWP_SIZE
| SWP_MOVE
| SWP_SHOW
| SWP_ZORDER
517 vError
= ::WinGetLastError(vHabmain
);
518 sError
= wxPMErrorToStr(vError
);
519 wxLogError("Error setting statusbar position. Error: %s\n", sError
);
523 } // end of wxFrame::OnCreateStatusBar
525 void wxFrame::PositionStatusBar()
532 // Native status bar positions itself
534 if (m_frameStatusBar
)
543 ::WinQueryWindowRect(GetHwnd(), &vRect
);
544 nWidth
= vRect
.xRight
- vRect
.xLeft
;
545 nHeight
= vRect
.yTop
- vRect
.yBottom
;
547 m_frameStatusBar
->GetSize( &nStatbarWidth
552 // Since we wish the status bar to be directly under the client area,
553 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
555 m_frameStatusBar
->SetSize( 0
560 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
562 vError
= ::WinGetLastError(vHabmain
);
563 sError
= wxPMErrorToStr(vError
);
564 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
567 if (!::WinSetWindowPos( m_frameStatusBar
->GetHWND()
573 ,SWP_SIZE
| SWP_MOVE
| SWP_SHOW
| SWP_ZORDER
576 vError
= ::WinGetLastError(vHabmain
);
577 sError
= wxPMErrorToStr(vError
);
578 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
582 } // end of wxFrame::PositionStatusBar
583 #endif // wxUSE_STATUSBAR
585 void wxFrame::DetachMenuBar()
589 m_frameMenuBar
->Detach();
590 m_frameMenuBar
= NULL
;
592 } // end of wxFrame::DetachMenuBar
594 void wxFrame::SetMenuBar(
600 HWND hClient
= NULLHANDLE
;
601 HWND hFrame
= NULLHANDLE
;
602 HWND hTitlebar
= NULLHANDLE
;
603 HWND hHScroll
= NULLHANDLE
;
604 HWND hVScroll
= NULLHANDLE
;
605 HWND hMenuBar
= NULLHANDLE
;
617 // Actually remove the menu from the frame
619 m_hMenu
= (WXHMENU
)0;
620 InternalSetMenuBar();
622 else // set new non NULL menu bar
624 m_frameMenuBar
= NULL
;
627 // Can set a menubar several times.
628 // TODO: how to prevent a memory leak if you have a currently-unattached
629 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
630 // there are problems for MDI).
632 if (pMenuBar
->GetHMenu())
634 m_hMenu
= pMenuBar
->GetHMenu();
639 m_hMenu
= pMenuBar
->Create();
643 InternalSetMenuBar();
644 m_frameMenuBar
= pMenuBar
;
645 pMenuBar
->Attach(this);
649 // Now resize the client to fit the new frame
651 WinQueryWindowPos(m_hFrame
, &vSwp
);
652 hTitlebar
= WinWindowFromID(m_hFrame
, FID_TITLEBAR
);
653 WinQueryWindowPos(hTitlebar
, &vSwpTitlebar
);
654 hHScroll
= WinWindowFromID(m_hFrame
, FID_HORZSCROLL
);
655 WinQueryWindowPos(hHScroll
, &vSwpHScroll
);
656 hVScroll
= WinWindowFromID(m_hFrame
, FID_VERTSCROLL
);
657 WinQueryWindowPos(hVScroll
, &vSwpVScroll
);
658 hMenuBar
= WinWindowFromID(m_hFrame
, FID_MENU
);
659 WinQueryWindowPos(hMenuBar
, &vSwpMenu
);
660 WinSetWindowPos( GetHwnd()
663 ,(SV_CYSIZEBORDER
/2) + vSwpHScroll
.cy
/2
664 ,vSwp
.cx
- ((SV_CXSIZEBORDER
+ 1) + vSwpVScroll
.cx
)
665 ,vSwp
.cy
- ((SV_CYSIZEBORDER
+ 1) + vSwpTitlebar
.cy
+ vSwpMenu
.cy
+ vSwpHScroll
.cy
/2)
668 } // end of wxFrame::SetMenuBar
670 void wxFrame::InternalSetMenuBar()
675 // Set the parent and owner of the menubar to be the frame
677 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
679 vError
= ::WinGetLastError(vHabmain
);
680 sError
= wxPMErrorToStr(vError
);
681 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
684 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
686 vError
= ::WinGetLastError(vHabmain
);
687 sError
= wxPMErrorToStr(vError
);
688 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
690 WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
691 } // end of wxFrame::InternalSetMenuBar
694 // Responds to colour changes, and passes event on to children
696 void wxFrame::OnSysColourChanged(
697 wxSysColourChangedEvent
& rEvent
700 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
703 if (m_frameStatusBar
)
705 wxSysColourChangedEvent vEvent2
;
707 vEvent2
.SetEventObject(m_frameStatusBar
);
708 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
712 // Propagate the event to the non-top-level children
714 wxWindow::OnSysColourChanged(rEvent
);
715 } // end of wxFrame::OnSysColourChanged
717 // Pass TRUE to show full screen, FALSE to restore.
718 bool wxFrame::ShowFullScreen(
728 m_bFsIsShowing
= TRUE
;
731 wxToolBar
* pTheToolBar
= GetToolBar();
732 wxStatusBar
* pTheStatusBar
= GetStatusBar();
737 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
739 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
742 // Zap the toolbar, menubar, and statusbar
744 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
746 pTheToolBar
->SetSize(-1,0);
747 pTheToolBar
->Show(FALSE
);
750 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
752 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
753 ::WinSetOwner(m_hMenu
, m_hFrame
);
754 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
758 // Save the number of fields in the statusbar
760 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
762 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
763 SetStatusBar((wxStatusBar
*) NULL
);
764 delete pTheStatusBar
;
767 m_nFsStatusBarFields
= 0;
770 // Zap the frame borders
774 // Save the 'normal' window style
776 m_lFsOldWindowStyle
= ::WinQueryWindowULong((HWND
)GetHWND(), QWL_STYLE
);
779 // Save the old position, width & height, maximize state
781 m_vFsOldSize
= GetRect();
782 m_bFsIsMaximized
= IsMaximized();
785 // Decide which window style flags to turn off
787 LONG lNewStyle
= m_lFsOldWindowStyle
;
790 if (lStyle
& wxFULLSCREEN_NOBORDER
)
791 lOffFlags
|= FCF_BORDER
;
792 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
793 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
795 lNewStyle
&= (~lOffFlags
);
798 // Change our window style to be compatible with full-screen mode
800 ::WinSetWindowULong((HWND
)GetHWND(), QWL_STYLE
, (ULONG
)lNewStyle
);
803 // Resize to the size of the desktop
809 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
810 nWidth
= vRect
.xRight
- vRect
.xLeft
;
812 // Rmember OS/2 is backwards!
814 nHeight
= vRect
.yTop
- vRect
.yBottom
;
821 // Now flush the window style cache and actually go full-screen
823 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
832 wxSizeEvent
vEvent( wxSize( nWidth
838 GetEventHandler()->ProcessEvent(vEvent
);
846 m_bFsIsShowing
= FALSE
;
848 wxToolBar
* pTheToolBar
= GetToolBar();
851 // Restore the toolbar, menubar, and statusbar
853 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
855 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
856 pTheToolBar
->Show(TRUE
);
859 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
861 CreateStatusBar(m_nFsStatusBarFields
);
865 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
867 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
868 ::WinSetOwner(m_hMenu
, m_hFrame
);
869 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
871 Maximize(m_bFsIsMaximized
);
873 ::WinSetWindowULong( (HWND
)GetHWND()
875 ,(ULONG
)m_lFsOldWindowStyle
877 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
887 } // end of wxFrame::ShowFullScreen
892 bool wxFrame::OS2Create(
895 , const wxChar
* zWclass
897 , const wxChar
* zTitle
905 ULONG ulCreateFlags
= 0L;
906 ULONG ulStyleFlags
= 0L;
907 ULONG ulExtraFlags
= 0L;
908 FRAMECDATA vFrameCtlData
;
909 HWND hParent
= NULLHANDLE
;
910 HWND hClient
= NULLHANDLE
;
911 HWND hFrame
= NULLHANDLE
;
912 HWND hTitlebar
= NULLHANDLE
;
913 HWND hHScroll
= NULLHANDLE
;
914 HWND hVScroll
= NULLHANDLE
;
919 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
922 hParent
= GetWinHwnd(pParent
);
924 hParent
= HWND_DESKTOP
;
926 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
927 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
928 FCF_MINMAX
| FCF_TASKLIST
;
931 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
932 ulCreateFlags
= FCF_TASKLIST
;
934 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
936 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
937 ulCreateFlags
|= FCF_VERTSCROLL
;
938 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
939 ulCreateFlags
|= FCF_HORZSCROLL
;
940 if (ulStyle
& wxMINIMIZE_BOX
)
941 ulCreateFlags
|= FCF_MINBUTTON
;
942 if (ulStyle
& wxMAXIMIZE_BOX
)
943 ulCreateFlags
|= FCF_MAXBUTTON
;
944 if (ulStyle
& wxTHICK_FRAME
)
945 ulCreateFlags
|= FCF_DLGBORDER
;
946 if (ulStyle
& wxSYSTEM_MENU
)
947 ulCreateFlags
|= FCF_SYSMENU
;
948 if (ulStyle
& wxCAPTION
)
949 ulCreateFlags
|= FCF_TASKLIST
;
950 if (ulStyle
& wxCLIP_CHILDREN
)
952 // Invalid for frame windows under PM
955 if (ulStyle
& wxTINY_CAPTION_VERT
)
956 ulCreateFlags
|= FCF_TASKLIST
;
957 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
958 ulCreateFlags
|= FCF_TASKLIST
;
960 if ((ulStyle
& wxTHICK_FRAME
) == 0)
961 ulCreateFlags
|= FCF_BORDER
;
962 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
963 ulExtraFlags
= kFrameToolWindow
;
965 if (ulStyle
& wxSTAY_ON_TOP
)
966 ulCreateFlags
|= FCF_SYSMODAL
;
968 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
969 ulStyleFlags
|= WS_MINIMIZED
;
970 if (ulStyle
& wxMAXIMIZE
)
971 ulStyleFlags
|= WS_MAXIMIZED
;
974 // Clear the visible flag, we always call show
976 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
980 // Set the frame control block
982 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
983 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
984 vFrameCtlData
.hmodResources
= 0L;
985 vFrameCtlData
.idResources
= 0;
988 // Create the frame window
990 if ((m_hFrame
= ::WinCreateWindow( hParent
// Frame is parent
991 ,WC_FRAME
// standard frame class
992 ,(PSZ
)zTitle
// Window title
994 ,0, 0, 0, 0 // Window position
998 ,(PVOID
)&vFrameCtlData
// Creation data
999 ,NULL
// Window Pres Params
1005 if (!wxWindow::OS2Create( m_hFrame
1015 ,(unsigned long)FID_CLIENT
1024 // Now size everything. If adding a menu the client will need to be resized.
1026 if (!::WinSetWindowPos( m_hFrame
1032 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1036 uCtlCount
= SHORT1FROMMP(::WinSendMsg(m_hFrame
, WM_FORMATFRAME
, (MPARAM
)vSwp
, (MPARAM
)vRect
));
1037 for (int i
= 0; i
< uCtlCount
; i
++)
1039 if (vSwp
[i
].hwnd
== m_hFrame
)
1040 memcpy(&m_vSwp
, &vSwp
[i
], sizeof(SWP
));
1041 else if (vSwp
[i
].hwnd
== m_hVScroll
)
1042 memcpy(&m_vSwpVScroll
, &vSwp
[i
], sizeof(SWP
));
1043 else if (vSwp
[i
].hwnd
== m_hHScroll
)
1044 memcpy(&m_vSwpVScroll
, &vSwp
[i
], sizeof(SWP
));
1045 else if (vSwp
[i
].hwnd
== m_hTitleBar
)
1046 memcpy(&m_vSwpTitleBar
, &vSwp
[i
], sizeof(SWP
));
1049 } // end of wxFrame::OS2Create
1052 // Default activation behaviour - set the focus for the first child
1055 void wxFrame::OnActivate(
1056 wxActivateEvent
& rEvent
1059 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1061 pNode
= pNode
->GetNext())
1063 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1064 // but how to do it without duplicating the code?
1067 wxWindow
* pChild
= pNode
->GetData();
1069 if (!pChild
->IsTopLevel()
1071 && !wxDynamicCast(pChild
, wxToolBar
)
1072 #endif // wxUSE_TOOLBAR
1074 && !wxDynamicCast(pChild
, wxStatusBar
)
1075 #endif // wxUSE_STATUSBAR
1082 } // end of wxFrame::OnActivate
1084 // ----------------------------------------------------------------------------
1085 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1086 // from the client area, so the client area is what's really available for the
1088 // ----------------------------------------------------------------------------
1090 // Checks if there is a toolbar, and returns the first free client position
1091 wxPoint
wxFrame::GetClientAreaOrigin() const
1093 wxPoint
vPoint(0, 0);
1100 GetToolBar()->GetSize( &nWidth
1104 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1110 // PM is backwards from windows
1111 vPoint
.y
+= nHeight
;
1115 } // end of wxFrame::GetClientAreaOrigin
1117 // ----------------------------------------------------------------------------
1118 // tool/status bar stuff
1119 // ----------------------------------------------------------------------------
1123 wxToolBar
* wxFrame::CreateToolBar(
1126 , const wxString
& rName
1129 if (wxFrameBase::CreateToolBar( lStyle
1136 return m_frameToolBar
;
1137 } // end of wxFrame::CreateToolBar
1139 void wxFrame::PositionToolBar()
1144 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1152 GetStatusBar()->GetClientSize( &nStatusX
1155 // PM is backwards from windows
1156 vRect
.yBottom
+= nStatusY
;
1158 #endif // wxUSE_STATUSBAR
1165 GetToolBar()->GetSize( &nToolbarWidth
1169 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1171 nToolbarHeight
= vRect
.yBottom
;
1175 nToolbarWidth
= vRect
.xRight
;
1179 // Use the 'real' PM position here
1181 GetToolBar()->SetSize( 0
1185 ,wxSIZE_NO_ADJUSTMENTS
1188 } // end of wxFrame::PositionToolBar
1189 #endif // wxUSE_TOOLBAR
1191 // ----------------------------------------------------------------------------
1192 // frame state (iconized/maximized/...)
1193 // ----------------------------------------------------------------------------
1196 // propagate our state change to all child frames: this allows us to emulate X
1197 // Windows behaviour where child frames float independently of the parent one
1198 // on the desktop, but are iconized/restored with it
1200 void wxFrame::IconizeChildFrames(
1204 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1206 pNode
= pNode
->GetNext() )
1208 wxWindow
* pWin
= pNode
->GetData();
1210 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1212 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1215 } // end of wxFrame::IconizeChildFrames
1217 // ===========================================================================
1218 // message processing
1219 // ===========================================================================
1221 // ---------------------------------------------------------------------------
1223 // ---------------------------------------------------------------------------
1224 bool wxFrame::OS2TranslateMessage(
1229 // try the menu bar accels
1231 wxMenuBar
* pMenuBar
= GetMenuBar();
1236 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1237 return rAcceleratorTable
.Translate(m_hFrame
, pMsg
);
1238 } // end of wxFrame::OS2TranslateMessage
1240 // ---------------------------------------------------------------------------
1241 // our private (non virtual) message handlers
1242 // ---------------------------------------------------------------------------
1243 bool wxFrame::HandlePaint()
1247 if (::WinQueryUpdateRect(GetHwnd(), &vRect
))
1252 // Icons in PM are the same as "pointers"
1257 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1259 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1262 // Hold a pointer to the dc so long as the OnPaint() message
1263 // is being processed
1266 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1269 // Erase background before painting or we get white background
1271 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1278 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1280 static const int nIconWidth
= 32;
1281 static const int nIconHeight
= 32;
1282 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1283 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1285 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1295 hPS
= WinBeginPaint(GetHwnd(), 0L, &vRect
);
1296 WinFillRect(hPS
, &vRect
, SYSCLR_WINDOW
);
1299 return wxWindow::HandlePaint();
1304 // nothing to paint - processed
1308 } // end of wxFrame::HandlePaint
1310 bool wxFrame::HandleSize(
1316 bool bProcessed
= FALSE
;
1322 // Only do it it if we were iconized before, otherwise resizing the
1323 // parent frame has a curious side effect of bringing it under it's
1329 // restore all child frames too
1331 IconizeChildFrames(FALSE
);
1338 m_bIconized
= FALSE
;
1343 // Iconize all child frames too
1345 IconizeChildFrames(TRUE
);
1353 // forward WM_SIZE to status bar control
1355 #if wxUSE_NATIVE_STATUSBAR
1356 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1358 wxSizeEvent
vEvent( wxSize( nX
1361 ,m_frameStatusBar
->GetId()
1364 vEvent
.SetEventObject(m_frameStatusBar
);
1365 m_frameStatusBar
->OnSize(vEvent
);
1367 #endif // wxUSE_NATIVE_STATUSBAR
1369 PositionStatusBar();
1371 wxSizeEvent
vEvent( wxSize( nX
1377 vEvent
.SetEventObject(this);
1378 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1381 } // end of wxFrame::HandleSize
1383 bool wxFrame::HandleCommand(
1392 // In case it's e.g. a toolbar.
1394 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1397 return pWin
->OS2Command( nCmd
1403 // Handle here commands from menus and accelerators
1405 if (nCmd
== 0 || nCmd
== 1)
1407 if (wxCurrentPopupMenu
)
1409 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1411 wxCurrentPopupMenu
= NULL
;
1413 return pPopupMenu
->OS2Command( nCmd
1418 if (ProcessCommand(nId
))
1424 } // end of wxFrame::HandleCommand
1426 bool wxFrame::HandleMenuSelect(
1434 if (nFlags
== 0xFFFF && hMenu
== 0)
1437 // Menu was removed from screen
1441 else if (!(nFlags
& MIS_SUBMENU
) && !(nFlags
& MIS_SEPARATOR
))
1448 // Don't give hints for separators (doesn't make sense) nor for the
1449 // items opening popup menus (they don't have them anyhow)
1453 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nMenuItem
);
1455 vEvent
.SetEventObject(this);
1456 return GetEventHandler()->ProcessEvent(vEvent
);
1457 } // end of wxFrame::HandleMenuSelect
1459 // ---------------------------------------------------------------------------
1460 // the window proc for wxFrame
1461 // ---------------------------------------------------------------------------
1463 MRESULT
wxFrame::OS2WindowProc(
1470 bool bProcessed
= FALSE
;
1476 // If we can't close, tell the system that we processed the
1477 // message - otherwise it would close us
1479 bProcessed
= !Close();
1488 UnpackCommand( (WXWPARAM
)wParam
1494 bProcessed
= HandleCommand( wId
1507 UnpackMenuSelect( wParam
1513 bProcessed
= HandleMenuSelect( wItem
1521 bProcessed
= HandlePaint();
1524 case WM_ERASEBACKGROUND
:
1526 // Return TRUE to request PM to paint the window background
1527 // in SYSCLR_WINDOW.
1530 mRc
= (MRESULT
)(TRUE
);
1533 case CM_QUERYDRAGIMAGE
:
1538 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1540 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1541 mRc
= (MRESULT
)hIcon
;
1542 bProcessed
= mRc
!= 0;
1547 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1552 mRc
= wxWindow::OS2WindowProc( uMessage
1557 } // wxFrame::OS2WindowProc