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
,wxWindow
* pWin
);
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
)
65 EVT_ACTIVATE(wxFrame::OnActivate
)
66 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
)
69 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
71 // ============================================================================
73 // ============================================================================
75 // ----------------------------------------------------------------------------
76 // static class members
77 // ----------------------------------------------------------------------------
80 #if wxUSE_NATIVE_STATUSBAR
81 bool wxFrame::m_bUseNativeStatusBar
= TRUE
;
83 bool wxFrame::m_bUseNativeStatusBar
= FALSE
;
86 #endif //wxUSE_STATUSBAR
88 // ----------------------------------------------------------------------------
89 // creation/destruction
90 // ----------------------------------------------------------------------------
99 // Data to save/restore when calling ShowFullScreen
101 m_lFsOldWindowStyle
= 0L;
102 m_nFsStatusBarFields
= 0;
103 m_nFsStatusBarHeight
= 0;
104 m_nFsToolBarHeight
= 0;
105 m_bFsIsMaximized
= FALSE
;
106 m_bFsIsShowing
= FALSE
;
108 m_pWinLastFocused
= (wxWindow
*)NULL
;
118 memset(&m_vSwp
, 0, sizeof(SWP
));
119 memset(&m_vSwpClient
, 0, sizeof(SWP
));
120 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
121 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
122 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
123 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
124 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
125 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
126 } // end of wxFrame::Init
128 bool wxFrame::Create(
131 , const wxString
& rsTitle
132 , const wxPoint
& rPos
133 , const wxSize
& rSize
135 , const wxString
& rsName
140 int nWidth
= rSize
.x
;
141 int nHeight
= rSize
.y
;
145 m_windowStyle
= lulStyle
;
146 m_frameMenuBar
= NULL
;
148 m_frameToolBar
= NULL
;
149 #endif //wxUSE_TOOLBAR
152 m_frameStatusBar
= NULL
;
153 #endif //wxUSE_STATUSBAR
155 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
160 m_windowId
= (int)NewControlId();
163 pParent
->AddChild(this);
167 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
170 bOk
= OS2Create( m_windowId
184 wxTopLevelWindows
.Append(this);
185 wxModelessWindows
.Append(this);
188 } // end of wxFrame::Create
192 m_isBeingDeleted
= TRUE
;
194 wxTopLevelWindows
.DeleteObject(this);
198 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
200 wxTheApp
->SetTopWindow(NULL
);
202 if (wxTheApp
->GetExitOnFrameDelete())
204 ::WinPostMsg(NULL
, WM_QUIT
, 0, 0);
208 wxModelessWindows
.DeleteObject(this);
211 // For some reason, wxWindows can activate another task altogether
212 // when a frame is destroyed after a modal dialog has been invoked.
213 // Try to bring the parent to the top.
215 // MT:Only do this if this frame is currently the active window, else weird
216 // things start to happen.
218 if (wxGetActiveWindow() == this)
220 if (GetParent() && GetParent()->GetHWND())
222 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
232 } // end of wxFrame::~wxFrame
235 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
237 void wxFrame::DoGetClientSize(
243 ::WinQueryWindowRect(GetHwnd(), &vRect
);
245 *pX
= vRect
.xRight
- vRect
.xLeft
;
247 *pY
= vRect
.yTop
- vRect
.yBottom
;
248 } // end of wxFrame::DoGetClientSize
251 // Set the client size (i.e. leave the calculation of borders etc.
254 void wxFrame::DoSetClientSize(
259 HWND hWnd
= GetHwnd();
263 ::WinQueryWindowRect(GetHwnd(), &vRect
);
264 ::WinQueryWindowRect(GetHwnd(), &vRect2
);
267 // Find the difference between the entire window (title bar and all)
268 // and the client area; add this to the new client size to move the
269 // window. Remember OS/2's backwards y coord system!
271 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
272 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
275 if ( GetStatusBar() )
280 GetStatusBar()->GetClientSize( &nStatusX
283 nActualHeight
+= nStatusY
;
285 #endif // wxUSE_STATUSBAR
287 wxPoint
vPoint(GetClientAreaOrigin());
288 nActualWidth
+= vPoint
.y
;
289 nActualHeight
+= vPoint
.x
;
293 vPointl
.x
= vRect2
.xLeft
;
294 vPointl
.y
= vRect2
.yTop
;
296 ::WinSetWindowPos( hWnd
302 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
305 wxSizeEvent
vEvent( wxSize( nWidth
310 vEvent
.SetEventObject(this);
311 GetEventHandler()->ProcessEvent(vEvent
);
312 } // end of wxFrame::DoSetClientSize
314 void wxFrame::DoGetSize(
321 ::WinQueryWindowRect(m_hFrame
, &vRect
);
322 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
323 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
324 } // end of wxFrame::DoGetSize
326 void wxFrame::DoGetPosition(
334 ::WinQueryWindowRect(m_hFrame
, &vRect
);
335 vPoint
.x
= vRect
.xLeft
;
338 // OS/2 is backwards [WIN32 it is vRect.yTop]
340 vPoint
.y
= vRect
.yBottom
;
344 } // end of wxFrame::DoGetPosition
346 // ----------------------------------------------------------------------------
347 // variations around ::ShowWindow()
348 // ----------------------------------------------------------------------------
350 void wxFrame::DoShowWindow(
354 ::WinShowWindow(m_hFrame
, (BOOL
)bShowCmd
);
355 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
356 } // end of wxFrame::DoShowWindow
364 DoShowWindow((int)bShow
);
368 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
370 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
371 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
372 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
373 ::WinEnableWindow(m_hFrame
, TRUE
);
374 vEvent
.SetEventObject(this);
375 GetEventHandler()->ProcessEvent(vEvent
);
380 // Try to highlight the correct window (the parent)
384 HWND hWndParent
= GetHwndOf(GetParent());
386 ::WinQueryWindowPos(hWndParent
, &vSwp
);
387 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
389 ::WinSetWindowPos( hWndParent
395 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
397 ::WinEnableWindow(hWndParent
, TRUE
);
401 } // end of wxFrame::Show
403 void wxFrame::Iconize(
407 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
408 } // end of wxFrame::Iconize
410 void wxFrame::Maximize(
413 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
414 } // end of wxFrame::Maximize
416 void wxFrame::Restore()
418 DoShowWindow(SWP_RESTORE
);
419 } // end of wxFrame::Restore
421 bool wxFrame::IsIconized() const
425 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
427 if (vSwp
.fl
& SWP_MINIMIZE
)
428 ((wxFrame
*)this)->m_bIconized
= TRUE
;
430 ((wxFrame
*)this)->m_bIconized
= FALSE
;
432 } // end of wxFrame::IsIconized
435 bool wxFrame::IsMaximized() const
440 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
441 return (vSwp
.fl
& SWP_MAXIMIZE
);
442 } // end of wxFrame::IsMaximized
444 void wxFrame::SetIcon(
448 wxFrameBase::SetIcon(rIcon
);
450 if ((m_icon
.GetHICON()) != NULLHANDLE
)
452 ::WinSendMsg( m_hFrame
454 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
457 ::WinSendMsg( m_hFrame
463 } // end of wxFrame::SetIcon
466 wxStatusBar
* wxFrame::OnCreateStatusBar(
470 , const wxString
& rName
473 wxStatusBar
* pStatusBar
= NULL
;
478 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
487 ::WinSetParent( pStatusBar
->GetHWND()
491 ::WinSetOwner( pStatusBar
->GetHWND()
497 if(::WinIsWindowShowing(m_hFrame
))
498 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
501 } // end of wxFrame::OnCreateStatusBar
503 void wxFrame::PositionStatusBar()
510 // Native status bar positions itself
512 if (m_frameStatusBar
)
521 ::WinQueryWindowRect(m_hFrame
, &vRect
);
522 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
524 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
525 nWidth
= vRect
.xRight
- vRect
.xLeft
;
527 m_frameStatusBar
->GetSize( &nStatbarWidth
532 // Since we wish the status bar to be directly under the client area,
533 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
535 m_frameStatusBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
536 ,vRect
.yBottom
- vFRect
.yBottom
540 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
542 vError
= ::WinGetLastError(vHabmain
);
543 sError
= wxPMErrorToStr(vError
);
544 wxLogError("Error setting parent for StautsBar. Error: %s\n", sError
);
548 } // end of wxFrame::PositionStatusBar
549 #endif // wxUSE_STATUSBAR
551 void wxFrame::DetachMenuBar()
555 m_frameMenuBar
->Detach();
556 m_frameMenuBar
= NULL
;
558 } // end of wxFrame::DetachMenuBar
560 void wxFrame::SetMenuBar(
566 HWND hTitlebar
= NULLHANDLE
;
567 HWND hHScroll
= NULLHANDLE
;
568 HWND hVScroll
= NULLHANDLE
;
569 HWND hMenuBar
= NULLHANDLE
;
581 // Actually remove the menu from the frame
583 m_hMenu
= (WXHMENU
)0;
584 InternalSetMenuBar();
586 else // set new non NULL menu bar
588 m_frameMenuBar
= NULL
;
591 // Can set a menubar several times.
592 // TODO: how to prevent a memory leak if you have a currently-unattached
593 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
594 // there are problems for MDI).
596 if (pMenuBar
->GetHMenu())
598 m_hMenu
= pMenuBar
->GetHMenu();
603 m_hMenu
= pMenuBar
->Create();
607 InternalSetMenuBar();
608 m_frameMenuBar
= pMenuBar
;
609 pMenuBar
->Attach(this);
611 } // end of wxFrame::SetMenuBar
613 void wxFrame::InternalSetMenuBar()
618 // Set the parent and owner of the menubar to be the frame
620 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
622 vError
= ::WinGetLastError(vHabmain
);
623 sError
= wxPMErrorToStr(vError
);
624 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
627 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
629 vError
= ::WinGetLastError(vHabmain
);
630 sError
= wxPMErrorToStr(vError
);
631 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
633 WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
634 } // end of wxFrame::InternalSetMenuBar
637 // Responds to colour changes, and passes event on to children
639 void wxFrame::OnSysColourChanged(
640 wxSysColourChangedEvent
& rEvent
643 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
647 if (m_frameStatusBar
)
649 wxSysColourChangedEvent vEvent2
;
651 vEvent2
.SetEventObject(m_frameStatusBar
);
652 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
654 #endif //wxUSE_STATUSBAR
657 // Propagate the event to the non-top-level children
659 wxWindow::OnSysColourChanged(rEvent
);
660 } // end of wxFrame::OnSysColourChanged
662 // Pass TRUE to show full screen, FALSE to restore.
663 bool wxFrame::ShowFullScreen(
673 m_bFsIsShowing
= TRUE
;
677 wxToolBar
* pTheToolBar
= GetToolBar();
678 #endif //wxUSE_TOOLBAR
681 wxStatusBar
* pTheStatusBar
= GetStatusBar();
682 #endif //wxUSE_STATUSBAR
688 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
689 #endif //wxUSE_TOOLBAR
693 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
694 #endif //wxUSE_STATUSBAR
698 // Zap the toolbar, menubar, and statusbar
700 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
702 pTheToolBar
->SetSize(-1,0);
703 pTheToolBar
->Show(FALSE
);
705 #endif //wxUSE_TOOLBAR
707 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
709 ::WinSetParent(m_hMenu
, GetHWND(), FALSE
);
710 ::WinSetOwner(m_hMenu
, GetHWND());
711 ::WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
716 // Save the number of fields in the statusbar
718 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
720 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
721 SetStatusBar((wxStatusBar
*) NULL
);
722 delete pTheStatusBar
;
725 m_nFsStatusBarFields
= 0;
726 #endif //wxUSE_STATUSBAR
729 // Zap the frame borders
733 // Save the 'normal' window style
735 m_lFsOldWindowStyle
= ::WinQueryWindowULong((HWND
)GetHWND(), QWL_STYLE
);
738 // Save the old position, width & height, maximize state
740 m_vFsOldSize
= GetRect();
741 m_bFsIsMaximized
= IsMaximized();
744 // Decide which window style flags to turn off
746 LONG lNewStyle
= m_lFsOldWindowStyle
;
749 if (lStyle
& wxFULLSCREEN_NOBORDER
)
750 lOffFlags
|= FCF_BORDER
;
751 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
752 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
754 lNewStyle
&= (~lOffFlags
);
757 // Change our window style to be compatible with full-screen mode
759 ::WinSetWindowULong((HWND
)GetHWND(), QWL_STYLE
, (ULONG
)lNewStyle
);
762 // Resize to the size of the desktop
768 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
769 nWidth
= vRect
.xRight
- vRect
.xLeft
;
771 // Rmember OS/2 is backwards!
773 nHeight
= vRect
.yTop
- vRect
.yBottom
;
780 // Now flush the window style cache and actually go full-screen
782 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
791 wxSizeEvent
vEvent( wxSize( nWidth
797 GetEventHandler()->ProcessEvent(vEvent
);
805 m_bFsIsShowing
= FALSE
;
808 wxToolBar
* pTheToolBar
= GetToolBar();
811 // Restore the toolbar, menubar, and statusbar
813 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
815 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
816 pTheToolBar
->Show(TRUE
);
818 #endif //wxUSE_TOOLBAR
821 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
823 CreateStatusBar(m_nFsStatusBarFields
);
824 // PositionStatusBar();
826 #endif //wxUSE_STATUSBAR
828 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
830 ::WinSetParent(m_hMenu
, GetHWND(), FALSE
);
831 ::WinSetOwner(m_hMenu
, GetHWND());
832 ::WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
834 Maximize(m_bFsIsMaximized
);
836 ::WinSetWindowULong( (HWND
)GetHWND()
838 ,(ULONG
)m_lFsOldWindowStyle
840 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
850 } // end of wxFrame::ShowFullScreen
855 bool wxFrame::OS2Create(
858 , const wxChar
* zWclass
860 , const wxChar
* zTitle
868 ULONG ulCreateFlags
= 0L;
869 ULONG ulStyleFlags
= 0L;
870 ULONG ulExtraFlags
= 0L;
871 FRAMECDATA vFrameCtlData
;
872 HWND hParent
= NULLHANDLE
;
873 HWND hTitlebar
= NULLHANDLE
;
874 HWND hHScroll
= NULLHANDLE
;
875 HWND hVScroll
= NULLHANDLE
;
876 HWND hFrame
= NULLHANDLE
;
877 HWND hClient
= NULLHANDLE
;
884 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
887 hParent
= GetWinHwnd(pParent
);
889 hParent
= HWND_DESKTOP
;
891 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
892 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
893 FCF_MINMAX
| FCF_TASKLIST
;
896 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
897 ulCreateFlags
= FCF_TASKLIST
;
899 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
901 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
902 ulCreateFlags
|= FCF_VERTSCROLL
;
903 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
904 ulCreateFlags
|= FCF_HORZSCROLL
;
905 if (ulStyle
& wxMINIMIZE_BOX
)
906 ulCreateFlags
|= FCF_MINBUTTON
;
907 if (ulStyle
& wxMAXIMIZE_BOX
)
908 ulCreateFlags
|= FCF_MAXBUTTON
;
909 if (ulStyle
& wxTHICK_FRAME
)
910 ulCreateFlags
|= FCF_DLGBORDER
;
911 if (ulStyle
& wxSYSTEM_MENU
)
912 ulCreateFlags
|= FCF_SYSMENU
;
913 if (ulStyle
& wxCAPTION
)
914 ulCreateFlags
|= FCF_TASKLIST
;
915 if (ulStyle
& wxCLIP_CHILDREN
)
917 // Invalid for frame windows under PM
920 if (ulStyle
& wxTINY_CAPTION_VERT
)
921 ulCreateFlags
|= FCF_TASKLIST
;
922 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
923 ulCreateFlags
|= FCF_TASKLIST
;
925 if ((ulStyle
& wxTHICK_FRAME
) == 0)
926 ulCreateFlags
|= FCF_BORDER
;
927 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
928 ulExtraFlags
= kFrameToolWindow
;
930 if (ulStyle
& wxSTAY_ON_TOP
)
931 ulCreateFlags
|= FCF_SYSMODAL
;
933 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
934 ulStyleFlags
|= WS_MINIMIZED
;
935 if (ulStyle
& wxMAXIMIZE
)
936 ulStyleFlags
|= WS_MAXIMIZED
;
939 // Clear the visible flag, we always call show
941 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
945 // Set the frame control block
947 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
948 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
949 vFrameCtlData
.hmodResources
= 0L;
950 vFrameCtlData
.idResources
= 0;
953 // Create the frame window: We break ranks with other ports now
954 // and instead of calling down into the base wxWindow class' OS2Create
955 // we do all our own stuff here. We will set the needed pieces
956 // of wxWindow manually, here.
959 hFrame
= ::WinCreateStdWindow( hParent
960 ,ulStyleFlags
// frame-window style
961 ,&ulCreateFlags
// window style
962 ,(PSZ
)zWclass
// class name
963 ,(PSZ
)zTitle
// window title
964 ,0L // default client style
965 ,NULLHANDLE
// resource in executable file
967 ,&hClient
// receives client window handle
971 vError
= ::WinGetLastError(vHabmain
);
972 sError
= wxPMErrorToStr(vError
);
973 wxLogError("Error creating frame. Error: %s\n", sError
);
978 // wxWindow class' m_hWnd set here and needed associations
982 wxAssociateWinWithHandle(m_hWnd
, this);
983 wxAssociateWinWithHandle(m_hFrame
, this);
986 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
987 // we manually subclass here because we don't want to use the main wxWndProc
990 m_fnOldWndProc
= (WXFARPROC
) ::WinSubclassWindow(m_hFrame
, (PFNWP
)wxFrameMainWndProc
);
993 // Now size everything. If adding a menu the client will need to be resized.
996 if (!::WinSetWindowPos( m_hFrame
1002 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1005 vError
= ::WinGetLastError(vHabmain
);
1006 sError
= wxPMErrorToStr(vError
);
1007 wxLogError("Error sizing frame. Error: %s\n", sError
);
1011 // We may have to be smarter here when variable sized toolbars are added!
1013 if (!::WinSetWindowPos( m_hWnd
1019 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1022 vError
= ::WinGetLastError(vHabmain
);
1023 sError
= wxPMErrorToStr(vError
);
1024 wxLogError("Error sizing client. Error: %s\n", sError
);
1029 uCtlCount = SHORT1FROMMP(::WinSendMsg(GetHWND(), WM_FORMATFRAME, (MPARAM)vSwp, (MPARAM)vRect));
1030 for (int i = 0; i < uCtlCount; i++)
1032 if (vSwp[i].hwnd == GetHWND())
1033 memcpy(&m_vSwp, &vSwp[i], sizeof(SWP));
1034 else if (vSwp[i].hwnd == m_hVScroll)
1035 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
1036 else if (vSwp[i].hwnd == m_hHScroll)
1037 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
1038 else if (vSwp[i].hwnd == m_hTitleBar)
1039 memcpy(&m_vSwpTitleBar, &vSwp[i], sizeof(SWP));
1042 } // end of wxFrame::OS2Create
1045 // Default activation behaviour - set the focus for the first child
1048 void wxFrame::OnActivate(
1049 wxActivateEvent
& rEvent
1052 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1054 pNode
= pNode
->GetNext())
1056 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1057 // but how to do it without duplicating the code?
1060 wxWindow
* pChild
= pNode
->GetData();
1062 if (!pChild
->IsTopLevel()
1064 && !wxDynamicCast(pChild
, wxToolBar
)
1065 #endif // wxUSE_TOOLBAR
1067 && !wxDynamicCast(pChild
, wxStatusBar
)
1068 #endif // wxUSE_STATUSBAR
1075 } // end of wxFrame::OnActivate
1077 // ----------------------------------------------------------------------------
1078 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1079 // from the client area, so the client area is what's really available for the
1081 // ----------------------------------------------------------------------------
1083 // Checks if there is a toolbar, and returns the first free client position
1084 wxPoint
wxFrame::GetClientAreaOrigin() const
1086 wxPoint
vPoint(0, 0);
1094 GetToolBar()->GetSize( &nWidth
1098 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1104 // PM is backwards from windows
1105 vPoint
.y
+= nHeight
;
1108 #endif //wxUSE_TOOLBAR
1110 } // end of wxFrame::GetClientAreaOrigin
1112 // ----------------------------------------------------------------------------
1113 // tool/status bar stuff
1114 // ----------------------------------------------------------------------------
1118 wxToolBar
* wxFrame::CreateToolBar(
1121 , const wxString
& rName
1124 if (wxFrameBase::CreateToolBar( lStyle
1131 return m_frameToolBar
;
1132 } // end of wxFrame::CreateToolBar
1134 void wxFrame::PositionToolBar()
1139 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1147 GetStatusBar()->GetClientSize( &nStatusX
1150 // PM is backwards from windows
1151 vRect
.yBottom
+= nStatusY
;
1153 #endif // wxUSE_STATUSBAR
1160 GetToolBar()->GetSize( &nToolbarWidth
1164 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1166 nToolbarHeight
= vRect
.yBottom
;
1170 nToolbarWidth
= vRect
.xRight
;
1174 // Use the 'real' PM position here
1176 GetToolBar()->SetSize( 0
1180 ,wxSIZE_NO_ADJUSTMENTS
1183 } // end of wxFrame::PositionToolBar
1184 #endif // wxUSE_TOOLBAR
1186 // ----------------------------------------------------------------------------
1187 // frame state (iconized/maximized/...)
1188 // ----------------------------------------------------------------------------
1191 // propagate our state change to all child frames: this allows us to emulate X
1192 // Windows behaviour where child frames float independently of the parent one
1193 // on the desktop, but are iconized/restored with it
1195 void wxFrame::IconizeChildFrames(
1199 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1201 pNode
= pNode
->GetNext() )
1203 wxWindow
* pWin
= pNode
->GetData();
1205 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1207 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1210 } // end of wxFrame::IconizeChildFrames
1212 // ===========================================================================
1213 // message processing
1214 // ===========================================================================
1216 // ---------------------------------------------------------------------------
1218 // ---------------------------------------------------------------------------
1219 bool wxFrame::OS2TranslateMessage(
1224 // try the menu bar accels
1226 wxMenuBar
* pMenuBar
= GetMenuBar();
1232 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1233 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1236 #endif //wxUSE_ACCEL
1237 } // end of wxFrame::OS2TranslateMessage
1239 // ---------------------------------------------------------------------------
1240 // our private (non virtual) message handlers
1241 // ---------------------------------------------------------------------------
1242 bool wxFrame::HandlePaint()
1246 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1251 // Icons in PM are the same as "pointers"
1256 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1258 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1261 // Hold a pointer to the dc so long as the OnPaint() message
1262 // is being processed
1265 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1268 // Erase background before painting or we get white background
1270 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1277 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1279 static const int nIconWidth
= 32;
1280 static const int nIconHeight
= 32;
1281 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1282 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1284 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1291 return wxWindow::HandlePaint();
1296 // nothing to paint - processed
1300 } // end of wxFrame::HandlePaint
1302 bool wxFrame::HandleSize(
1308 bool bProcessed
= FALSE
;
1314 // Only do it it if we were iconized before, otherwise resizing the
1315 // parent frame has a curious side effect of bringing it under it's
1321 // restore all child frames too
1323 IconizeChildFrames(FALSE
);
1330 m_bIconized
= FALSE
;
1335 // Iconize all child frames too
1337 IconizeChildFrames(TRUE
);
1345 // forward WM_SIZE to status bar control
1347 #if wxUSE_NATIVE_STATUSBAR
1348 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1350 wxSizeEvent
vEvent( wxSize( nX
1353 ,m_frameStatusBar
->GetId()
1356 vEvent
.SetEventObject(m_frameStatusBar
);
1357 m_frameStatusBar
->OnSize(vEvent
);
1359 #endif // wxUSE_NATIVE_STATUSBAR
1361 PositionStatusBar();
1364 #endif // wxUSE_TOOLBAR
1366 wxSizeEvent
vEvent( wxSize( nX
1372 vEvent
.SetEventObject(this);
1373 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1376 } // end of wxFrame::HandleSize
1378 bool wxFrame::HandleCommand(
1387 // In case it's e.g. a toolbar.
1389 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1392 return pWin
->OS2Command( nCmd
1398 // Handle here commands from menus and accelerators
1400 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1402 if (wxCurrentPopupMenu
)
1404 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1406 wxCurrentPopupMenu
= NULL
;
1408 return pPopupMenu
->OS2Command( nCmd
1413 if (ProcessCommand(nId
))
1419 } // end of wxFrame::HandleCommand
1421 bool wxFrame::HandleMenuSelect(
1432 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1434 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1436 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1438 vEvent
.SetEventObject(this);
1439 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1443 } // end of wxFrame::HandleMenuSelect
1445 // ---------------------------------------------------------------------------
1446 // Main Frame window proc
1447 // ---------------------------------------------------------------------------
1448 MRESULT EXPENTRY
wxFrameMainWndProc(
1455 MRESULT rc
= (MRESULT
)0;
1456 bool bProcessed
= FALSE
;
1457 wxFrame
* pWnd
= NULL
;
1459 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1462 case WM_QUERYFRAMECTLCOUNT
:
1463 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1465 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1467 rc
= MRFROMSHORT(uItemCount
);
1471 case WM_FORMATFRAME
:
1472 /////////////////////////////////////////////////////////////////////////////////
1473 // Applications that subclass frame controls may find that the frame is already
1474 // subclassed the number of frame controls is variable.
1475 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1476 // subclassed by calling the previous window procedure and modifying its result.
1477 ////////////////////////////////////////////////////////////////////////////////
1487 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1488 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1489 if(pWnd
->m_frameStatusBar
)
1491 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1492 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1493 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1494 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1496 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1498 vSwpStb
.x
= vRectl
.xLeft
- vRstb
.xLeft
;
1499 vSwpStb
.y
= vRectl
.yBottom
- vRstb
.yBottom
;
1500 vSwpStb
.cx
= vRectl
.xRight
- vRectl
.xLeft
- 1; //?? -1 ??
1501 vSwpStb
.cy
= nHeight
;
1502 vSwpStb
.fl
= SWP_SIZE
|SWP_MOVE
| SWP_SHOW
;
1503 vSwpStb
.hwnd
= pWnd
->m_frameStatusBar
->GetHWND();
1504 vSwpStb
.hwndInsertBehind
= HWND_TOP
;
1506 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1507 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1508 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1509 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1510 for(i
= 0; i
< nItemCount
; i
++)
1512 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1514 pSWP
[i
].x
= vRectl
.xLeft
;
1515 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1516 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1517 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1518 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1519 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1523 rc
= MRFROMSHORT(nItemCount
);
1528 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1529 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1531 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1534 } // end of wxFrameMainWndProc
1536 MRESULT EXPENTRY
wxFrameWndProc(
1544 // Trace all ulMsgs - useful for the debugging
1547 wxFrame
* pWnd
= NULL
;
1549 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1550 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1553 // When we get the first message for the HWND we just created, we associate
1554 // it with wxWindow stored in wxWndHook
1556 // if (!pWnd && wxWndHook)
1558 // wxAssociateWinWithHandle(hWnd, wxWndHook);
1559 // pWnd = wxWndHook;
1560 // wxWndHook = NULL;
1561 // pWnd->SetHWND((WXHWND)hWnd);
1564 MRESULT rc
= (MRESULT
)0;
1565 bool bProcessed
= FALSE
;
1568 // Stop right here if we don't have a valid handle in our wxWindow object.
1570 if (pWnd
&& !pWnd
->GetHWND())
1572 pWnd
->SetHWND((WXHWND
) hWnd
);
1573 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1582 // If we can't close, tell the system that we processed the
1583 // message - otherwise it would close us
1585 bProcessed
= !pWnd
->Close();
1593 hPS
= WinBeginPaint(hWnd
, 0L, &vRect
);
1594 WinFillRect(hPS
, &vRect
, CLR_BLUE
/* SYSCLR_WINDOW */);
1607 pWnd
->UnpackCommand( (WXWPARAM
)wParam
1613 rc
= (MRESULT
) pWnd
->HandleCommand( wId
1626 pWnd
->UnpackMenuSelect( wParam
1632 bProcessed
= pWnd
->HandleMenuSelect( wItem
1642 SHORT nScxold
= SHORT1FROMMP(wParam
); // Old horizontal size.
1643 SHORT nScyold
= SHORT2FROMMP(wParam
); // Old vertical size.
1644 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1645 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1647 lParam
= MRFROM2SHORT( nScxnew
- 20
1652 bProcessed
= pWnd
->HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1653 rc
= (MRESULT
)FALSE
;
1657 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1661 } // end of wxFrameWndProc
1663 MRESULT
wxFrame::OS2WindowProc(
1670 bool bProcessed
= FALSE
;
1676 // If we can't close, tell the system that we processed the
1677 // message - otherwise it would close us
1679 bProcessed
= !Close();
1688 UnpackCommand( (WXWPARAM
)wParam
1695 bProcessed
= HandleCommand( wId
1708 UnpackMenuSelect( wParam
1714 bProcessed
= HandleMenuSelect( wItem
1718 mRc
= (MRESULT
)TRUE
;
1723 bProcessed
= HandlePaint();
1726 case WM_ERASEBACKGROUND
:
1728 // Return TRUE to request PM to paint the window background
1729 // in SYSCLR_WINDOW.
1732 mRc
= (MRESULT
)(TRUE
);
1735 case CM_QUERYDRAGIMAGE
:
1740 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1742 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1743 mRc
= (MRESULT
)hIcon
;
1744 bProcessed
= mRc
!= 0;
1749 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1752 case WM_QUERYFRAMECTLCOUNT
:
1754 USHORT itemCount
= SHORT1FROMMR(OS2GetOldWndProc()(GetHWND(), uMessage
, wParam
, lParam
));
1756 if(m_frameStatusBar
)
1758 #endif //wxUSE_STATUSBAR
1761 mRc
= MRFROMSHORT( itemCount
);
1765 case WM_FORMATFRAME
:
1768 USHORT usClient
= 0;
1773 itemCount
= SHORT1FROMMR(OS2GetOldWndProc()(GetHWND(), uMessage
, wParam
, lParam
));
1774 pSWP
= (PSWP
)PVOIDFROMMP( wParam
);
1776 while(pSWP
[usClient
].hwnd
!= WinWindowFromID(GetHWND(), FID_CLIENT
)
1777 && usClient
< itemCount
)
1781 if(m_frameStatusBar
)
1785 m_frameStatusBar
->GetSize(NULL
, &height
);
1787 if(usClient
== itemCount
)
1789 // frame has no client window
1790 // using another method of calculation
1793 ::WinQueryWindowRect(GetHWND(), &wRectl
);
1794 ::WinMapWindowPoints(GetHWND(), HWND_DESKTOP
, (PPOINTL
)&wRectl
, 2);
1795 ::WinCalcFrameRect(GetHWND(), &wRectl
, TRUE
);
1796 ::WinMapWindowPoints(HWND_DESKTOP
, GetHWND(), (PPOINTL
)&wRectl
, 2);
1798 pSWP
[itemCount
].x
= wRectl
.xLeft
;
1799 pSWP
[itemCount
].y
= wRectl
.yBottom
;
1800 pSWP
[itemCount
].cx
= wRectl
.xRight
- wRectl
.xLeft
- 1;
1801 pSWP
[itemCount
].cy
= height
;
1802 pSWP
[itemCount
].fl
= SWP_SIZE
|
1805 pSWP
[itemCount
].hwnd
= m_frameStatusBar
->GetHWND();
1806 pSWP
[itemCount
].hwndInsertBehind
= HWND_TOP
;
1811 pSWP
[itemCount
].x
= pSWP
[usClient
].x
;
1812 pSWP
[itemCount
].y
= pSWP
[usClient
].y
;
1813 pSWP
[itemCount
].cx
= pSWP
[usClient
].cx
;
1814 pSWP
[itemCount
].cy
= height
;
1815 pSWP
[itemCount
].fl
= SWP_SIZE
|
1818 pSWP
[itemCount
].hwnd
= m_frameStatusBar
->GetHWND();
1819 pSWP
[itemCount
].hwndInsertBehind
= HWND_TOP
;
1820 pSWP
[usClient
].cy
-= height
;
1821 pSWP
[usClient
].y
+= height
;
1826 #endif //wxUSE_STATUSBAR
1829 mRc
= MRFROMSHORT(itemCount
);
1835 mRc
= wxWindow::OS2WindowProc( uMessage
1839 return (MRESULT
)mRc
;
1840 } // wxFrame::OS2WindowProc
1842 void wxFrame::SetClient(WXHWND c_Hwnd
)
1844 // Duh...nothing to do under OS/2
1847 void wxFrame::SetClient(
1851 wxWindow
* pOldClient
= this->GetClient();
1852 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1854 if(pOldClient
== pWindow
) // nothing to do
1856 if(pWindow
== NULL
) // just need to remove old client
1858 if(pOldClient
== NULL
) // nothing to do
1861 if(bClientHasFocus
)
1864 pOldClient
->Enable( FALSE
);
1865 pOldClient
->Show( FALSE
);
1866 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1867 // to avoid OS/2 bug need to update frame
1868 ::WinSendMsg((HWND
)this->GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1873 // Else need to change client
1878 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1881 pOldClient
->Enable(FALSE
);
1882 pOldClient
->Show(FALSE
);
1883 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1885 pWindow
->Reparent(this);
1886 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1887 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1889 pWindow
->Show(); // ensure client is showing
1890 if( this->IsShown() )
1893 ::WinSendMsg(GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1897 wxWindow
* wxFrame::GetClient()
1899 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(GetHWND(), FID_CLIENT
));