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 // ----------------------------------------------------------------------------
1113 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1114 // from the client area, so the client area is what's really available for the
1116 // ----------------------------------------------------------------------------
1118 // Checks if there is a toolbar, and returns the first free client position
1119 wxPoint
wxFrame::GetClientAreaOrigin() const
1121 wxPoint
vPoint(0, 0);
1129 GetToolBar()->GetSize( &nWidth
1133 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1139 // PM is backwards from windows
1140 vPoint
.y
+= nHeight
;
1143 #endif //wxUSE_TOOLBAR
1145 } // end of wxFrame::GetClientAreaOrigin
1147 // ----------------------------------------------------------------------------
1148 // tool/status bar stuff
1149 // ----------------------------------------------------------------------------
1153 wxToolBar
* wxFrame::CreateToolBar(
1156 , const wxString
& rName
1159 if (wxFrameBase::CreateToolBar( lStyle
1166 return m_frameToolBar
;
1167 } // end of wxFrame::CreateToolBar
1169 void wxFrame::PositionToolBar()
1174 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1182 GetStatusBar()->GetClientSize( &nStatusX
1185 // PM is backwards from windows
1186 vRect
.yBottom
+= nStatusY
;
1188 #endif // wxUSE_STATUSBAR
1190 if ( m_frameToolBar
)
1195 m_frameToolBar
->GetSize( &nToolbarWidth
1199 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1201 nToolbarHeight
= vRect
.yBottom
;
1205 nToolbarWidth
= vRect
.xRight
;
1209 // Use the 'real' PM position here
1211 GetToolBar()->SetSize( 0
1215 ,wxSIZE_NO_ADJUSTMENTS
1218 } // end of wxFrame::PositionToolBar
1219 #endif // wxUSE_TOOLBAR
1221 // ----------------------------------------------------------------------------
1222 // frame state (iconized/maximized/...)
1223 // ----------------------------------------------------------------------------
1226 // propagate our state change to all child frames: this allows us to emulate X
1227 // Windows behaviour where child frames float independently of the parent one
1228 // on the desktop, but are iconized/restored with it
1230 void wxFrame::IconizeChildFrames(
1234 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1236 pNode
= pNode
->GetNext() )
1238 wxWindow
* pWin
= pNode
->GetData();
1240 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1242 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1245 } // end of wxFrame::IconizeChildFrames
1247 // ===========================================================================
1248 // message processing
1249 // ===========================================================================
1251 // ---------------------------------------------------------------------------
1253 // ---------------------------------------------------------------------------
1254 bool wxFrame::OS2TranslateMessage(
1259 // try the menu bar accels
1261 wxMenuBar
* pMenuBar
= GetMenuBar();
1267 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1268 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1271 #endif //wxUSE_ACCEL
1272 } // end of wxFrame::OS2TranslateMessage
1274 // ---------------------------------------------------------------------------
1275 // our private (non virtual) message handlers
1276 // ---------------------------------------------------------------------------
1277 bool wxFrame::HandlePaint()
1281 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1286 // Icons in PM are the same as "pointers"
1291 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1293 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1296 // Hold a pointer to the dc so long as the OnPaint() message
1297 // is being processed
1300 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1303 // Erase background before painting or we get white background
1305 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1312 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1314 static const int nIconWidth
= 32;
1315 static const int nIconHeight
= 32;
1316 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1317 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1319 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1326 return(wxWindow::HandlePaint());
1331 // nothing to paint - processed
1335 } // end of wxFrame::HandlePaint
1337 bool wxFrame::HandleSize(
1343 bool bProcessed
= FALSE
;
1349 // Only do it it if we were iconized before, otherwise resizing the
1350 // parent frame has a curious side effect of bringing it under it's
1356 // restore all child frames too
1358 IconizeChildFrames(FALSE
);
1365 m_bIconized
= FALSE
;
1370 // Iconize all child frames too
1372 IconizeChildFrames(TRUE
);
1380 // forward WM_SIZE to status bar control
1382 #if wxUSE_NATIVE_STATUSBAR
1383 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1385 wxSizeEvent
vEvent( wxSize( nX
1388 ,m_frameStatusBar
->GetId()
1391 vEvent
.SetEventObject(m_frameStatusBar
);
1392 m_frameStatusBar
->OnSize(vEvent
);
1394 #endif // wxUSE_NATIVE_STATUSBAR
1396 PositionStatusBar();
1399 #endif // wxUSE_TOOLBAR
1401 wxSizeEvent
vEvent( wxSize( nX
1407 vEvent
.SetEventObject(this);
1408 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1411 } // end of wxFrame::HandleSize
1413 bool wxFrame::HandleCommand(
1422 // In case it's e.g. a toolbar.
1424 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1427 return pWin
->OS2Command( nCmd
1433 // Handle here commands from menus and accelerators
1435 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1437 if (wxCurrentPopupMenu
)
1439 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1441 wxCurrentPopupMenu
= NULL
;
1443 return pPopupMenu
->OS2Command( nCmd
1448 if (ProcessCommand(nId
))
1454 } // end of wxFrame::HandleCommand
1456 bool wxFrame::HandleMenuSelect(
1467 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1469 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1471 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1473 vEvent
.SetEventObject(this);
1474 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1478 } // end of wxFrame::HandleMenuSelect
1480 // ---------------------------------------------------------------------------
1481 // Main Frame window proc
1482 // ---------------------------------------------------------------------------
1483 MRESULT EXPENTRY
wxFrameMainWndProc(
1490 MRESULT rc
= (MRESULT
)0;
1491 bool bProcessed
= FALSE
;
1492 wxFrame
* pWnd
= NULL
;
1494 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1497 case WM_QUERYFRAMECTLCOUNT
:
1498 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1500 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1502 rc
= MRFROMSHORT(uItemCount
);
1506 case WM_FORMATFRAME
:
1507 /////////////////////////////////////////////////////////////////////////////////
1508 // Applications that subclass frame controls may find that the frame is already
1509 // subclassed the number of frame controls is variable.
1510 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1511 // subclassed by calling the previous window procedure and modifying its result.
1512 ////////////////////////////////////////////////////////////////////////////////
1522 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1523 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1524 if(pWnd
->m_frameStatusBar
)
1526 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1527 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1528 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1529 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1531 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1533 vSwpStb
.x
= vRectl
.xLeft
- vRstb
.xLeft
;
1534 vSwpStb
.y
= vRectl
.yBottom
- vRstb
.yBottom
;
1535 vSwpStb
.cx
= vRectl
.xRight
- vRectl
.xLeft
- 1; //?? -1 ??
1536 vSwpStb
.cy
= nHeight
;
1537 vSwpStb
.fl
= SWP_SIZE
|SWP_MOVE
| SWP_SHOW
;
1538 vSwpStb
.hwnd
= pWnd
->m_frameStatusBar
->GetHWND();
1539 vSwpStb
.hwndInsertBehind
= HWND_TOP
;
1541 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1542 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1543 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1544 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1545 for(i
= 0; i
< nItemCount
; i
++)
1547 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1549 pSWP
[i
].x
= vRectl
.xLeft
;
1550 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1551 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1552 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1553 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1554 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1558 rc
= MRFROMSHORT(nItemCount
);
1563 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1564 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1566 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1569 } // end of wxFrameMainWndProc
1571 MRESULT EXPENTRY
wxFrameWndProc(
1579 // Trace all ulMsgs - useful for the debugging
1582 wxFrame
* pWnd
= NULL
;
1584 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1585 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1588 // When we get the first message for the HWND we just created, we associate
1589 // it with wxWindow stored in wxWndHook
1592 MRESULT rc
= (MRESULT
)0;
1593 bool bProcessed
= FALSE
;
1596 // Stop right here if we don't have a valid handle in our wxWindow object.
1598 if (pWnd
&& !pWnd
->GetHWND())
1600 pWnd
->SetHWND((WXHWND
) hWnd
);
1601 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1607 rc
= pWnd
->OS2WindowProc(ulMsg
, wParam
, lParam
);
1609 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1612 } // end of wxFrameWndProc
1614 MRESULT
wxFrame::OS2WindowProc(
1621 bool bProcessed
= FALSE
;
1627 // If we can't close, tell the system that we processed the
1628 // message - otherwise it would close us
1630 bProcessed
= !Close();
1634 bProcessed
= HandlePaint();
1635 mRc
= (MRESULT
)FALSE
;
1638 case WM_ERASEBACKGROUND
:
1640 // Returning TRUE to requests PM to paint the window background
1641 // in SYSCLR_WINDOW. We capture this here because the PS returned
1642 // in Frames is the PS for the whole frame, which we can't really
1643 // use at all. If you want to paint a different background, do it
1644 // in an OnPaint using a wxPaintDC.
1646 mRc
= (MRESULT
)(TRUE
);
1655 UnpackCommand( (WXWPARAM
)wParam
1662 bProcessed
= HandleCommand( wId
1675 UnpackMenuSelect( wParam
1681 bProcessed
= HandleMenuSelect( wItem
1685 mRc
= (MRESULT
)TRUE
;
1691 SHORT nScxold
= SHORT1FROMMP(wParam
); // Old horizontal size.
1692 SHORT nScyold
= SHORT2FROMMP(wParam
); // Old vertical size.
1693 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1694 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1696 lParam
= MRFROM2SHORT( nScxnew
- 20
1700 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1701 mRc
= (MRESULT
)FALSE
;
1704 case CM_QUERYDRAGIMAGE
:
1709 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1711 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1712 mRc
= (MRESULT
)hIcon
;
1713 bProcessed
= mRc
!= 0;
1719 mRc
= wxWindow::OS2WindowProc( uMessage
1723 return (MRESULT
)mRc
;
1724 } // wxFrame::OS2WindowProc
1726 void wxFrame::SetClient(WXHWND c_Hwnd
)
1728 // Duh...nothing to do under OS/2
1731 void wxFrame::SetClient(
1735 wxWindow
* pOldClient
= this->GetClient();
1736 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1738 if(pOldClient
== pWindow
) // nothing to do
1740 if(pWindow
== NULL
) // just need to remove old client
1742 if(pOldClient
== NULL
) // nothing to do
1745 if(bClientHasFocus
)
1748 pOldClient
->Enable( FALSE
);
1749 pOldClient
->Show( FALSE
);
1750 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1751 // to avoid OS/2 bug need to update frame
1752 ::WinSendMsg((HWND
)this->GetFrame(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1757 // Else need to change client
1762 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1765 pOldClient
->Enable(FALSE
);
1766 pOldClient
->Show(FALSE
);
1767 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1769 pWindow
->Reparent(this);
1770 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1771 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1773 pWindow
->Show(); // ensure client is showing
1774 if( this->IsShown() )
1777 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1781 wxWindow
* wxFrame::GetClient()
1783 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(m_hFrame
, FID_CLIENT
));