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
);
248 // No need to use statusbar code as in WIN32 as the FORMATFRAME
249 // window procedure ensures PM knows about the new frame client
250 // size internally. A ::WinQueryWindowRect is all that is needed!
254 *pX
= vRect
.xRight
- vRect
.xLeft
;
256 *pY
= vRect
.yTop
- vRect
.yBottom
;
257 } // end of wxFrame::DoGetClientSize
260 // Set the client size (i.e. leave the calculation of borders etc.
263 void wxFrame::DoSetClientSize(
268 HWND hWnd
= GetHwnd();
272 ::WinQueryWindowRect(GetHwnd(), &vRect
);
273 ::WinQueryWindowRect(GetHwnd(), &vRect2
);
276 // Find the difference between the entire window (title bar and all)
277 // and the client area; add this to the new client size to move the
278 // window. Remember OS/2's backwards y coord system!
280 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
281 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
284 if ( GetStatusBar() )
289 GetStatusBar()->GetClientSize( &nStatusX
292 nActualHeight
+= nStatusY
;
294 #endif // wxUSE_STATUSBAR
296 wxPoint
vPoint(GetClientAreaOrigin());
297 nActualWidth
+= vPoint
.y
;
298 nActualHeight
+= vPoint
.x
;
302 vPointl
.x
= vRect2
.xLeft
;
303 vPointl
.y
= vRect2
.yTop
;
305 ::WinSetWindowPos( hWnd
311 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
314 wxSizeEvent
vEvent( wxSize( nWidth
319 vEvent
.SetEventObject(this);
320 GetEventHandler()->ProcessEvent(vEvent
);
321 } // end of wxFrame::DoSetClientSize
323 void wxFrame::DoGetSize(
330 ::WinQueryWindowRect(m_hFrame
, &vRect
);
331 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
332 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
333 } // end of wxFrame::DoGetSize
335 void wxFrame::DoGetPosition(
343 ::WinQueryWindowRect(m_hFrame
, &vRect
);
344 vPoint
.x
= vRect
.xLeft
;
347 // OS/2 is backwards [WIN32 it is vRect.yTop]
349 vPoint
.y
= vRect
.yBottom
;
353 } // end of wxFrame::DoGetPosition
355 // ----------------------------------------------------------------------------
356 // variations around ::ShowWindow()
357 // ----------------------------------------------------------------------------
359 void wxFrame::DoShowWindow(
363 ::WinShowWindow(m_hFrame
, (BOOL
)bShowCmd
);
364 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
365 } // end of wxFrame::DoShowWindow
373 DoShowWindow((int)bShow
);
377 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
379 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
380 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
381 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
382 ::WinEnableWindow(m_hFrame
, TRUE
);
383 vEvent
.SetEventObject(this);
384 GetEventHandler()->ProcessEvent(vEvent
);
389 // Try to highlight the correct window (the parent)
393 HWND hWndParent
= GetHwndOf(GetParent());
395 ::WinQueryWindowPos(hWndParent
, &vSwp
);
396 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
398 ::WinSetWindowPos( hWndParent
404 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
406 ::WinEnableWindow(hWndParent
, TRUE
);
410 } // end of wxFrame::Show
412 void wxFrame::Iconize(
416 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
417 } // end of wxFrame::Iconize
419 void wxFrame::Maximize(
422 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
423 } // end of wxFrame::Maximize
425 void wxFrame::Restore()
427 DoShowWindow(SWP_RESTORE
);
428 } // end of wxFrame::Restore
430 bool wxFrame::IsIconized() const
434 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
436 if (vSwp
.fl
& SWP_MINIMIZE
)
437 ((wxFrame
*)this)->m_bIconized
= TRUE
;
439 ((wxFrame
*)this)->m_bIconized
= FALSE
;
441 } // end of wxFrame::IsIconized
444 bool wxFrame::IsMaximized() const
449 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
450 return (vSwp
.fl
& SWP_MAXIMIZE
);
451 } // end of wxFrame::IsMaximized
453 void wxFrame::SetIcon(
457 wxFrameBase::SetIcon(rIcon
);
459 if ((m_icon
.GetHICON()) != NULLHANDLE
)
461 ::WinSendMsg( m_hFrame
463 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
466 ::WinSendMsg( m_hFrame
472 } // end of wxFrame::SetIcon
475 wxStatusBar
* wxFrame::OnCreateStatusBar(
479 , const wxString
& rName
482 wxStatusBar
* pStatusBar
= NULL
;
487 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
496 ::WinSetParent( pStatusBar
->GetHWND()
500 ::WinSetOwner( pStatusBar
->GetHWND()
506 if(::WinIsWindowShowing(m_hFrame
))
507 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
510 } // end of wxFrame::OnCreateStatusBar
512 void wxFrame::PositionStatusBar()
519 // Native status bar positions itself
521 if (m_frameStatusBar
)
530 ::WinQueryWindowRect(m_hFrame
, &vRect
);
531 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
533 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
534 nWidth
= vRect
.xRight
- vRect
.xLeft
;
536 m_frameStatusBar
->GetSize( &nStatbarWidth
541 // Since we wish the status bar to be directly under the client area,
542 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
544 m_frameStatusBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
545 ,vRect
.yBottom
- vFRect
.yBottom
549 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
551 vError
= ::WinGetLastError(vHabmain
);
552 sError
= wxPMErrorToStr(vError
);
553 wxLogError("Error setting parent for StautsBar. Error: %s\n", sError
);
557 } // end of wxFrame::PositionStatusBar
558 #endif // wxUSE_STATUSBAR
560 void wxFrame::DetachMenuBar()
564 m_frameMenuBar
->Detach();
565 m_frameMenuBar
= NULL
;
567 } // end of wxFrame::DetachMenuBar
569 void wxFrame::SetMenuBar(
575 HWND hTitlebar
= NULLHANDLE
;
576 HWND hHScroll
= NULLHANDLE
;
577 HWND hVScroll
= NULLHANDLE
;
578 HWND hMenuBar
= NULLHANDLE
;
590 // Actually remove the menu from the frame
592 m_hMenu
= (WXHMENU
)0;
593 InternalSetMenuBar();
595 else // set new non NULL menu bar
597 m_frameMenuBar
= NULL
;
600 // Can set a menubar several times.
601 // TODO: how to prevent a memory leak if you have a currently-unattached
602 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
603 // there are problems for MDI).
605 if (pMenuBar
->GetHMenu())
607 m_hMenu
= pMenuBar
->GetHMenu();
612 m_hMenu
= pMenuBar
->Create();
616 InternalSetMenuBar();
617 m_frameMenuBar
= pMenuBar
;
618 pMenuBar
->Attach(this);
620 } // end of wxFrame::SetMenuBar
622 void wxFrame::InternalSetMenuBar()
627 // Set the parent and owner of the menubar to be the frame
629 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
631 vError
= ::WinGetLastError(vHabmain
);
632 sError
= wxPMErrorToStr(vError
);
633 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
636 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
638 vError
= ::WinGetLastError(vHabmain
);
639 sError
= wxPMErrorToStr(vError
);
640 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
642 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
643 } // end of wxFrame::InternalSetMenuBar
646 // Responds to colour changes, and passes event on to children
648 void wxFrame::OnSysColourChanged(
649 wxSysColourChangedEvent
& rEvent
652 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
656 if (m_frameStatusBar
)
658 wxSysColourChangedEvent vEvent2
;
660 vEvent2
.SetEventObject(m_frameStatusBar
);
661 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
663 #endif //wxUSE_STATUSBAR
666 // Propagate the event to the non-top-level children
668 wxWindow::OnSysColourChanged(rEvent
);
669 } // end of wxFrame::OnSysColourChanged
671 // Pass TRUE to show full screen, FALSE to restore.
672 bool wxFrame::ShowFullScreen(
682 m_bFsIsShowing
= TRUE
;
686 wxToolBar
* pTheToolBar
= GetToolBar();
687 #endif //wxUSE_TOOLBAR
690 wxStatusBar
* pTheStatusBar
= GetStatusBar();
691 #endif //wxUSE_STATUSBAR
697 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
698 #endif //wxUSE_TOOLBAR
702 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
703 #endif //wxUSE_STATUSBAR
707 // Zap the toolbar, menubar, and statusbar
709 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
711 pTheToolBar
->SetSize(-1,0);
712 pTheToolBar
->Show(FALSE
);
714 #endif //wxUSE_TOOLBAR
716 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
718 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
719 ::WinSetOwner(m_hMenu
, m_hFrame
);
720 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
725 // Save the number of fields in the statusbar
727 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
729 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
730 SetStatusBar((wxStatusBar
*) NULL
);
731 delete pTheStatusBar
;
734 m_nFsStatusBarFields
= 0;
735 #endif //wxUSE_STATUSBAR
738 // Zap the frame borders
742 // Save the 'normal' window style
744 m_lFsOldWindowStyle
= ::WinQueryWindowULong(m_hFrame
, QWL_STYLE
);
747 // Save the old position, width & height, maximize state
749 m_vFsOldSize
= GetRect();
750 m_bFsIsMaximized
= IsMaximized();
753 // Decide which window style flags to turn off
755 LONG lNewStyle
= m_lFsOldWindowStyle
;
758 if (lStyle
& wxFULLSCREEN_NOBORDER
)
759 lOffFlags
|= FCF_BORDER
;
760 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
761 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
763 lNewStyle
&= (~lOffFlags
);
766 // Change our window style to be compatible with full-screen mode
768 ::WinSetWindowULong((HWND
)m_hFrame
, QWL_STYLE
, (ULONG
)lNewStyle
);
771 // Resize to the size of the desktop
777 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
778 nWidth
= vRect
.xRight
- vRect
.xLeft
;
780 // Rmember OS/2 is backwards!
782 nHeight
= vRect
.yTop
- vRect
.yBottom
;
789 // Now flush the window style cache and actually go full-screen
791 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
800 wxSizeEvent
vEvent( wxSize( nWidth
806 GetEventHandler()->ProcessEvent(vEvent
);
814 m_bFsIsShowing
= FALSE
;
817 wxToolBar
* pTheToolBar
= GetToolBar();
820 // Restore the toolbar, menubar, and statusbar
822 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
824 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
825 pTheToolBar
->Show(TRUE
);
827 #endif //wxUSE_TOOLBAR
830 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
832 CreateStatusBar(m_nFsStatusBarFields
);
833 // PositionStatusBar();
835 #endif //wxUSE_STATUSBAR
837 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
839 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
840 ::WinSetOwner(m_hMenu
, m_hFrame
);
841 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
843 Maximize(m_bFsIsMaximized
);
845 ::WinSetWindowULong( m_hFrame
847 ,(ULONG
)m_lFsOldWindowStyle
849 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
859 } // end of wxFrame::ShowFullScreen
864 bool wxFrame::OS2Create(
867 , const wxChar
* zWclass
869 , const wxChar
* zTitle
877 ULONG ulCreateFlags
= 0L;
878 ULONG ulStyleFlags
= 0L;
879 ULONG ulExtraFlags
= 0L;
880 FRAMECDATA vFrameCtlData
;
881 HWND hParent
= NULLHANDLE
;
882 HWND hTitlebar
= NULLHANDLE
;
883 HWND hHScroll
= NULLHANDLE
;
884 HWND hVScroll
= NULLHANDLE
;
885 HWND hFrame
= NULLHANDLE
;
886 HWND hClient
= NULLHANDLE
;
893 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
896 hParent
= GetWinHwnd(pParent
);
898 hParent
= HWND_DESKTOP
;
900 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
901 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
902 FCF_MINMAX
| FCF_TASKLIST
;
905 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
906 ulCreateFlags
= FCF_TASKLIST
;
908 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
910 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
911 ulCreateFlags
|= FCF_VERTSCROLL
;
912 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
913 ulCreateFlags
|= FCF_HORZSCROLL
;
914 if (ulStyle
& wxMINIMIZE_BOX
)
915 ulCreateFlags
|= FCF_MINBUTTON
;
916 if (ulStyle
& wxMAXIMIZE_BOX
)
917 ulCreateFlags
|= FCF_MAXBUTTON
;
918 if (ulStyle
& wxTHICK_FRAME
)
919 ulCreateFlags
|= FCF_DLGBORDER
;
920 if (ulStyle
& wxSYSTEM_MENU
)
921 ulCreateFlags
|= FCF_SYSMENU
;
922 if (ulStyle
& wxCAPTION
)
923 ulCreateFlags
|= FCF_TASKLIST
;
924 if (ulStyle
& wxCLIP_CHILDREN
)
926 // Invalid for frame windows under PM
929 if (ulStyle
& wxTINY_CAPTION_VERT
)
930 ulCreateFlags
|= FCF_TASKLIST
;
931 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
932 ulCreateFlags
|= FCF_TASKLIST
;
934 if ((ulStyle
& wxTHICK_FRAME
) == 0)
935 ulCreateFlags
|= FCF_BORDER
;
936 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
937 ulExtraFlags
= kFrameToolWindow
;
939 if (ulStyle
& wxSTAY_ON_TOP
)
940 ulCreateFlags
|= FCF_SYSMODAL
;
942 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
943 ulStyleFlags
|= WS_MINIMIZED
;
944 if (ulStyle
& wxMAXIMIZE
)
945 ulStyleFlags
|= WS_MAXIMIZED
;
948 // Clear the visible flag, we always call show
950 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
954 // Set the frame control block
956 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
957 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
958 vFrameCtlData
.hmodResources
= 0L;
959 vFrameCtlData
.idResources
= 0;
962 // Create the frame window: We break ranks with other ports now
963 // and instead of calling down into the base wxWindow class' OS2Create
964 // we do all our own stuff here. We will set the needed pieces
965 // of wxWindow manually, here.
968 hFrame
= ::WinCreateStdWindow( hParent
969 ,ulStyleFlags
// frame-window style
970 ,&ulCreateFlags
// window style
971 ,(PSZ
)zWclass
// class name
972 ,(PSZ
)zTitle
// window title
973 ,0L // default client style
974 ,NULLHANDLE
// resource in executable file
976 ,&hClient
// receives client window handle
980 vError
= ::WinGetLastError(vHabmain
);
981 sError
= wxPMErrorToStr(vError
);
982 wxLogError("Error creating frame. Error: %s\n", sError
);
987 // wxWindow class' m_hWnd set here and needed associations
991 wxAssociateWinWithHandle(m_hWnd
, this);
992 wxAssociateWinWithHandle(m_hFrame
, this);
994 m_backgroundColour
.Set(wxString("GREY"));
996 LONG lColor
= (LONG
)m_backgroundColour
.GetPixel();
998 if (!::WinSetPresParam( m_hWnd
1004 vError
= ::WinGetLastError(vHabmain
);
1005 sError
= wxPMErrorToStr(vError
);
1006 wxLogError("Error creating frame. Error: %s\n", sError
);
1011 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
1012 // we manually subclass here because we don't want to use the main wxWndProc
1015 m_fnOldWndProc
= (WXFARPROC
) ::WinSubclassWindow(m_hFrame
, (PFNWP
)wxFrameMainWndProc
);
1018 // Now size everything. If adding a menu the client will need to be resized.
1021 if (!::WinSetWindowPos( m_hFrame
1027 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1030 vError
= ::WinGetLastError(vHabmain
);
1031 sError
= wxPMErrorToStr(vError
);
1032 wxLogError("Error sizing frame. Error: %s\n", sError
);
1036 // We may have to be smarter here when variable sized toolbars are added!
1038 if (!::WinSetWindowPos( m_hWnd
1044 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1047 vError
= ::WinGetLastError(vHabmain
);
1048 sError
= wxPMErrorToStr(vError
);
1049 wxLogError("Error sizing client. Error: %s\n", sError
);
1053 } // end of wxFrame::OS2Create
1056 // Default activation behaviour - set the focus for the first child
1059 void wxFrame::OnActivate(
1060 wxActivateEvent
& rEvent
1063 if ( rEvent
.GetActive() )
1065 // restore focus to the child which was last focused
1066 wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd
);
1068 wxWindow
* pParent
= m_pWinLastFocused
? m_pWinLastFocused
->GetParent()
1075 wxSetFocusToChild( pParent
1079 else // deactivating
1082 // Remember the last focused child if it is our child
1084 m_pWinLastFocused
= FindFocus();
1086 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1088 pNode
= pNode
->GetNext())
1090 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1091 // but how to do it without duplicating the code?
1094 wxWindow
* pChild
= pNode
->GetData();
1096 if (!pChild
->IsTopLevel()
1098 && !wxDynamicCast(pChild
, wxToolBar
)
1099 #endif // wxUSE_TOOLBAR
1101 && !wxDynamicCast(pChild
, wxStatusBar
)
1102 #endif // wxUSE_STATUSBAR
1110 } // end of wxFrame::OnActivate
1112 void wxFrame::RemoveChild(
1113 wxWindowBase
* pChild
1116 if (pChild
== m_pWinLastFocused
)
1117 m_pWinLastFocused
= NULL
;
1118 wxFrameBase::RemoveChild(pChild
);
1119 } // end of wxFrame::RemoveChild
1121 // ----------------------------------------------------------------------------
1122 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1123 // from the client area, so the client area is what's really available for the
1125 // ----------------------------------------------------------------------------
1127 // Checks if there is a toolbar, and returns the first free client position
1128 wxPoint
wxFrame::GetClientAreaOrigin() const
1130 wxPoint
vPoint(0, 0);
1138 GetToolBar()->GetSize( &nWidth
1142 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1148 // PM is backwards from windows
1149 vPoint
.y
+= nHeight
;
1152 #endif //wxUSE_TOOLBAR
1154 } // end of wxFrame::GetClientAreaOrigin
1156 // ----------------------------------------------------------------------------
1157 // tool/status bar stuff
1158 // ----------------------------------------------------------------------------
1162 wxToolBar
* wxFrame::CreateToolBar(
1165 , const wxString
& rName
1168 if (wxFrameBase::CreateToolBar( lStyle
1175 return m_frameToolBar
;
1176 } // end of wxFrame::CreateToolBar
1178 void wxFrame::PositionToolBar()
1183 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1191 GetStatusBar()->GetClientSize( &nStatusX
1194 // PM is backwards from windows
1195 vRect
.yBottom
+= nStatusY
;
1197 #endif // wxUSE_STATUSBAR
1199 if ( m_frameToolBar
)
1204 m_frameToolBar
->GetSize( &nToolbarWidth
1208 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1210 nToolbarHeight
= vRect
.yBottom
;
1214 nToolbarWidth
= vRect
.xRight
;
1218 // Use the 'real' PM position here
1220 GetToolBar()->SetSize( 0
1224 ,wxSIZE_NO_ADJUSTMENTS
1227 } // end of wxFrame::PositionToolBar
1228 #endif // wxUSE_TOOLBAR
1230 // ----------------------------------------------------------------------------
1231 // frame state (iconized/maximized/...)
1232 // ----------------------------------------------------------------------------
1235 // propagate our state change to all child frames: this allows us to emulate X
1236 // Windows behaviour where child frames float independently of the parent one
1237 // on the desktop, but are iconized/restored with it
1239 void wxFrame::IconizeChildFrames(
1243 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1245 pNode
= pNode
->GetNext() )
1247 wxWindow
* pWin
= pNode
->GetData();
1249 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1251 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1254 } // end of wxFrame::IconizeChildFrames
1256 // ===========================================================================
1257 // message processing
1258 // ===========================================================================
1260 // ---------------------------------------------------------------------------
1262 // ---------------------------------------------------------------------------
1263 bool wxFrame::OS2TranslateMessage(
1268 // try the menu bar accels
1270 wxMenuBar
* pMenuBar
= GetMenuBar();
1276 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1277 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1280 #endif //wxUSE_ACCEL
1281 } // end of wxFrame::OS2TranslateMessage
1283 // ---------------------------------------------------------------------------
1284 // our private (non virtual) message handlers
1285 // ---------------------------------------------------------------------------
1286 bool wxFrame::HandlePaint()
1290 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1295 // Icons in PM are the same as "pointers"
1300 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1302 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1305 // Hold a pointer to the dc so long as the OnPaint() message
1306 // is being processed
1309 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1312 // Erase background before painting or we get white background
1314 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1321 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1323 static const int nIconWidth
= 32;
1324 static const int nIconHeight
= 32;
1325 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1326 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1328 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1335 return(wxWindow::HandlePaint());
1340 // nothing to paint - processed
1344 } // end of wxFrame::HandlePaint
1346 bool wxFrame::HandleSize(
1352 bool bProcessed
= FALSE
;
1358 // Only do it it if we were iconized before, otherwise resizing the
1359 // parent frame has a curious side effect of bringing it under it's
1365 // restore all child frames too
1367 IconizeChildFrames(FALSE
);
1374 m_bIconized
= FALSE
;
1379 // Iconize all child frames too
1381 IconizeChildFrames(TRUE
);
1389 // forward WM_SIZE to status bar control
1391 #if wxUSE_NATIVE_STATUSBAR
1392 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1394 wxSizeEvent
vEvent( wxSize( nX
1397 ,m_frameStatusBar
->GetId()
1400 vEvent
.SetEventObject(m_frameStatusBar
);
1401 m_frameStatusBar
->OnSize(vEvent
);
1403 #endif // wxUSE_NATIVE_STATUSBAR
1405 PositionStatusBar();
1408 #endif // wxUSE_TOOLBAR
1410 wxSizeEvent
vEvent( wxSize( nX
1416 vEvent
.SetEventObject(this);
1417 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1420 } // end of wxFrame::HandleSize
1422 bool wxFrame::HandleCommand(
1431 // In case it's e.g. a toolbar.
1433 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1436 return pWin
->OS2Command( nCmd
1442 // Handle here commands from menus and accelerators
1444 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1446 if (wxCurrentPopupMenu
)
1448 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1450 wxCurrentPopupMenu
= NULL
;
1452 return pPopupMenu
->OS2Command( nCmd
1457 if (ProcessCommand(nId
))
1463 } // end of wxFrame::HandleCommand
1465 bool wxFrame::HandleMenuSelect(
1476 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1478 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1480 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1482 vEvent
.SetEventObject(this);
1483 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1487 } // end of wxFrame::HandleMenuSelect
1489 // ---------------------------------------------------------------------------
1490 // Main Frame window proc
1491 // ---------------------------------------------------------------------------
1492 MRESULT EXPENTRY
wxFrameMainWndProc(
1499 MRESULT rc
= (MRESULT
)0;
1500 bool bProcessed
= FALSE
;
1501 wxFrame
* pWnd
= NULL
;
1503 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1506 case WM_QUERYFRAMECTLCOUNT
:
1507 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1509 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1511 rc
= MRFROMSHORT(uItemCount
);
1515 case WM_FORMATFRAME
:
1516 /////////////////////////////////////////////////////////////////////////////////
1517 // Applications that subclass frame controls may find that the frame is already
1518 // subclassed the number of frame controls is variable.
1519 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1520 // subclassed by calling the previous window procedure and modifying its result.
1521 ////////////////////////////////////////////////////////////////////////////////
1531 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1532 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1533 if(pWnd
->m_frameStatusBar
)
1535 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1536 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1537 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1538 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1540 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1542 vSwpStb
.x
= vRectl
.xLeft
- vRstb
.xLeft
;
1543 vSwpStb
.y
= vRectl
.yBottom
- vRstb
.yBottom
;
1544 vSwpStb
.cx
= vRectl
.xRight
- vRectl
.xLeft
- 1; //?? -1 ??
1545 vSwpStb
.cy
= nHeight
;
1546 vSwpStb
.fl
= SWP_SIZE
|SWP_MOVE
| SWP_SHOW
;
1547 vSwpStb
.hwnd
= pWnd
->m_frameStatusBar
->GetHWND();
1548 vSwpStb
.hwndInsertBehind
= HWND_TOP
;
1550 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1551 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1552 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1553 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1554 for(i
= 0; i
< nItemCount
; i
++)
1556 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1558 pSWP
[i
].x
= vRectl
.xLeft
;
1559 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1560 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1561 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1562 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1563 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1567 rc
= MRFROMSHORT(nItemCount
);
1572 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1573 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1575 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1578 } // end of wxFrameMainWndProc
1580 MRESULT EXPENTRY
wxFrameWndProc(
1588 // Trace all ulMsgs - useful for the debugging
1591 wxFrame
* pWnd
= NULL
;
1593 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1594 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1597 // When we get the first message for the HWND we just created, we associate
1598 // it with wxWindow stored in wxWndHook
1601 MRESULT rc
= (MRESULT
)0;
1602 bool bProcessed
= FALSE
;
1605 // Stop right here if we don't have a valid handle in our wxWindow object.
1607 if (pWnd
&& !pWnd
->GetHWND())
1609 pWnd
->SetHWND((WXHWND
) hWnd
);
1610 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1616 rc
= pWnd
->OS2WindowProc(ulMsg
, wParam
, lParam
);
1618 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1621 } // end of wxFrameWndProc
1623 MRESULT
wxFrame::OS2WindowProc(
1630 bool bProcessed
= FALSE
;
1636 // If we can't close, tell the system that we processed the
1637 // message - otherwise it would close us
1639 bProcessed
= !Close();
1643 bProcessed
= HandlePaint();
1644 mRc
= (MRESULT
)FALSE
;
1647 case WM_ERASEBACKGROUND
:
1649 // Returning TRUE to requests PM to paint the window background
1650 // in SYSCLR_WINDOW. We capture this here because the PS returned
1651 // in Frames is the PS for the whole frame, which we can't really
1652 // use at all. If you want to paint a different background, do it
1653 // in an OnPaint using a wxPaintDC.
1655 mRc
= (MRESULT
)(TRUE
);
1664 UnpackCommand( (WXWPARAM
)wParam
1671 bProcessed
= HandleCommand( wId
1684 UnpackMenuSelect( wParam
1690 bProcessed
= HandleMenuSelect( wItem
1694 mRc
= (MRESULT
)TRUE
;
1700 SHORT nScxold
= SHORT1FROMMP(wParam
); // Old horizontal size.
1701 SHORT nScyold
= SHORT2FROMMP(wParam
); // Old vertical size.
1702 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1703 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1705 lParam
= MRFROM2SHORT( nScxnew
- 20
1709 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1710 mRc
= (MRESULT
)FALSE
;
1713 case CM_QUERYDRAGIMAGE
:
1718 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1720 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1721 mRc
= (MRESULT
)hIcon
;
1722 bProcessed
= mRc
!= 0;
1728 mRc
= wxWindow::OS2WindowProc( uMessage
1732 return (MRESULT
)mRc
;
1733 } // wxFrame::OS2WindowProc
1735 void wxFrame::SetClient(WXHWND c_Hwnd
)
1737 // Duh...nothing to do under OS/2
1740 void wxFrame::SetClient(
1744 wxWindow
* pOldClient
= this->GetClient();
1745 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1747 if(pOldClient
== pWindow
) // nothing to do
1749 if(pWindow
== NULL
) // just need to remove old client
1751 if(pOldClient
== NULL
) // nothing to do
1754 if(bClientHasFocus
)
1757 pOldClient
->Enable( FALSE
);
1758 pOldClient
->Show( FALSE
);
1759 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1760 // to avoid OS/2 bug need to update frame
1761 ::WinSendMsg((HWND
)this->GetFrame(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1766 // Else need to change client
1771 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1774 pOldClient
->Enable(FALSE
);
1775 pOldClient
->Show(FALSE
);
1776 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1778 pWindow
->Reparent(this);
1779 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1780 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1782 pWindow
->Show(); // ensure client is showing
1783 if( this->IsShown() )
1786 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1790 wxWindow
* wxFrame::GetClient()
1792 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(m_hFrame
, FID_CLIENT
));