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 // ----------------------------------------------------------------------------
69 #if wxUSE_NATIVE_STATUSBAR
70 bool wxFrame::m_bUseNativeStatusBar
= TRUE
;
72 bool wxFrame::m_bUseNativeStatusBar
= FALSE
;
75 #endif //wxUSE_STATUSBAR
77 // ----------------------------------------------------------------------------
78 // creation/destruction
79 // ----------------------------------------------------------------------------
88 // Data to save/restore when calling ShowFullScreen
90 m_lFsOldWindowStyle
= 0L;
91 m_nFsStatusBarFields
= 0;
92 m_nFsStatusBarHeight
= 0;
93 m_nFsToolBarHeight
= 0;
94 m_bFsIsMaximized
= FALSE
;
95 m_bFsIsShowing
= FALSE
;
97 m_pWinLastFocused
= (wxWindow
*)NULL
;
102 memset(&m_vSwp
, 0, sizeof(SWP
));
103 memset(&m_vSwpClient
, 0, sizeof(SWP
));
104 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
105 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
106 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
107 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
108 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
109 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
110 } // end of wxFrame::Init
112 bool wxFrame::Create(
115 , const wxString
& rsTitle
116 , const wxPoint
& rPos
117 , const wxSize
& rSize
119 , const wxString
& rsName
124 int nWidth
= rSize
.x
;
125 int nHeight
= rSize
.y
;
128 m_windowStyle
= lulStyle
;
129 m_frameMenuBar
= NULL
;
131 m_frameToolBar
= NULL
;
132 #endif //wxUSE_TOOLBAR
135 m_frameStatusBar
= NULL
;
136 #endif //wxUSE_STATUSBAR
138 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
143 m_windowId
= (int)NewControlId();
146 pParent
->AddChild(this);
150 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
154 wxTopLevelWindows
.Append(this);
156 OS2Create( m_windowId
168 wxModelessWindows
.Append(this);
170 } // end of wxFrame::Create
174 m_isBeingDeleted
= TRUE
;
176 wxTopLevelWindows
.DeleteObject(this);
180 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
182 wxTheApp
->SetTopWindow(NULL
);
184 if (wxTheApp
->GetExitOnFrameDelete())
186 ::WinPostMsg(NULL
, WM_QUIT
, 0, 0);
190 wxModelessWindows
.DeleteObject(this);
193 // For some reason, wxWindows can activate another task altogether
194 // when a frame is destroyed after a modal dialog has been invoked.
195 // Try to bring the parent to the top.
197 // MT:Only do this if this frame is currently the active window, else weird
198 // things start to happen.
200 if (wxGetActiveWindow() == this)
202 if (GetParent() && GetParent()->GetHWND())
204 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
214 } // end of wxFrame::~wxFrame
217 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
219 void wxFrame::DoGetClientSize(
225 // OS/2 PM's coordinates go from bottom-left not
226 // top-left thus the += instead of the -=
231 // PM has no GetClientRect that inherantly knows about the client window
232 // We have to explicitly go fetch it!
234 ::WinQueryWindowRect(GetHwnd(), &vRect
);
237 if ( GetStatusBar() )
242 GetStatusBar()->GetClientSize( &nStatusX
245 vRect
.yBottom
+= nStatusY
;
247 #endif // wxUSE_STATUSBAR
249 wxPoint
vPoint(GetClientAreaOrigin());
251 vRect
.yBottom
+= vPoint
.y
;
252 vRect
.xRight
-= vPoint
.x
;
258 } // end of wxFrame::DoGetClientSize
261 // Set the client size (i.e. leave the calculation of borders etc.
264 void wxFrame::DoSetClientSize(
269 HWND hWnd
= GetHwnd();
273 ::WinQueryWindowRect(GetHwnd(), &vRect
);
275 ::WinQueryWindowRect(GetHWND(), &vRect2
);
278 // Find the difference between the entire window (title bar and all)
279 // and the client area; add this to the new client size to move the
280 // window. Remember OS/2's backwards y coord system!
282 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
283 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
286 if ( GetStatusBar() )
291 GetStatusBar()->GetClientSize( &nStatusX
294 nActualHeight
+= nStatusY
;
296 #endif // wxUSE_STATUSBAR
298 wxPoint
vPoint(GetClientAreaOrigin());
299 nActualWidth
+= vPoint
.y
;
300 nActualHeight
+= vPoint
.x
;
304 vPointl
.x
= vRect2
.xLeft
;
305 vPointl
.y
= vRect2
.yTop
;
307 ::WinSetWindowPos( hWnd
313 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
316 wxSizeEvent
vEvent( wxSize( nWidth
321 vEvent
.SetEventObject(this);
322 GetEventHandler()->ProcessEvent(vEvent
);
323 } // end of wxFrame::DoSetClientSize
325 void wxFrame::DoGetSize(
332 ::WinQueryWindowRect(GetHWND(), &vRect
);
333 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
334 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
335 } // end of wxFrame::DoGetSize
337 void wxFrame::DoGetPosition(
345 ::WinQueryWindowRect(GetHWND(), &vRect
);
346 vPoint
.x
= vRect
.xLeft
;
349 // OS/2 is backwards [WIN32 it is vRect.yTop]
351 vPoint
.y
= vRect
.yBottom
;
355 } // end of wxFrame::DoGetPosition
357 // ----------------------------------------------------------------------------
358 // variations around ::ShowWindow()
359 // ----------------------------------------------------------------------------
361 void wxFrame::DoShowWindow(
365 ::WinShowWindow(GetHWND(), (BOOL
)bShowCmd
);
366 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
367 } // end of wxFrame::DoShowWindow
375 DoShowWindow((int)bShow
);
379 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
381 ::WinQueryWindowPos(GetHWND(), &vSwp
);
382 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
383 ::WinSendMsg(GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
384 ::WinEnableWindow(GetHWND(), TRUE
);
385 vEvent
.SetEventObject(this);
386 GetEventHandler()->ProcessEvent(vEvent
);
391 // Try to highlight the correct window (the parent)
395 HWND hWndParent
= GetHwndOf(GetParent());
397 ::WinQueryWindowPos(hWndParent
, &vSwp
);
398 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
400 ::WinSetWindowPos( hWndParent
406 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
408 ::WinEnableWindow(hWndParent
, TRUE
);
412 } // end of wxFrame::Show
414 void wxFrame::Iconize(
418 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
419 } // end of wxFrame::Iconize
421 void wxFrame::Maximize(
424 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
425 } // end of wxFrame::Maximize
427 void wxFrame::Restore()
429 DoShowWindow(SWP_RESTORE
);
430 } // end of wxFrame::Restore
432 bool wxFrame::IsIconized() const
436 ::WinQueryWindowPos(GetHwnd(), &vSwp
);
438 if (vSwp
.fl
& SWP_MINIMIZE
)
439 ((wxFrame
*)this)->m_bIconized
= TRUE
;
441 ((wxFrame
*)this)->m_bIconized
= FALSE
;
443 } // end of wxFrame::IsIconized
446 bool wxFrame::IsMaximized() const
451 ::WinQueryWindowPos(GetHWND(), &vSwp
);
452 return (vSwp
.fl
& SWP_MAXIMIZE
);
453 } // end of wxFrame::IsMaximized
455 void wxFrame::SetIcon(
459 wxFrameBase::SetIcon(rIcon
);
461 if ((m_icon
.GetHICON()) != NULLHANDLE
)
463 ::WinSendMsg( GetHWND()
465 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
468 ::WinSendMsg( GetHWND()
474 } // end of wxFrame::SetIcon
477 wxStatusBar
* wxFrame::OnCreateStatusBar(
481 , const wxString
& rName
484 wxStatusBar
* pStatusBar
= NULL
;
489 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
501 if( ::WinIsWindowShowing(GetHWND()) )
502 ::WinSendMsg(GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
505 } // end of wxFrame::OnCreateStatusBar
507 void wxFrame::PositionStatusBar()
514 // Native status bar positions itself
516 if (m_frameStatusBar
)
525 ::WinQueryWindowRect(GetHwnd(), &vRect
);
526 nWidth
= vRect
.xRight
- vRect
.xLeft
;
527 nHeight
= vRect
.yTop
- vRect
.yBottom
;
529 m_frameStatusBar
->GetSize( &nStatbarWidth
534 // Since we wish the status bar to be directly under the client area,
535 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
537 m_frameStatusBar
->SetSize( 0
542 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
544 vError
= ::WinGetLastError(vHabmain
);
545 sError
= wxPMErrorToStr(vError
);
546 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
549 if (!::WinSetWindowPos( m_frameStatusBar
->GetHWND()
555 ,SWP_SIZE
| SWP_MOVE
| SWP_SHOW
| SWP_ZORDER
558 vError
= ::WinGetLastError(vHabmain
);
559 sError
= wxPMErrorToStr(vError
);
560 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
564 } // end of wxFrame::PositionStatusBar
565 #endif // wxUSE_STATUSBAR
567 void wxFrame::DetachMenuBar()
571 m_frameMenuBar
->Detach();
572 m_frameMenuBar
= NULL
;
574 } // end of wxFrame::DetachMenuBar
576 void wxFrame::SetMenuBar(
582 HWND hClient
= NULLHANDLE
;
583 HWND hFrame
= NULLHANDLE
;
584 HWND hTitlebar
= NULLHANDLE
;
585 HWND hHScroll
= NULLHANDLE
;
586 HWND hVScroll
= NULLHANDLE
;
587 HWND hMenuBar
= NULLHANDLE
;
599 // Actually remove the menu from the frame
601 m_hMenu
= (WXHMENU
)0;
602 InternalSetMenuBar();
604 else // set new non NULL menu bar
606 m_frameMenuBar
= NULL
;
609 // Can set a menubar several times.
610 // TODO: how to prevent a memory leak if you have a currently-unattached
611 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
612 // there are problems for MDI).
614 if (pMenuBar
->GetHMenu())
616 m_hMenu
= pMenuBar
->GetHMenu();
621 m_hMenu
= pMenuBar
->Create();
625 InternalSetMenuBar();
626 m_frameMenuBar
= pMenuBar
;
627 pMenuBar
->Attach(this);
631 // Now resize the client to fit the new frame
633 WinQueryWindowPos(GetHWND(), &vSwp
);
634 hTitlebar
= WinWindowFromID(GetHWND(), FID_TITLEBAR
);
635 WinQueryWindowPos(hTitlebar
, &vSwpTitlebar
);
636 hHScroll
= WinWindowFromID(GetHWND(), FID_HORZSCROLL
);
637 WinQueryWindowPos(hHScroll
, &vSwpHScroll
);
638 hVScroll
= WinWindowFromID(GetHWND(), FID_VERTSCROLL
);
639 WinQueryWindowPos(hVScroll
, &vSwpVScroll
);
640 hMenuBar
= WinWindowFromID(GetHWND(), FID_MENU
);
641 WinQueryWindowPos(hMenuBar
, &vSwpMenu
);
642 WinSetWindowPos( GetHwnd()
645 ,(SV_CYSIZEBORDER
/2) + vSwpHScroll
.cy
/2
646 ,vSwp
.cx
- ((SV_CXSIZEBORDER
+ 1) + vSwpVScroll
.cx
)
647 ,vSwp
.cy
- ((SV_CYSIZEBORDER
+ 1) + vSwpTitlebar
.cy
+ vSwpMenu
.cy
+ vSwpHScroll
.cy
/2)
650 } // end of wxFrame::SetMenuBar
652 void wxFrame::InternalSetMenuBar()
657 // Set the parent and owner of the menubar to be the frame
659 if (!::WinSetParent(m_hMenu
, GetHWND(), FALSE
))
661 vError
= ::WinGetLastError(vHabmain
);
662 sError
= wxPMErrorToStr(vError
);
663 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
666 if (!::WinSetOwner(m_hMenu
, GetHWND()))
668 vError
= ::WinGetLastError(vHabmain
);
669 sError
= wxPMErrorToStr(vError
);
670 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
672 WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
673 } // end of wxFrame::InternalSetMenuBar
676 // Responds to colour changes, and passes event on to children
678 void wxFrame::OnSysColourChanged(
679 wxSysColourChangedEvent
& rEvent
682 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
686 if (m_frameStatusBar
)
688 wxSysColourChangedEvent vEvent2
;
690 vEvent2
.SetEventObject(m_frameStatusBar
);
691 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
693 #endif //wxUSE_STATUSBAR
696 // Propagate the event to the non-top-level children
698 wxWindow::OnSysColourChanged(rEvent
);
699 } // end of wxFrame::OnSysColourChanged
701 // Pass TRUE to show full screen, FALSE to restore.
702 bool wxFrame::ShowFullScreen(
712 m_bFsIsShowing
= TRUE
;
716 wxToolBar
* pTheToolBar
= GetToolBar();
717 #endif //wxUSE_TOOLBAR
720 wxStatusBar
* pTheStatusBar
= GetStatusBar();
721 #endif //wxUSE_STATUSBAR
727 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
728 #endif //wxUSE_TOOLBAR
732 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
733 #endif //wxUSE_STATUSBAR
737 // Zap the toolbar, menubar, and statusbar
739 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
741 pTheToolBar
->SetSize(-1,0);
742 pTheToolBar
->Show(FALSE
);
744 #endif //wxUSE_TOOLBAR
746 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
748 ::WinSetParent(m_hMenu
, GetHWND(), FALSE
);
749 ::WinSetOwner(m_hMenu
, GetHWND());
750 ::WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
755 // Save the number of fields in the statusbar
757 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
759 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
760 SetStatusBar((wxStatusBar
*) NULL
);
761 delete pTheStatusBar
;
764 m_nFsStatusBarFields
= 0;
765 #endif //wxUSE_STATUSBAR
768 // Zap the frame borders
772 // Save the 'normal' window style
774 m_lFsOldWindowStyle
= ::WinQueryWindowULong((HWND
)GetHWND(), QWL_STYLE
);
777 // Save the old position, width & height, maximize state
779 m_vFsOldSize
= GetRect();
780 m_bFsIsMaximized
= IsMaximized();
783 // Decide which window style flags to turn off
785 LONG lNewStyle
= m_lFsOldWindowStyle
;
788 if (lStyle
& wxFULLSCREEN_NOBORDER
)
789 lOffFlags
|= FCF_BORDER
;
790 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
791 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
793 lNewStyle
&= (~lOffFlags
);
796 // Change our window style to be compatible with full-screen mode
798 ::WinSetWindowULong((HWND
)GetHWND(), QWL_STYLE
, (ULONG
)lNewStyle
);
801 // Resize to the size of the desktop
807 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
808 nWidth
= vRect
.xRight
- vRect
.xLeft
;
810 // Rmember OS/2 is backwards!
812 nHeight
= vRect
.yTop
- vRect
.yBottom
;
819 // Now flush the window style cache and actually go full-screen
821 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
830 wxSizeEvent
vEvent( wxSize( nWidth
836 GetEventHandler()->ProcessEvent(vEvent
);
844 m_bFsIsShowing
= FALSE
;
847 wxToolBar
* pTheToolBar
= GetToolBar();
850 // Restore the toolbar, menubar, and statusbar
852 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
854 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
855 pTheToolBar
->Show(TRUE
);
857 #endif //wxUSE_TOOLBAR
860 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
862 CreateStatusBar(m_nFsStatusBarFields
);
863 // PositionStatusBar();
865 #endif //wxUSE_STATUSBAR
867 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
869 ::WinSetParent(m_hMenu
, GetHWND(), FALSE
);
870 ::WinSetOwner(m_hMenu
, GetHWND());
871 ::WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
873 Maximize(m_bFsIsMaximized
);
875 ::WinSetWindowULong( (HWND
)GetHWND()
877 ,(ULONG
)m_lFsOldWindowStyle
879 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
889 } // end of wxFrame::ShowFullScreen
894 bool wxFrame::OS2Create(
897 , const wxChar
* zWclass
899 , const wxChar
* zTitle
907 ULONG ulCreateFlags
= 0L;
908 ULONG ulStyleFlags
= 0L;
909 ULONG ulExtraFlags
= 0L;
910 FRAMECDATA vFrameCtlData
;
911 HWND hParent
= NULLHANDLE
;
912 HWND hClient
= NULLHANDLE
;
913 HWND hFrame
= NULLHANDLE
;
914 HWND hTitlebar
= NULLHANDLE
;
915 HWND hHScroll
= NULLHANDLE
;
916 HWND hVScroll
= NULLHANDLE
;
921 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
924 hParent
= GetWinHwnd(pParent
);
926 hParent
= HWND_DESKTOP
;
928 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
929 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
930 FCF_MINMAX
| FCF_TASKLIST
;
933 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
934 ulCreateFlags
= FCF_TASKLIST
;
936 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
938 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
939 ulCreateFlags
|= FCF_VERTSCROLL
;
940 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
941 ulCreateFlags
|= FCF_HORZSCROLL
;
942 if (ulStyle
& wxMINIMIZE_BOX
)
943 ulCreateFlags
|= FCF_MINBUTTON
;
944 if (ulStyle
& wxMAXIMIZE_BOX
)
945 ulCreateFlags
|= FCF_MAXBUTTON
;
946 if (ulStyle
& wxTHICK_FRAME
)
947 ulCreateFlags
|= FCF_DLGBORDER
;
948 if (ulStyle
& wxSYSTEM_MENU
)
949 ulCreateFlags
|= FCF_SYSMENU
;
950 if (ulStyle
& wxCAPTION
)
951 ulCreateFlags
|= FCF_TASKLIST
;
952 if (ulStyle
& wxCLIP_CHILDREN
)
954 // Invalid for frame windows under PM
957 if (ulStyle
& wxTINY_CAPTION_VERT
)
958 ulCreateFlags
|= FCF_TASKLIST
;
959 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
960 ulCreateFlags
|= FCF_TASKLIST
;
962 if ((ulStyle
& wxTHICK_FRAME
) == 0)
963 ulCreateFlags
|= FCF_BORDER
;
964 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
965 ulExtraFlags
= kFrameToolWindow
;
967 if (ulStyle
& wxSTAY_ON_TOP
)
968 ulCreateFlags
|= FCF_SYSMODAL
;
970 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
971 ulStyleFlags
|= WS_MINIMIZED
;
972 if (ulStyle
& wxMAXIMIZE
)
973 ulStyleFlags
|= WS_MAXIMIZED
;
976 // Clear the visible flag, we always call show
978 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
982 // Set the frame control block
984 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
985 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
986 vFrameCtlData
.hmodResources
= 0L;
987 vFrameCtlData
.idResources
= 0;
990 // Create the frame window
993 if (!wxWindow::OS2Create( hParent
1001 ,(PVOID
)&vFrameCtlData
1009 // Now need to subclass window.
1012 //SubclassWin(GetHWND());
1014 // ::WinCreateWindow(GetHWND(), WC_LISTBOX, "", WS_VISIBLE, 0, 0,
1015 // 0, 0, GetHWND(), HWND_TOP, FID_CLIENT, NULL, NULL);
1017 // Now size everything. If adding a menu the client will need to be resized.
1020 if (!::WinSetWindowPos( GetHWND()
1026 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1030 uCtlCount = SHORT1FROMMP(::WinSendMsg(GetHWND(), WM_FORMATFRAME, (MPARAM)vSwp, (MPARAM)vRect));
1031 for (int i = 0; i < uCtlCount; i++)
1033 if (vSwp[i].hwnd == GetHWND())
1034 memcpy(&m_vSwp, &vSwp[i], sizeof(SWP));
1035 else if (vSwp[i].hwnd == m_hVScroll)
1036 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
1037 else if (vSwp[i].hwnd == m_hHScroll)
1038 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
1039 else if (vSwp[i].hwnd == m_hTitleBar)
1040 memcpy(&m_vSwpTitleBar, &vSwp[i], sizeof(SWP));
1043 } // end of wxFrame::OS2Create
1046 // Default activation behaviour - set the focus for the first child
1049 void wxFrame::OnActivate(
1050 wxActivateEvent
& rEvent
1053 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1055 pNode
= pNode
->GetNext())
1057 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1058 // but how to do it without duplicating the code?
1061 wxWindow
* pChild
= pNode
->GetData();
1063 if (!pChild
->IsTopLevel()
1065 && !wxDynamicCast(pChild
, wxToolBar
)
1066 #endif // wxUSE_TOOLBAR
1068 && !wxDynamicCast(pChild
, wxStatusBar
)
1069 #endif // wxUSE_STATUSBAR
1076 } // end of wxFrame::OnActivate
1078 // ----------------------------------------------------------------------------
1079 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1080 // from the client area, so the client area is what's really available for the
1082 // ----------------------------------------------------------------------------
1084 // Checks if there is a toolbar, and returns the first free client position
1085 wxPoint
wxFrame::GetClientAreaOrigin() const
1087 wxPoint
vPoint(0, 0);
1095 GetToolBar()->GetSize( &nWidth
1099 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1105 // PM is backwards from windows
1106 vPoint
.y
+= nHeight
;
1109 #endif //wxUSE_TOOLBAR
1111 } // end of wxFrame::GetClientAreaOrigin
1113 // ----------------------------------------------------------------------------
1114 // tool/status bar stuff
1115 // ----------------------------------------------------------------------------
1119 wxToolBar
* wxFrame::CreateToolBar(
1122 , const wxString
& rName
1125 if (wxFrameBase::CreateToolBar( lStyle
1132 return m_frameToolBar
;
1133 } // end of wxFrame::CreateToolBar
1135 void wxFrame::PositionToolBar()
1140 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1148 GetStatusBar()->GetClientSize( &nStatusX
1151 // PM is backwards from windows
1152 vRect
.yBottom
+= nStatusY
;
1154 #endif // wxUSE_STATUSBAR
1161 GetToolBar()->GetSize( &nToolbarWidth
1165 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1167 nToolbarHeight
= vRect
.yBottom
;
1171 nToolbarWidth
= vRect
.xRight
;
1175 // Use the 'real' PM position here
1177 GetToolBar()->SetSize( 0
1181 ,wxSIZE_NO_ADJUSTMENTS
1184 } // end of wxFrame::PositionToolBar
1185 #endif // wxUSE_TOOLBAR
1187 // ----------------------------------------------------------------------------
1188 // frame state (iconized/maximized/...)
1189 // ----------------------------------------------------------------------------
1192 // propagate our state change to all child frames: this allows us to emulate X
1193 // Windows behaviour where child frames float independently of the parent one
1194 // on the desktop, but are iconized/restored with it
1196 void wxFrame::IconizeChildFrames(
1200 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1202 pNode
= pNode
->GetNext() )
1204 wxWindow
* pWin
= pNode
->GetData();
1206 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1208 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1211 } // end of wxFrame::IconizeChildFrames
1213 // ===========================================================================
1214 // message processing
1215 // ===========================================================================
1217 // ---------------------------------------------------------------------------
1219 // ---------------------------------------------------------------------------
1220 bool wxFrame::OS2TranslateMessage(
1225 // try the menu bar accels
1227 wxMenuBar
* pMenuBar
= GetMenuBar();
1233 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1234 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1237 #endif //wxUSE_ACCEL
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(GetHWND(), 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
);
1292 /* DosBeep(500,500);
1296 hPS = WinBeginPaint(GetHwnd(), 0L, &vRect);
1297 WinFillRect(hPS, &vRect, SYSCLR_WINDOW);
1300 return wxWindow::HandlePaint();
1305 // nothing to paint - processed
1309 } // end of wxFrame::HandlePaint
1311 bool wxFrame::HandleSize(
1317 bool bProcessed
= FALSE
;
1323 // Only do it it if we were iconized before, otherwise resizing the
1324 // parent frame has a curious side effect of bringing it under it's
1330 // restore all child frames too
1332 IconizeChildFrames(FALSE
);
1339 m_bIconized
= FALSE
;
1344 // Iconize all child frames too
1346 IconizeChildFrames(TRUE
);
1354 // forward WM_SIZE to status bar control
1356 #if wxUSE_NATIVE_STATUSBAR
1357 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1359 wxSizeEvent
vEvent( wxSize( nX
1362 ,m_frameStatusBar
->GetId()
1365 vEvent
.SetEventObject(m_frameStatusBar
);
1366 m_frameStatusBar
->OnSize(vEvent
);
1368 #endif // wxUSE_NATIVE_STATUSBAR
1370 // PositionStatusBar();
1373 #endif // wxUSE_TOOLBAR
1375 wxSizeEvent
vEvent( wxSize( nX
1381 vEvent
.SetEventObject(this);
1382 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1385 } // end of wxFrame::HandleSize
1387 bool wxFrame::HandleCommand(
1396 // In case it's e.g. a toolbar.
1398 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1401 return pWin
->OS2Command( nCmd
1407 // Handle here commands from menus and accelerators
1409 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1411 if (wxCurrentPopupMenu
)
1413 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1415 wxCurrentPopupMenu
= NULL
;
1417 return pPopupMenu
->OS2Command( nCmd
1422 if (ProcessCommand(nId
))
1428 } // end of wxFrame::HandleCommand
1430 bool wxFrame::HandleMenuSelect(
1438 /* This is wrong section according to IBM's documentation
1439 if (nFlags == 0xFFFF && hMenu == 0)
1442 // Menu was removed from screen
1446 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1453 // Don't give hints for separators (doesn't make sense) nor for the
1454 // items opening popup menus (they don't have them anyhow)
1465 rc
= WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1467 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1469 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1471 vEvent
.SetEventObject(this);
1472 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1476 } // end of wxFrame::HandleMenuSelect
1478 // ---------------------------------------------------------------------------
1479 // the window proc for wxFrame
1480 // ---------------------------------------------------------------------------
1482 MRESULT
wxFrame::OS2WindowProc(
1489 bool bProcessed
= FALSE
;
1495 // If we can't close, tell the system that we processed the
1496 // message - otherwise it would close us
1498 bProcessed
= !Close();
1507 UnpackCommand( (WXWPARAM
)wParam
1514 bProcessed
= HandleCommand( wId
1527 UnpackMenuSelect( wParam
1533 bProcessed
= HandleMenuSelect( wItem
1537 mRc
= (MRESULT
)TRUE
;
1542 bProcessed
= HandlePaint();
1545 case WM_ERASEBACKGROUND
:
1547 // Return TRUE to request PM to paint the window background
1548 // in SYSCLR_WINDOW.
1551 mRc
= (MRESULT
)(TRUE
);
1554 case CM_QUERYDRAGIMAGE
:
1559 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1561 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1562 mRc
= (MRESULT
)hIcon
;
1563 bProcessed
= mRc
!= 0;
1568 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1571 case WM_QUERYFRAMECTLCOUNT
:
1573 USHORT itemCount
= SHORT1FROMMR(OS2GetOldWndProc()(GetHWND(), uMessage
, wParam
, lParam
));
1575 if(m_frameStatusBar
)
1577 #endif //wxUSE_STATUSBAR
1580 mRc
= MRFROMSHORT( itemCount
);
1584 case WM_FORMATFRAME
:
1587 USHORT usClient
= 0;
1592 itemCount
= SHORT1FROMMR(OS2GetOldWndProc()(GetHWND(), uMessage
, wParam
, lParam
));
1593 pSWP
= (PSWP
)PVOIDFROMMP( wParam
);
1595 while(pSWP
[usClient
].hwnd
!= WinWindowFromID(GetHWND(), FID_CLIENT
)
1596 && usClient
< itemCount
)
1600 if(m_frameStatusBar
)
1604 m_frameStatusBar
->GetSize(NULL
, &height
);
1606 if(usClient
== itemCount
)
1608 // frame has no client window
1609 // using another method of calculation
1612 ::WinQueryWindowRect(GetHWND(), &wRectl
);
1613 ::WinMapWindowPoints(GetHWND(), HWND_DESKTOP
, (PPOINTL
)&wRectl
, 2);
1614 ::WinCalcFrameRect(GetHWND(), &wRectl
, TRUE
);
1615 ::WinMapWindowPoints(HWND_DESKTOP
, GetHWND(), (PPOINTL
)&wRectl
, 2);
1617 pSWP
[itemCount
].x
= wRectl
.xLeft
;
1618 pSWP
[itemCount
].y
= wRectl
.yBottom
;
1619 pSWP
[itemCount
].cx
= wRectl
.xRight
- wRectl
.xLeft
- 1;
1620 pSWP
[itemCount
].cy
= height
;
1621 pSWP
[itemCount
].fl
= SWP_SIZE
|
1624 pSWP
[itemCount
].hwnd
= m_frameStatusBar
->GetHWND();
1625 pSWP
[itemCount
].hwndInsertBehind
= HWND_TOP
;
1630 pSWP
[itemCount
].x
= pSWP
[usClient
].x
;
1631 pSWP
[itemCount
].y
= pSWP
[usClient
].y
;
1632 pSWP
[itemCount
].cx
= pSWP
[usClient
].cx
;
1633 pSWP
[itemCount
].cy
= height
;
1634 pSWP
[itemCount
].fl
= SWP_SIZE
|
1637 pSWP
[itemCount
].hwnd
= m_frameStatusBar
->GetHWND();
1638 pSWP
[itemCount
].hwndInsertBehind
= HWND_TOP
;
1639 pSWP
[usClient
].cy
-= height
;
1640 pSWP
[usClient
].y
+= height
;
1645 #endif //wxUSE_STATUSBAR
1648 mRc
= MRFROMSHORT(itemCount
);
1654 mRc
= wxWindow::OS2WindowProc( uMessage
1658 return (MRESULT
)mRc
;
1659 } // wxFrame::OS2WindowProc
1662 void wxFrame::SetClient(WXHWND c_Hwnd
)
1664 // Are we really need to implement it?
1667 void wxFrame::SetClient(wxWindow
* c_Window
)
1669 wxWindow
*oldClient
= this->GetClient();
1670 bool clientHasFocus
= oldClient
&& (oldClient
== wxWindow::FindFocus());
1672 if(oldClient
== c_Window
) // nothing to do
1675 if(c_Window
== NULL
) // just need to remove old client
1677 if(oldClient
== NULL
) // nothing to do
1680 if( clientHasFocus
)
1683 oldClient
->Enable( FALSE
);
1684 oldClient
->Show( FALSE
);
1685 ::WinSetWindowUShort(oldClient
->GetHWND(), QWS_ID
, (USHORT
)oldClient
->GetId());
1686 // to avoid OS/2 bug need to update frame
1687 ::WinSendMsg((HWND
)this->GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1691 // else need to change client
1692 if( clientHasFocus
)
1695 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1698 oldClient
->Enable( FALSE
);
1699 oldClient
->Show( FALSE
);
1700 ::WinSetWindowUShort(oldClient
->GetHWND(), QWS_ID
, (USHORT
)oldClient
->GetId());
1703 c_Window
->Reparent( this );
1704 ::WinSetWindowUShort(c_Window
->GetHWND(), QWS_ID
, FID_CLIENT
);
1706 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1708 c_Window
->Show(); // ensure client is showing
1710 if( this->IsShown() )
1713 ::WinSendMsg(GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1717 wxWindow
*wxFrame::GetClient()
1719 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(GetHWND(), FID_CLIENT
));