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"
17 #include "wx/object.h"
18 #include "wx/dynarray.h"
21 #include "wx/string.h"
30 #include "wx/dialog.h"
31 #include "wx/settings.h"
32 #include "wx/dcclient.h"
35 #include "wx/os2/private.h"
38 #include "wx/statusbr.h"
39 #include "wx/generic/statusbr.h"
40 #endif // wxUSE_STATUSBAR
43 #include "wx/toolbar.h"
44 #endif // wxUSE_TOOLBAR
46 #include "wx/menuitem.h"
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 extern wxWindowList wxModelessWindows
;
54 extern wxList WXDLLEXPORT wxPendingDelete
;
55 extern wxChar wxFrameClassName
[];
56 extern wxMenu
*wxCurrentPopupMenu
;
58 extern void wxAssociateWinWithHandle( HWND hWnd
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
)
67 EVT_ACTIVATE(wxFrame::OnActivate
)
68 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
)
71 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
73 // ============================================================================
75 // ============================================================================
77 // ----------------------------------------------------------------------------
78 // static class members
79 // ----------------------------------------------------------------------------
82 #if wxUSE_NATIVE_STATUSBAR
83 bool wxFrame::m_bUseNativeStatusBar
= TRUE
;
85 bool wxFrame::m_bUseNativeStatusBar
= FALSE
;
88 #endif //wxUSE_STATUSBAR
90 // ----------------------------------------------------------------------------
91 // creation/destruction
92 // ----------------------------------------------------------------------------
101 // Data to save/restore when calling ShowFullScreen
103 m_lFsOldWindowStyle
= 0L;
104 m_nFsStatusBarFields
= 0;
105 m_nFsStatusBarHeight
= 0;
106 m_nFsToolBarHeight
= 0;
107 m_bFsIsMaximized
= FALSE
;
108 m_bFsIsShowing
= FALSE
;
110 m_pWinLastFocused
= (wxWindow
*)NULL
;
120 memset(&m_vSwp
, 0, sizeof(SWP
));
121 memset(&m_vSwpClient
, 0, sizeof(SWP
));
122 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
123 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
124 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
125 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
126 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
127 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
128 } // end of wxFrame::Init
130 bool wxFrame::Create(
133 , const wxString
& rsTitle
134 , const wxPoint
& rPos
135 , const wxSize
& rSize
137 , const wxString
& rsName
142 int nWidth
= rSize
.x
;
143 int nHeight
= rSize
.y
;
147 m_windowStyle
= lulStyle
;
148 m_frameMenuBar
= NULL
;
150 m_frameToolBar
= NULL
;
151 #endif //wxUSE_TOOLBAR
154 m_frameStatusBar
= NULL
;
155 #endif //wxUSE_STATUSBAR
157 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
162 m_windowId
= (int)NewControlId();
165 pParent
->AddChild(this);
169 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
172 bOk
= OS2Create( m_windowId
186 wxTopLevelWindows
.Append(this);
187 wxModelessWindows
.Append(this);
190 } // end of wxFrame::Create
194 m_isBeingDeleted
= TRUE
;
196 wxTopLevelWindows
.DeleteObject(this);
200 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
202 wxTheApp
->SetTopWindow(NULL
);
204 if (wxTheApp
->GetExitOnFrameDelete())
206 ::WinPostMsg(NULL
, WM_QUIT
, 0, 0);
210 wxModelessWindows
.DeleteObject(this);
213 // For some reason, wxWindows can activate another task altogether
214 // when a frame is destroyed after a modal dialog has been invoked.
215 // Try to bring the parent to the top.
217 // MT:Only do this if this frame is currently the active window, else weird
218 // things start to happen.
220 if (wxGetActiveWindow() == this)
222 if (GetParent() && GetParent()->GetHWND())
224 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
234 } // end of wxFrame::~wxFrame
237 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
239 void wxFrame::DoGetClientSize(
245 ::WinQueryWindowRect(GetHwnd(), &vRect
);
246 #if 0 // not needed for OS/2 wxUSE_STATUSBAR
247 if ( GetStatusBar() && GetStatusBar()->IsShown() )
252 GetStatusBar()->GetClientSize( &nStatusX
255 vRect
.yBottom
+= nStatusY
;
257 #endif // wxUSE_STATUSBAR
259 *pX
= vRect
.xRight
- vRect
.xLeft
;
261 *pY
= vRect
.yTop
- vRect
.yBottom
;
262 } // end of wxFrame::DoGetClientSize
265 // Set the client size (i.e. leave the calculation of borders etc.
268 void wxFrame::DoSetClientSize(
273 HWND hWnd
= GetHwnd();
277 ::WinQueryWindowRect(GetHwnd(), &vRect
);
278 ::WinQueryWindowRect(GetHwnd(), &vRect2
);
281 // Find the difference between the entire window (title bar and all)
282 // and the client area; add this to the new client size to move the
283 // window. Remember OS/2's backwards y coord system!
285 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
286 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
289 if ( GetStatusBar() )
294 GetStatusBar()->GetClientSize( &nStatusX
297 nActualHeight
+= nStatusY
;
299 #endif // wxUSE_STATUSBAR
301 wxPoint
vPoint(GetClientAreaOrigin());
302 nActualWidth
+= vPoint
.y
;
303 nActualHeight
+= vPoint
.x
;
307 vPointl
.x
= vRect2
.xLeft
;
308 vPointl
.y
= vRect2
.yTop
;
310 ::WinSetWindowPos( hWnd
316 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
319 wxSizeEvent
vEvent( wxSize( nWidth
324 vEvent
.SetEventObject(this);
325 GetEventHandler()->ProcessEvent(vEvent
);
326 } // end of wxFrame::DoSetClientSize
328 void wxFrame::DoGetSize(
335 ::WinQueryWindowRect(m_hFrame
, &vRect
);
336 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
337 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
338 } // end of wxFrame::DoGetSize
340 void wxFrame::DoGetPosition(
348 ::WinQueryWindowRect(m_hFrame
, &vRect
);
349 vPoint
.x
= vRect
.xLeft
;
352 // OS/2 is backwards [WIN32 it is vRect.yTop]
354 vPoint
.y
= vRect
.yBottom
;
358 } // end of wxFrame::DoGetPosition
360 // ----------------------------------------------------------------------------
361 // variations around ::ShowWindow()
362 // ----------------------------------------------------------------------------
364 void wxFrame::DoShowWindow(
368 ::WinShowWindow(m_hFrame
, (BOOL
)bShowCmd
);
369 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
370 } // end of wxFrame::DoShowWindow
378 DoShowWindow((int)bShow
);
382 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
384 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
385 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
386 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
387 ::WinEnableWindow(m_hFrame
, TRUE
);
388 vEvent
.SetEventObject(this);
389 GetEventHandler()->ProcessEvent(vEvent
);
394 // Try to highlight the correct window (the parent)
398 HWND hWndParent
= GetHwndOf(GetParent());
400 ::WinQueryWindowPos(hWndParent
, &vSwp
);
401 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
403 ::WinSetWindowPos( hWndParent
409 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
411 ::WinEnableWindow(hWndParent
, TRUE
);
415 } // end of wxFrame::Show
417 void wxFrame::Iconize(
421 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
422 } // end of wxFrame::Iconize
424 void wxFrame::Maximize(
427 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
428 } // end of wxFrame::Maximize
430 void wxFrame::Restore()
432 DoShowWindow(SWP_RESTORE
);
433 } // end of wxFrame::Restore
435 bool wxFrame::IsIconized() const
439 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
441 if (vSwp
.fl
& SWP_MINIMIZE
)
442 ((wxFrame
*)this)->m_bIconized
= TRUE
;
444 ((wxFrame
*)this)->m_bIconized
= FALSE
;
446 } // end of wxFrame::IsIconized
449 bool wxFrame::IsMaximized() const
454 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
455 return (vSwp
.fl
& SWP_MAXIMIZE
);
456 } // end of wxFrame::IsMaximized
458 void wxFrame::SetIcon(
462 wxFrameBase::SetIcon(rIcon
);
464 if ((m_icon
.GetHICON()) != NULLHANDLE
)
466 ::WinSendMsg( m_hFrame
468 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
471 ::WinSendMsg( m_hFrame
477 } // end of wxFrame::SetIcon
480 wxStatusBar
* wxFrame::OnCreateStatusBar(
484 , const wxString
& rName
487 wxStatusBar
* pStatusBar
= NULL
;
492 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
501 ::WinSetParent( pStatusBar
->GetHWND()
505 ::WinSetOwner( pStatusBar
->GetHWND()
511 if(::WinIsWindowShowing(m_hFrame
))
512 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
515 } // end of wxFrame::OnCreateStatusBar
517 void wxFrame::PositionStatusBar()
524 // Native status bar positions itself
526 if (m_frameStatusBar
)
535 ::WinQueryWindowRect(m_hFrame
, &vRect
);
536 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
538 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
539 nWidth
= vRect
.xRight
- vRect
.xLeft
;
541 m_frameStatusBar
->GetSize( &nStatbarWidth
546 // Since we wish the status bar to be directly under the client area,
547 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
549 m_frameStatusBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
550 ,vRect
.yBottom
- vFRect
.yBottom
554 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
556 vError
= ::WinGetLastError(vHabmain
);
557 sError
= wxPMErrorToStr(vError
);
558 wxLogError("Error setting parent for StautsBar. Error: %s\n", sError
);
562 } // end of wxFrame::PositionStatusBar
563 #endif // wxUSE_STATUSBAR
565 void wxFrame::DetachMenuBar()
569 m_frameMenuBar
->Detach();
570 m_frameMenuBar
= NULL
;
572 } // end of wxFrame::DetachMenuBar
574 void wxFrame::SetMenuBar(
580 HWND hTitlebar
= NULLHANDLE
;
581 HWND hHScroll
= NULLHANDLE
;
582 HWND hVScroll
= NULLHANDLE
;
583 HWND hMenuBar
= NULLHANDLE
;
595 // Actually remove the menu from the frame
597 m_hMenu
= (WXHMENU
)0;
598 InternalSetMenuBar();
600 else // set new non NULL menu bar
602 m_frameMenuBar
= NULL
;
605 // Can set a menubar several times.
606 // TODO: how to prevent a memory leak if you have a currently-unattached
607 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
608 // there are problems for MDI).
610 if (pMenuBar
->GetHMenu())
612 m_hMenu
= pMenuBar
->GetHMenu();
617 m_hMenu
= pMenuBar
->Create();
621 InternalSetMenuBar();
622 m_frameMenuBar
= pMenuBar
;
623 pMenuBar
->Attach(this);
625 } // end of wxFrame::SetMenuBar
627 void wxFrame::InternalSetMenuBar()
632 // Set the parent and owner of the menubar to be the frame
634 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
636 vError
= ::WinGetLastError(vHabmain
);
637 sError
= wxPMErrorToStr(vError
);
638 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
641 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
643 vError
= ::WinGetLastError(vHabmain
);
644 sError
= wxPMErrorToStr(vError
);
645 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
647 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
648 } // end of wxFrame::InternalSetMenuBar
651 // Responds to colour changes, and passes event on to children
653 void wxFrame::OnSysColourChanged(
654 wxSysColourChangedEvent
& rEvent
657 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
661 if (m_frameStatusBar
)
663 wxSysColourChangedEvent vEvent2
;
665 vEvent2
.SetEventObject(m_frameStatusBar
);
666 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
668 #endif //wxUSE_STATUSBAR
671 // Propagate the event to the non-top-level children
673 wxWindow::OnSysColourChanged(rEvent
);
674 } // end of wxFrame::OnSysColourChanged
676 // Pass TRUE to show full screen, FALSE to restore.
677 bool wxFrame::ShowFullScreen(
687 m_bFsIsShowing
= TRUE
;
691 wxToolBar
* pTheToolBar
= GetToolBar();
692 #endif //wxUSE_TOOLBAR
695 wxStatusBar
* pTheStatusBar
= GetStatusBar();
696 #endif //wxUSE_STATUSBAR
702 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
703 #endif //wxUSE_TOOLBAR
707 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
708 #endif //wxUSE_STATUSBAR
712 // Zap the toolbar, menubar, and statusbar
714 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
716 pTheToolBar
->SetSize(-1,0);
717 pTheToolBar
->Show(FALSE
);
719 #endif //wxUSE_TOOLBAR
721 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
723 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
724 ::WinSetOwner(m_hMenu
, m_hFrame
);
725 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
730 // Save the number of fields in the statusbar
732 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
734 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
735 SetStatusBar((wxStatusBar
*) NULL
);
736 delete pTheStatusBar
;
739 m_nFsStatusBarFields
= 0;
740 #endif //wxUSE_STATUSBAR
743 // Zap the frame borders
747 // Save the 'normal' window style
749 m_lFsOldWindowStyle
= ::WinQueryWindowULong(m_hFrame
, QWL_STYLE
);
752 // Save the old position, width & height, maximize state
754 m_vFsOldSize
= GetRect();
755 m_bFsIsMaximized
= IsMaximized();
758 // Decide which window style flags to turn off
760 LONG lNewStyle
= m_lFsOldWindowStyle
;
763 if (lStyle
& wxFULLSCREEN_NOBORDER
)
764 lOffFlags
|= FCF_BORDER
;
765 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
766 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
768 lNewStyle
&= (~lOffFlags
);
771 // Change our window style to be compatible with full-screen mode
773 ::WinSetWindowULong((HWND
)m_hFrame
, QWL_STYLE
, (ULONG
)lNewStyle
);
776 // Resize to the size of the desktop
782 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
783 nWidth
= vRect
.xRight
- vRect
.xLeft
;
785 // Rmember OS/2 is backwards!
787 nHeight
= vRect
.yTop
- vRect
.yBottom
;
794 // Now flush the window style cache and actually go full-screen
796 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
805 wxSizeEvent
vEvent( wxSize( nWidth
811 GetEventHandler()->ProcessEvent(vEvent
);
819 m_bFsIsShowing
= FALSE
;
822 wxToolBar
* pTheToolBar
= GetToolBar();
825 // Restore the toolbar, menubar, and statusbar
827 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
829 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
830 pTheToolBar
->Show(TRUE
);
832 #endif //wxUSE_TOOLBAR
835 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
837 CreateStatusBar(m_nFsStatusBarFields
);
838 // PositionStatusBar();
840 #endif //wxUSE_STATUSBAR
842 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
844 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
845 ::WinSetOwner(m_hMenu
, m_hFrame
);
846 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
848 Maximize(m_bFsIsMaximized
);
850 ::WinSetWindowULong( m_hFrame
852 ,(ULONG
)m_lFsOldWindowStyle
854 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
864 } // end of wxFrame::ShowFullScreen
869 bool wxFrame::OS2Create(
872 , const wxChar
* zWclass
874 , const wxChar
* zTitle
882 ULONG ulCreateFlags
= 0L;
883 ULONG ulStyleFlags
= 0L;
884 ULONG ulExtraFlags
= 0L;
885 FRAMECDATA vFrameCtlData
;
886 HWND hParent
= NULLHANDLE
;
887 HWND hTitlebar
= NULLHANDLE
;
888 HWND hHScroll
= NULLHANDLE
;
889 HWND hVScroll
= NULLHANDLE
;
890 HWND hFrame
= NULLHANDLE
;
891 HWND hClient
= NULLHANDLE
;
898 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
901 hParent
= GetWinHwnd(pParent
);
903 hParent
= HWND_DESKTOP
;
905 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
906 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
907 FCF_MINMAX
| FCF_TASKLIST
;
910 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
911 ulCreateFlags
= FCF_TASKLIST
;
913 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
915 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
916 ulCreateFlags
|= FCF_VERTSCROLL
;
917 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
918 ulCreateFlags
|= FCF_HORZSCROLL
;
919 if (ulStyle
& wxMINIMIZE_BOX
)
920 ulCreateFlags
|= FCF_MINBUTTON
;
921 if (ulStyle
& wxMAXIMIZE_BOX
)
922 ulCreateFlags
|= FCF_MAXBUTTON
;
923 if (ulStyle
& wxTHICK_FRAME
)
924 ulCreateFlags
|= FCF_DLGBORDER
;
925 if (ulStyle
& wxSYSTEM_MENU
)
926 ulCreateFlags
|= FCF_SYSMENU
;
927 if (ulStyle
& wxCAPTION
)
928 ulCreateFlags
|= FCF_TASKLIST
;
929 if (ulStyle
& wxCLIP_CHILDREN
)
931 // Invalid for frame windows under PM
934 if (ulStyle
& wxTINY_CAPTION_VERT
)
935 ulCreateFlags
|= FCF_TASKLIST
;
936 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
937 ulCreateFlags
|= FCF_TASKLIST
;
939 if ((ulStyle
& wxTHICK_FRAME
) == 0)
940 ulCreateFlags
|= FCF_BORDER
;
941 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
942 ulExtraFlags
= kFrameToolWindow
;
944 if (ulStyle
& wxSTAY_ON_TOP
)
945 ulCreateFlags
|= FCF_SYSMODAL
;
947 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
948 ulStyleFlags
|= WS_MINIMIZED
;
949 if (ulStyle
& wxMAXIMIZE
)
950 ulStyleFlags
|= WS_MAXIMIZED
;
953 // Clear the visible flag, we always call show
955 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
959 // Set the frame control block
961 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
962 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
963 vFrameCtlData
.hmodResources
= 0L;
964 vFrameCtlData
.idResources
= 0;
967 // Create the frame window: We break ranks with other ports now
968 // and instead of calling down into the base wxWindow class' OS2Create
969 // we do all our own stuff here. We will set the needed pieces
970 // of wxWindow manually, here.
973 hFrame
= ::WinCreateStdWindow( hParent
974 ,ulStyleFlags
// frame-window style
975 ,&ulCreateFlags
// window style
976 ,(PSZ
)zWclass
// class name
977 ,(PSZ
)zTitle
// window title
978 ,0L // default client style
979 ,NULLHANDLE
// resource in executable file
981 ,&hClient
// receives client window handle
985 vError
= ::WinGetLastError(vHabmain
);
986 sError
= wxPMErrorToStr(vError
);
987 wxLogError("Error creating frame. Error: %s\n", sError
);
992 // wxWindow class' m_hWnd set here and needed associations
996 wxAssociateWinWithHandle(m_hWnd
, this);
997 wxAssociateWinWithHandle(m_hFrame
, this);
999 m_backgroundColour
.Set(wxString("GREY"));
1001 LONG lColor
= (LONG
)m_backgroundColour
.GetPixel();
1003 if (!::WinSetPresParam( m_hWnd
1009 vError
= ::WinGetLastError(vHabmain
);
1010 sError
= wxPMErrorToStr(vError
);
1011 wxLogError("Error creating frame. Error: %s\n", sError
);
1016 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
1017 // we manually subclass here because we don't want to use the main wxWndProc
1020 m_fnOldWndProc
= (WXFARPROC
) ::WinSubclassWindow(m_hFrame
, (PFNWP
)wxFrameMainWndProc
);
1023 // 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
1035 vError
= ::WinGetLastError(vHabmain
);
1036 sError
= wxPMErrorToStr(vError
);
1037 wxLogError("Error sizing frame. Error: %s\n", sError
);
1041 // We may have to be smarter here when variable sized toolbars are added!
1043 if (!::WinSetWindowPos( m_hWnd
1049 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1052 vError
= ::WinGetLastError(vHabmain
);
1053 sError
= wxPMErrorToStr(vError
);
1054 wxLogError("Error sizing client. Error: %s\n", sError
);
1058 } // end of wxFrame::OS2Create
1061 // Default activation behaviour - set the focus for the first child
1064 void wxFrame::OnActivate(
1065 wxActivateEvent
& rEvent
1068 if ( rEvent
.GetActive() )
1070 // restore focus to the child which was last focused
1071 wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd
);
1073 wxWindow
* pParent
= m_pWinLastFocused
? m_pWinLastFocused
->GetParent()
1080 wxSetFocusToChild( pParent
1084 else // deactivating
1087 // Remember the last focused child if it is our child
1089 m_pWinLastFocused
= FindFocus();
1091 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1093 pNode
= pNode
->GetNext())
1095 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1096 // but how to do it without duplicating the code?
1099 wxWindow
* pChild
= pNode
->GetData();
1101 if (!pChild
->IsTopLevel()
1103 && !wxDynamicCast(pChild
, wxToolBar
)
1104 #endif // wxUSE_TOOLBAR
1106 && !wxDynamicCast(pChild
, wxStatusBar
)
1107 #endif // wxUSE_STATUSBAR
1115 } // end of wxFrame::OnActivate
1117 // ----------------------------------------------------------------------------
1118 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1119 // from the client area, so the client area is what's really available for the
1121 // ----------------------------------------------------------------------------
1123 // Checks if there is a toolbar, and returns the first free client position
1124 wxPoint
wxFrame::GetClientAreaOrigin() const
1126 wxPoint
vPoint(0, 0);
1134 GetToolBar()->GetSize( &nWidth
1138 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1144 // PM is backwards from windows
1145 vPoint
.y
+= nHeight
;
1148 #endif //wxUSE_TOOLBAR
1150 } // end of wxFrame::GetClientAreaOrigin
1152 // ----------------------------------------------------------------------------
1153 // tool/status bar stuff
1154 // ----------------------------------------------------------------------------
1158 wxToolBar
* wxFrame::CreateToolBar(
1161 , const wxString
& rName
1164 if (wxFrameBase::CreateToolBar( lStyle
1171 return m_frameToolBar
;
1172 } // end of wxFrame::CreateToolBar
1174 void wxFrame::PositionToolBar()
1179 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1187 GetStatusBar()->GetClientSize( &nStatusX
1190 // PM is backwards from windows
1191 vRect
.yBottom
+= nStatusY
;
1193 #endif // wxUSE_STATUSBAR
1195 if ( m_frameToolBar
)
1200 m_frameToolBar
->GetSize( &nToolbarWidth
1204 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1206 nToolbarHeight
= vRect
.yBottom
;
1210 nToolbarWidth
= vRect
.xRight
;
1214 // Use the 'real' PM position here
1216 GetToolBar()->SetSize( 0
1220 ,wxSIZE_NO_ADJUSTMENTS
1223 } // end of wxFrame::PositionToolBar
1224 #endif // wxUSE_TOOLBAR
1226 // ----------------------------------------------------------------------------
1227 // frame state (iconized/maximized/...)
1228 // ----------------------------------------------------------------------------
1231 // propagate our state change to all child frames: this allows us to emulate X
1232 // Windows behaviour where child frames float independently of the parent one
1233 // on the desktop, but are iconized/restored with it
1235 void wxFrame::IconizeChildFrames(
1239 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1241 pNode
= pNode
->GetNext() )
1243 wxWindow
* pWin
= pNode
->GetData();
1245 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1247 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1250 } // end of wxFrame::IconizeChildFrames
1252 // ===========================================================================
1253 // message processing
1254 // ===========================================================================
1256 // ---------------------------------------------------------------------------
1258 // ---------------------------------------------------------------------------
1259 bool wxFrame::OS2TranslateMessage(
1264 // try the menu bar accels
1266 wxMenuBar
* pMenuBar
= GetMenuBar();
1272 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1273 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1276 #endif //wxUSE_ACCEL
1277 } // end of wxFrame::OS2TranslateMessage
1279 // ---------------------------------------------------------------------------
1280 // our private (non virtual) message handlers
1281 // ---------------------------------------------------------------------------
1282 bool wxFrame::HandlePaint()
1286 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1291 // Icons in PM are the same as "pointers"
1296 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1298 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1301 // Hold a pointer to the dc so long as the OnPaint() message
1302 // is being processed
1305 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1308 // Erase background before painting or we get white background
1310 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1317 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1319 static const int nIconWidth
= 32;
1320 static const int nIconHeight
= 32;
1321 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1322 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1324 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1331 return(wxWindow::HandlePaint());
1336 // nothing to paint - processed
1340 } // end of wxFrame::HandlePaint
1342 bool wxFrame::HandleSize(
1348 bool bProcessed
= FALSE
;
1354 // Only do it it if we were iconized before, otherwise resizing the
1355 // parent frame has a curious side effect of bringing it under it's
1361 // restore all child frames too
1363 IconizeChildFrames(FALSE
);
1370 m_bIconized
= FALSE
;
1375 // Iconize all child frames too
1377 IconizeChildFrames(TRUE
);
1385 // forward WM_SIZE to status bar control
1387 #if wxUSE_NATIVE_STATUSBAR
1388 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1390 wxSizeEvent
vEvent( wxSize( nX
1393 ,m_frameStatusBar
->GetId()
1396 vEvent
.SetEventObject(m_frameStatusBar
);
1397 m_frameStatusBar
->OnSize(vEvent
);
1399 #endif // wxUSE_NATIVE_STATUSBAR
1401 PositionStatusBar();
1404 #endif // wxUSE_TOOLBAR
1406 wxSizeEvent
vEvent( wxSize( nX
1412 vEvent
.SetEventObject(this);
1413 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1416 } // end of wxFrame::HandleSize
1418 bool wxFrame::HandleCommand(
1427 // In case it's e.g. a toolbar.
1429 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1432 return pWin
->OS2Command( nCmd
1438 // Handle here commands from menus and accelerators
1440 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1442 if (wxCurrentPopupMenu
)
1444 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1446 wxCurrentPopupMenu
= NULL
;
1448 return pPopupMenu
->OS2Command( nCmd
1453 if (ProcessCommand(nId
))
1459 } // end of wxFrame::HandleCommand
1461 bool wxFrame::HandleMenuSelect(
1472 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1474 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1476 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1478 vEvent
.SetEventObject(this);
1479 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1483 } // end of wxFrame::HandleMenuSelect
1485 // ---------------------------------------------------------------------------
1486 // Main Frame window proc
1487 // ---------------------------------------------------------------------------
1488 MRESULT EXPENTRY
wxFrameMainWndProc(
1495 MRESULT rc
= (MRESULT
)0;
1496 bool bProcessed
= FALSE
;
1497 wxFrame
* pWnd
= NULL
;
1499 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1502 case WM_QUERYFRAMECTLCOUNT
:
1503 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1505 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1507 rc
= MRFROMSHORT(uItemCount
);
1511 case WM_FORMATFRAME
:
1512 /////////////////////////////////////////////////////////////////////////////////
1513 // Applications that subclass frame controls may find that the frame is already
1514 // subclassed the number of frame controls is variable.
1515 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1516 // subclassed by calling the previous window procedure and modifying its result.
1517 ////////////////////////////////////////////////////////////////////////////////
1527 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1528 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1529 if(pWnd
->m_frameStatusBar
)
1531 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1532 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1533 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1534 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1536 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1538 vSwpStb
.x
= vRectl
.xLeft
- vRstb
.xLeft
;
1539 vSwpStb
.y
= vRectl
.yBottom
- vRstb
.yBottom
;
1540 vSwpStb
.cx
= vRectl
.xRight
- vRectl
.xLeft
- 1; //?? -1 ??
1541 vSwpStb
.cy
= nHeight
;
1542 vSwpStb
.fl
= SWP_SIZE
|SWP_MOVE
| SWP_SHOW
;
1543 vSwpStb
.hwnd
= pWnd
->m_frameStatusBar
->GetHWND();
1544 vSwpStb
.hwndInsertBehind
= HWND_TOP
;
1546 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1547 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1548 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1549 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1550 for(i
= 0; i
< nItemCount
; i
++)
1552 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1554 pSWP
[i
].x
= vRectl
.xLeft
;
1555 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1556 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1557 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1558 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1559 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1563 rc
= MRFROMSHORT(nItemCount
);
1568 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1569 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1571 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1574 } // end of wxFrameMainWndProc
1576 MRESULT EXPENTRY
wxFrameWndProc(
1584 // Trace all ulMsgs - useful for the debugging
1587 wxFrame
* pWnd
= NULL
;
1589 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1590 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1593 // When we get the first message for the HWND we just created, we associate
1594 // it with wxWindow stored in wxWndHook
1597 MRESULT rc
= (MRESULT
)0;
1598 bool bProcessed
= FALSE
;
1601 // Stop right here if we don't have a valid handle in our wxWindow object.
1603 if (pWnd
&& !pWnd
->GetHWND())
1605 pWnd
->SetHWND((WXHWND
) hWnd
);
1606 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1612 rc
= pWnd
->OS2WindowProc(ulMsg
, wParam
, lParam
);
1614 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1617 } // end of wxFrameWndProc
1619 MRESULT
wxFrame::OS2WindowProc(
1626 bool bProcessed
= FALSE
;
1632 // If we can't close, tell the system that we processed the
1633 // message - otherwise it would close us
1635 bProcessed
= !Close();
1639 bProcessed
= HandlePaint();
1640 mRc
= (MRESULT
)FALSE
;
1643 case WM_ERASEBACKGROUND
:
1645 // Returning TRUE to requests PM to paint the window background
1646 // in SYSCLR_WINDOW. We capture this here because the PS returned
1647 // in Frames is the PS for the whole frame, which we can't really
1648 // use at all. If you want to paint a different background, do it
1649 // in an OnPaint using a wxPaintDC.
1651 mRc
= (MRESULT
)(TRUE
);
1660 UnpackCommand( (WXWPARAM
)wParam
1667 bProcessed
= HandleCommand( wId
1680 UnpackMenuSelect( wParam
1686 bProcessed
= HandleMenuSelect( wItem
1690 mRc
= (MRESULT
)TRUE
;
1696 SHORT nScxold
= SHORT1FROMMP(wParam
); // Old horizontal size.
1697 SHORT nScyold
= SHORT2FROMMP(wParam
); // Old vertical size.
1698 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1699 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1701 lParam
= MRFROM2SHORT( nScxnew
- 20
1705 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1706 mRc
= (MRESULT
)FALSE
;
1709 case CM_QUERYDRAGIMAGE
:
1714 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1716 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1717 mRc
= (MRESULT
)hIcon
;
1718 bProcessed
= mRc
!= 0;
1724 mRc
= wxWindow::OS2WindowProc( uMessage
1728 return (MRESULT
)mRc
;
1729 } // wxFrame::OS2WindowProc
1731 void wxFrame::SetClient(WXHWND c_Hwnd
)
1733 // Duh...nothing to do under OS/2
1736 void wxFrame::SetClient(
1740 wxWindow
* pOldClient
= this->GetClient();
1741 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1743 if(pOldClient
== pWindow
) // nothing to do
1745 if(pWindow
== NULL
) // just need to remove old client
1747 if(pOldClient
== NULL
) // nothing to do
1750 if(bClientHasFocus
)
1753 pOldClient
->Enable( FALSE
);
1754 pOldClient
->Show( FALSE
);
1755 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1756 // to avoid OS/2 bug need to update frame
1757 ::WinSendMsg((HWND
)this->GetFrame(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1762 // Else need to change client
1767 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1770 pOldClient
->Enable(FALSE
);
1771 pOldClient
->Show(FALSE
);
1772 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1774 pWindow
->Reparent(this);
1775 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1776 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1778 pWindow
->Show(); // ensure client is showing
1779 if( this->IsShown() )
1782 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1786 wxWindow
* wxFrame::GetClient()
1788 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(m_hFrame
, FID_CLIENT
));