1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
21 #include "wx/dialog.h"
22 #include "wx/settings.h"
23 #include "wx/dcclient.h"
26 #include "wx/os2/private.h"
29 #include "wx/statusbr.h"
30 #include "wx/generic/statusbr.h"
31 #endif // wxUSE_STATUSBAR
34 #include "wx/toolbar.h"
35 #endif // wxUSE_TOOLBAR
37 #include "wx/menuitem.h"
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 extern wxWindowList wxModelessWindows
;
45 extern wxList WXDLLEXPORT wxPendingDelete
;
46 extern wxChar wxFrameClassName
[];
47 extern wxMenu
*wxCurrentPopupMenu
;
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
)
54 EVT_ACTIVATE(wxFrame::OnActivate
)
55 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
)
58 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
60 // ============================================================================
62 // ============================================================================
64 // ----------------------------------------------------------------------------
65 // static class members
66 // ----------------------------------------------------------------------------
68 #if wxUSE_NATIVE_STATUSBAR
69 bool wxFrame::m_bUseNativeStatusBar
= TRUE
;
71 bool wxFrame::m_bUseNativeStatusBar
= FALSE
;
74 // ----------------------------------------------------------------------------
75 // creation/destruction
76 // ----------------------------------------------------------------------------
85 // Data to save/restore when calling ShowFullScreen
87 m_lFsOldWindowStyle
= 0L;
88 m_nFsStatusBarFields
= 0;
89 m_nFsStatusBarHeight
= 0;
90 m_nFsToolBarHeight
= 0;
91 m_bFsIsMaximized
= FALSE
;
92 m_bFsIsShowing
= FALSE
;
94 m_pWinLastFocused
= (wxWindow
*)NULL
;
99 memset(&m_vSwp
, 0, sizeof(SWP
));
100 memset(&m_vSwpClient
, 0, sizeof(SWP
));
101 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
102 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
103 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
104 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
105 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
106 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
107 } // end of wxFrame::Init
109 bool wxFrame::Create(
112 , const wxString
& rsTitle
113 , const wxPoint
& rPos
114 , const wxSize
& rSize
116 , const wxString
& rsName
121 int nWidth
= rSize
.x
;
122 int nHeight
= rSize
.y
;
125 m_windowStyle
= lulStyle
;
126 m_frameMenuBar
= NULL
;
127 m_frameToolBar
= NULL
;
128 m_frameStatusBar
= NULL
;
130 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
135 m_windowId
= (int)NewControlId();
138 pParent
->AddChild(this);
142 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
146 wxTopLevelWindows
.Append(this);
148 OS2Create( m_windowId
160 wxModelessWindows
.Append(this);
162 } // end of wxFrame::Create
166 m_isBeingDeleted
= TRUE
;
168 wxTopLevelWindows
.DeleteObject(this);
172 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
174 wxTheApp
->SetTopWindow(NULL
);
176 if (wxTheApp
->GetExitOnFrameDelete())
178 ::WinPostMsg(NULL
, WM_QUIT
, 0, 0);
182 wxModelessWindows
.DeleteObject(this);
185 // For some reason, wxWindows can activate another task altogether
186 // when a frame is destroyed after a modal dialog has been invoked.
187 // Try to bring the parent to the top.
189 // MT:Only do this if this frame is currently the active window, else weird
190 // things start to happen.
192 if (wxGetActiveWindow() == this)
194 if (GetParent() && GetParent()->GetHWND())
196 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
206 } // end of wxFrame::~wxFrame
209 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
211 void wxFrame::DoGetClientSize(
217 // OS/2 PM's coordinates go from bottom-left not
218 // top-left thus the += instead of the -=
223 // PM has no GetClientRect that inherantly knows about the client window
224 // We have to explicitly go fetch it!
226 ::WinQueryWindowRect(GetHwnd(), &vRect
);
229 if ( GetStatusBar() )
234 GetStatusBar()->GetClientSize( &nStatusX
237 vRect
.yBottom
+= nStatusY
;
239 #endif // wxUSE_STATUSBAR
241 wxPoint
vPoint(GetClientAreaOrigin());
243 vRect
.yBottom
+= vPoint
.y
;
244 vRect
.xRight
-= vPoint
.x
;
250 } // end of wxFrame::DoGetClientSize
253 // Set the client size (i.e. leave the calculation of borders etc.
256 void wxFrame::DoSetClientSize(
261 HWND hWnd
= GetHwnd();
265 ::WinQueryWindowRect(GetHwnd(), &vRect
);
267 ::WinQueryWindowRect(GetHWND(), &vRect2
);
270 // Find the difference between the entire window (title bar and all)
271 // and the client area; add this to the new client size to move the
272 // window. Remember OS/2's backwards y coord system!
274 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
275 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
278 if ( GetStatusBar() )
283 GetStatusBar()->GetClientSize( &nStatusX
286 nActualHeight
+= nStatusY
;
288 #endif // wxUSE_STATUSBAR
290 wxPoint
vPoint(GetClientAreaOrigin());
291 nActualWidth
+= vPoint
.y
;
292 nActualHeight
+= vPoint
.x
;
296 vPointl
.x
= vRect2
.xLeft
;
297 vPointl
.y
= vRect2
.yTop
;
299 ::WinSetWindowPos( hWnd
305 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
308 wxSizeEvent
vEvent( wxSize( nWidth
313 vEvent
.SetEventObject(this);
314 GetEventHandler()->ProcessEvent(vEvent
);
315 } // end of wxFrame::DoSetClientSize
317 void wxFrame::DoGetSize(
324 ::WinQueryWindowRect(GetHWND(), &vRect
);
325 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
326 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
327 } // end of wxFrame::DoGetSize
329 void wxFrame::DoGetPosition(
337 ::WinQueryWindowRect(GetHWND(), &vRect
);
338 vPoint
.x
= vRect
.xLeft
;
341 // OS/2 is backwards [WIN32 it is vRect.yTop]
343 vPoint
.y
= vRect
.yBottom
;
347 } // end of wxFrame::DoGetPosition
349 // ----------------------------------------------------------------------------
350 // variations around ::ShowWindow()
351 // ----------------------------------------------------------------------------
353 void wxFrame::DoShowWindow(
357 ::WinShowWindow(GetHWND(), (BOOL
)bShowCmd
);
358 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
359 } // end of wxFrame::DoShowWindow
367 DoShowWindow((int)bShow
);
371 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
373 ::WinQueryWindowPos(GetHWND(), &vSwp
);
374 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
375 ::WinSendMsg(GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
376 ::WinEnableWindow(GetHWND(), TRUE
);
377 vEvent
.SetEventObject(this);
378 GetEventHandler()->ProcessEvent(vEvent
);
383 // Try to highlight the correct window (the parent)
387 HWND hWndParent
= GetHwndOf(GetParent());
389 ::WinQueryWindowPos(hWndParent
, &vSwp
);
390 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
392 ::WinSetWindowPos( hWndParent
398 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
400 ::WinEnableWindow(hWndParent
, TRUE
);
404 } // end of wxFrame::Show
406 void wxFrame::Iconize(
410 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
411 } // end of wxFrame::Iconize
413 void wxFrame::Maximize(
416 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
417 } // end of wxFrame::Maximize
419 void wxFrame::Restore()
421 DoShowWindow(SWP_RESTORE
);
422 } // end of wxFrame::Restore
424 bool wxFrame::IsIconized() const
428 ::WinQueryWindowPos(GetHwnd(), &vSwp
);
430 if (vSwp
.fl
& SWP_MINIMIZE
)
431 ((wxFrame
*)this)->m_bIconized
= TRUE
;
433 ((wxFrame
*)this)->m_bIconized
= FALSE
;
435 } // end of wxFrame::IsIconized
438 bool wxFrame::IsMaximized() const
443 ::WinQueryWindowPos(GetHWND(), &vSwp
);
444 return (vSwp
.fl
& SWP_MAXIMIZE
);
445 } // end of wxFrame::IsMaximized
447 void wxFrame::SetIcon(
451 wxFrameBase::SetIcon(rIcon
);
453 if ((m_icon
.GetHICON()) != NULLHANDLE
)
455 ::WinSendMsg( GetHWND()
457 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
460 ::WinSendMsg( GetHWND()
466 } // end of wxFrame::SetIcon
469 wxStatusBar
* wxFrame::OnCreateStatusBar(
473 , const wxString
& rName
476 wxStatusBar
* pStatusBar
= NULL
;
481 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
493 if( ::WinIsWindowShowing(GetHWND()) )
494 ::WinSendMsg(GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
497 } // end of wxFrame::OnCreateStatusBar
499 void wxFrame::PositionStatusBar()
506 // Native status bar positions itself
508 if (m_frameStatusBar
)
517 ::WinQueryWindowRect(GetHwnd(), &vRect
);
518 nWidth
= vRect
.xRight
- vRect
.xLeft
;
519 nHeight
= vRect
.yTop
- vRect
.yBottom
;
521 m_frameStatusBar
->GetSize( &nStatbarWidth
526 // Since we wish the status bar to be directly under the client area,
527 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
529 m_frameStatusBar
->SetSize( 0
534 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
536 vError
= ::WinGetLastError(vHabmain
);
537 sError
= wxPMErrorToStr(vError
);
538 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
541 if (!::WinSetWindowPos( m_frameStatusBar
->GetHWND()
547 ,SWP_SIZE
| SWP_MOVE
| SWP_SHOW
| SWP_ZORDER
550 vError
= ::WinGetLastError(vHabmain
);
551 sError
= wxPMErrorToStr(vError
);
552 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
556 } // end of wxFrame::PositionStatusBar
557 #endif // wxUSE_STATUSBAR
559 void wxFrame::DetachMenuBar()
563 m_frameMenuBar
->Detach();
564 m_frameMenuBar
= NULL
;
566 } // end of wxFrame::DetachMenuBar
568 void wxFrame::SetMenuBar(
574 HWND hClient
= NULLHANDLE
;
575 HWND hFrame
= NULLHANDLE
;
576 HWND hTitlebar
= NULLHANDLE
;
577 HWND hHScroll
= NULLHANDLE
;
578 HWND hVScroll
= NULLHANDLE
;
579 HWND hMenuBar
= NULLHANDLE
;
591 // Actually remove the menu from the frame
593 m_hMenu
= (WXHMENU
)0;
594 InternalSetMenuBar();
596 else // set new non NULL menu bar
598 m_frameMenuBar
= NULL
;
601 // Can set a menubar several times.
602 // TODO: how to prevent a memory leak if you have a currently-unattached
603 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
604 // there are problems for MDI).
606 if (pMenuBar
->GetHMenu())
608 m_hMenu
= pMenuBar
->GetHMenu();
613 m_hMenu
= pMenuBar
->Create();
617 InternalSetMenuBar();
618 m_frameMenuBar
= pMenuBar
;
619 pMenuBar
->Attach(this);
623 // Now resize the client to fit the new frame
625 WinQueryWindowPos(GetHWND(), &vSwp
);
626 hTitlebar
= WinWindowFromID(GetHWND(), FID_TITLEBAR
);
627 WinQueryWindowPos(hTitlebar
, &vSwpTitlebar
);
628 hHScroll
= WinWindowFromID(GetHWND(), FID_HORZSCROLL
);
629 WinQueryWindowPos(hHScroll
, &vSwpHScroll
);
630 hVScroll
= WinWindowFromID(GetHWND(), FID_VERTSCROLL
);
631 WinQueryWindowPos(hVScroll
, &vSwpVScroll
);
632 hMenuBar
= WinWindowFromID(GetHWND(), FID_MENU
);
633 WinQueryWindowPos(hMenuBar
, &vSwpMenu
);
634 WinSetWindowPos( GetHwnd()
637 ,(SV_CYSIZEBORDER
/2) + vSwpHScroll
.cy
/2
638 ,vSwp
.cx
- ((SV_CXSIZEBORDER
+ 1) + vSwpVScroll
.cx
)
639 ,vSwp
.cy
- ((SV_CYSIZEBORDER
+ 1) + vSwpTitlebar
.cy
+ vSwpMenu
.cy
+ vSwpHScroll
.cy
/2)
642 } // end of wxFrame::SetMenuBar
644 void wxFrame::InternalSetMenuBar()
649 // Set the parent and owner of the menubar to be the frame
651 if (!::WinSetParent(m_hMenu
, GetHWND(), FALSE
))
653 vError
= ::WinGetLastError(vHabmain
);
654 sError
= wxPMErrorToStr(vError
);
655 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
658 if (!::WinSetOwner(m_hMenu
, GetHWND()))
660 vError
= ::WinGetLastError(vHabmain
);
661 sError
= wxPMErrorToStr(vError
);
662 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
664 WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
665 } // end of wxFrame::InternalSetMenuBar
668 // Responds to colour changes, and passes event on to children
670 void wxFrame::OnSysColourChanged(
671 wxSysColourChangedEvent
& rEvent
674 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
677 if (m_frameStatusBar
)
679 wxSysColourChangedEvent vEvent2
;
681 vEvent2
.SetEventObject(m_frameStatusBar
);
682 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
686 // Propagate the event to the non-top-level children
688 wxWindow::OnSysColourChanged(rEvent
);
689 } // end of wxFrame::OnSysColourChanged
691 // Pass TRUE to show full screen, FALSE to restore.
692 bool wxFrame::ShowFullScreen(
702 m_bFsIsShowing
= TRUE
;
705 wxToolBar
* pTheToolBar
= GetToolBar();
706 wxStatusBar
* pTheStatusBar
= GetStatusBar();
711 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
713 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
716 // Zap the toolbar, menubar, and statusbar
718 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
720 pTheToolBar
->SetSize(-1,0);
721 pTheToolBar
->Show(FALSE
);
724 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
726 ::WinSetParent(m_hMenu
, GetHWND(), FALSE
);
727 ::WinSetOwner(m_hMenu
, GetHWND());
728 ::WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
732 // Save the number of fields in the statusbar
734 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
736 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
737 SetStatusBar((wxStatusBar
*) NULL
);
738 delete pTheStatusBar
;
741 m_nFsStatusBarFields
= 0;
744 // Zap the frame borders
748 // Save the 'normal' window style
750 m_lFsOldWindowStyle
= ::WinQueryWindowULong((HWND
)GetHWND(), QWL_STYLE
);
753 // Save the old position, width & height, maximize state
755 m_vFsOldSize
= GetRect();
756 m_bFsIsMaximized
= IsMaximized();
759 // Decide which window style flags to turn off
761 LONG lNewStyle
= m_lFsOldWindowStyle
;
764 if (lStyle
& wxFULLSCREEN_NOBORDER
)
765 lOffFlags
|= FCF_BORDER
;
766 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
767 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
769 lNewStyle
&= (~lOffFlags
);
772 // Change our window style to be compatible with full-screen mode
774 ::WinSetWindowULong((HWND
)GetHWND(), QWL_STYLE
, (ULONG
)lNewStyle
);
777 // Resize to the size of the desktop
783 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
784 nWidth
= vRect
.xRight
- vRect
.xLeft
;
786 // Rmember OS/2 is backwards!
788 nHeight
= vRect
.yTop
- vRect
.yBottom
;
795 // Now flush the window style cache and actually go full-screen
797 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
806 wxSizeEvent
vEvent( wxSize( nWidth
812 GetEventHandler()->ProcessEvent(vEvent
);
820 m_bFsIsShowing
= FALSE
;
822 wxToolBar
* pTheToolBar
= GetToolBar();
825 // Restore the toolbar, menubar, and statusbar
827 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
829 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
830 pTheToolBar
->Show(TRUE
);
833 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
835 CreateStatusBar(m_nFsStatusBarFields
);
836 // PositionStatusBar();
839 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
841 ::WinSetParent(m_hMenu
, GetHWND(), FALSE
);
842 ::WinSetOwner(m_hMenu
, GetHWND());
843 ::WinSendMsg((HWND
)GetHWND(), WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
845 Maximize(m_bFsIsMaximized
);
847 ::WinSetWindowULong( (HWND
)GetHWND()
849 ,(ULONG
)m_lFsOldWindowStyle
851 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
861 } // end of wxFrame::ShowFullScreen
866 bool wxFrame::OS2Create(
869 , const wxChar
* zWclass
871 , const wxChar
* zTitle
879 ULONG ulCreateFlags
= 0L;
880 ULONG ulStyleFlags
= 0L;
881 ULONG ulExtraFlags
= 0L;
882 FRAMECDATA vFrameCtlData
;
883 HWND hParent
= NULLHANDLE
;
884 HWND hClient
= NULLHANDLE
;
885 HWND hFrame
= NULLHANDLE
;
886 HWND hTitlebar
= NULLHANDLE
;
887 HWND hHScroll
= NULLHANDLE
;
888 HWND hVScroll
= 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
965 if (!wxWindow::OS2Create( hParent
973 ,(PVOID
)&vFrameCtlData
981 // Now need to subclass window.
984 //SubclassWin(GetHWND());
986 // ::WinCreateWindow(GetHWND(), WC_LISTBOX, "", WS_VISIBLE, 0, 0,
987 // 0, 0, GetHWND(), HWND_TOP, FID_CLIENT, NULL, NULL);
989 // Now size everything. If adding a menu the client will need to be resized.
992 if (!::WinSetWindowPos( GetHWND()
998 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1002 uCtlCount = SHORT1FROMMP(::WinSendMsg(GetHWND(), WM_FORMATFRAME, (MPARAM)vSwp, (MPARAM)vRect));
1003 for (int i = 0; i < uCtlCount; i++)
1005 if (vSwp[i].hwnd == GetHWND())
1006 memcpy(&m_vSwp, &vSwp[i], sizeof(SWP));
1007 else if (vSwp[i].hwnd == m_hVScroll)
1008 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
1009 else if (vSwp[i].hwnd == m_hHScroll)
1010 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
1011 else if (vSwp[i].hwnd == m_hTitleBar)
1012 memcpy(&m_vSwpTitleBar, &vSwp[i], sizeof(SWP));
1015 } // end of wxFrame::OS2Create
1018 // Default activation behaviour - set the focus for the first child
1021 void wxFrame::OnActivate(
1022 wxActivateEvent
& rEvent
1025 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1027 pNode
= pNode
->GetNext())
1029 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1030 // but how to do it without duplicating the code?
1033 wxWindow
* pChild
= pNode
->GetData();
1035 if (!pChild
->IsTopLevel()
1037 && !wxDynamicCast(pChild
, wxToolBar
)
1038 #endif // wxUSE_TOOLBAR
1040 && !wxDynamicCast(pChild
, wxStatusBar
)
1041 #endif // wxUSE_STATUSBAR
1048 } // end of wxFrame::OnActivate
1050 // ----------------------------------------------------------------------------
1051 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1052 // from the client area, so the client area is what's really available for the
1054 // ----------------------------------------------------------------------------
1056 // Checks if there is a toolbar, and returns the first free client position
1057 wxPoint
wxFrame::GetClientAreaOrigin() const
1059 wxPoint
vPoint(0, 0);
1066 GetToolBar()->GetSize( &nWidth
1070 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1076 // PM is backwards from windows
1077 vPoint
.y
+= nHeight
;
1081 } // end of wxFrame::GetClientAreaOrigin
1083 // ----------------------------------------------------------------------------
1084 // tool/status bar stuff
1085 // ----------------------------------------------------------------------------
1089 wxToolBar
* wxFrame::CreateToolBar(
1092 , const wxString
& rName
1095 if (wxFrameBase::CreateToolBar( lStyle
1102 return m_frameToolBar
;
1103 } // end of wxFrame::CreateToolBar
1105 void wxFrame::PositionToolBar()
1110 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1118 GetStatusBar()->GetClientSize( &nStatusX
1121 // PM is backwards from windows
1122 vRect
.yBottom
+= nStatusY
;
1124 #endif // wxUSE_STATUSBAR
1131 GetToolBar()->GetSize( &nToolbarWidth
1135 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1137 nToolbarHeight
= vRect
.yBottom
;
1141 nToolbarWidth
= vRect
.xRight
;
1145 // Use the 'real' PM position here
1147 GetToolBar()->SetSize( 0
1151 ,wxSIZE_NO_ADJUSTMENTS
1154 } // end of wxFrame::PositionToolBar
1155 #endif // wxUSE_TOOLBAR
1157 // ----------------------------------------------------------------------------
1158 // frame state (iconized/maximized/...)
1159 // ----------------------------------------------------------------------------
1162 // propagate our state change to all child frames: this allows us to emulate X
1163 // Windows behaviour where child frames float independently of the parent one
1164 // on the desktop, but are iconized/restored with it
1166 void wxFrame::IconizeChildFrames(
1170 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1172 pNode
= pNode
->GetNext() )
1174 wxWindow
* pWin
= pNode
->GetData();
1176 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1178 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1181 } // end of wxFrame::IconizeChildFrames
1183 // ===========================================================================
1184 // message processing
1185 // ===========================================================================
1187 // ---------------------------------------------------------------------------
1189 // ---------------------------------------------------------------------------
1190 bool wxFrame::OS2TranslateMessage(
1195 // try the menu bar accels
1197 wxMenuBar
* pMenuBar
= GetMenuBar();
1202 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1203 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1204 } // end of wxFrame::OS2TranslateMessage
1206 // ---------------------------------------------------------------------------
1207 // our private (non virtual) message handlers
1208 // ---------------------------------------------------------------------------
1209 bool wxFrame::HandlePaint()
1213 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1218 // Icons in PM are the same as "pointers"
1223 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1225 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1228 // Hold a pointer to the dc so long as the OnPaint() message
1229 // is being processed
1232 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1235 // Erase background before painting or we get white background
1237 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1244 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1246 static const int nIconWidth
= 32;
1247 static const int nIconHeight
= 32;
1248 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1249 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1251 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1258 /* DosBeep(500,500);
1262 hPS = WinBeginPaint(GetHwnd(), 0L, &vRect);
1263 WinFillRect(hPS, &vRect, SYSCLR_WINDOW);
1266 return wxWindow::HandlePaint();
1271 // nothing to paint - processed
1275 } // end of wxFrame::HandlePaint
1277 bool wxFrame::HandleSize(
1283 bool bProcessed
= FALSE
;
1289 // Only do it it if we were iconized before, otherwise resizing the
1290 // parent frame has a curious side effect of bringing it under it's
1296 // restore all child frames too
1298 IconizeChildFrames(FALSE
);
1305 m_bIconized
= FALSE
;
1310 // Iconize all child frames too
1312 IconizeChildFrames(TRUE
);
1320 // forward WM_SIZE to status bar control
1322 #if wxUSE_NATIVE_STATUSBAR
1323 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1325 wxSizeEvent
vEvent( wxSize( nX
1328 ,m_frameStatusBar
->GetId()
1331 vEvent
.SetEventObject(m_frameStatusBar
);
1332 m_frameStatusBar
->OnSize(vEvent
);
1334 #endif // wxUSE_NATIVE_STATUSBAR
1336 // PositionStatusBar();
1338 wxSizeEvent
vEvent( wxSize( nX
1344 vEvent
.SetEventObject(this);
1345 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1348 } // end of wxFrame::HandleSize
1350 bool wxFrame::HandleCommand(
1359 // In case it's e.g. a toolbar.
1361 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1364 return pWin
->OS2Command( nCmd
1370 // Handle here commands from menus and accelerators
1372 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1374 if (wxCurrentPopupMenu
)
1376 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1378 wxCurrentPopupMenu
= NULL
;
1380 return pPopupMenu
->OS2Command( nCmd
1385 if (ProcessCommand(nId
))
1391 } // end of wxFrame::HandleCommand
1393 bool wxFrame::HandleMenuSelect(
1401 /* This is wrong section according to IBM's documentation
1402 if (nFlags == 0xFFFF && hMenu == 0)
1405 // Menu was removed from screen
1409 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1416 // Don't give hints for separators (doesn't make sense) nor for the
1417 // items opening popup menus (they don't have them anyhow)
1428 rc
= WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1430 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1432 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1434 vEvent
.SetEventObject(this);
1435 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1439 } // end of wxFrame::HandleMenuSelect
1441 // ---------------------------------------------------------------------------
1442 // the window proc for wxFrame
1443 // ---------------------------------------------------------------------------
1445 MRESULT
wxFrame::OS2WindowProc(
1452 bool bProcessed
= FALSE
;
1458 // If we can't close, tell the system that we processed the
1459 // message - otherwise it would close us
1461 bProcessed
= !Close();
1470 UnpackCommand( (WXWPARAM
)wParam
1477 bProcessed
= HandleCommand( wId
1490 UnpackMenuSelect( wParam
1496 bProcessed
= HandleMenuSelect( wItem
1500 mRc
= (MRESULT
)TRUE
;
1505 bProcessed
= HandlePaint();
1508 case WM_ERASEBACKGROUND
:
1510 // Return TRUE to request PM to paint the window background
1511 // in SYSCLR_WINDOW.
1514 mRc
= (MRESULT
)(TRUE
);
1517 case CM_QUERYDRAGIMAGE
:
1522 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1524 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1525 mRc
= (MRESULT
)hIcon
;
1526 bProcessed
= mRc
!= 0;
1531 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1534 case WM_QUERYFRAMECTLCOUNT
:
1536 USHORT itemCount
= SHORT1FROMMR(OS2GetOldWndProc()(GetHWND(), uMessage
, wParam
, lParam
));
1537 if(m_frameStatusBar
)
1540 mRc
= MRFROMSHORT( itemCount
);
1544 case WM_FORMATFRAME
:
1547 USHORT usClient
= 0;
1552 itemCount
= SHORT1FROMMR(OS2GetOldWndProc()(GetHWND(), uMessage
, wParam
, lParam
));
1553 pSWP
= (PSWP
)PVOIDFROMMP( wParam
);
1555 while(pSWP
[usClient
].hwnd
!= WinWindowFromID(GetHWND(), FID_CLIENT
)
1556 && usClient
< itemCount
)
1559 if(m_frameStatusBar
)
1563 m_frameStatusBar
->GetSize(NULL
, &height
);
1565 if(usClient
== itemCount
)
1567 // frame has no client window
1568 // using another method of calculation
1571 ::WinQueryWindowRect(GetHWND(), &wRectl
);
1572 ::WinMapWindowPoints(GetHWND(), HWND_DESKTOP
, (PPOINTL
)&wRectl
, 2);
1573 ::WinCalcFrameRect(GetHWND(), &wRectl
, TRUE
);
1574 ::WinMapWindowPoints(HWND_DESKTOP
, GetHWND(), (PPOINTL
)&wRectl
, 2);
1576 pSWP
[itemCount
].x
= wRectl
.xLeft
;
1577 pSWP
[itemCount
].y
= wRectl
.yBottom
;
1578 pSWP
[itemCount
].cx
= wRectl
.xRight
- wRectl
.xLeft
- 1;
1579 pSWP
[itemCount
].cy
= height
;
1580 pSWP
[itemCount
].fl
= SWP_SIZE
|
1583 pSWP
[itemCount
].hwnd
= m_frameStatusBar
->GetHWND();
1584 pSWP
[itemCount
].hwndInsertBehind
= HWND_TOP
;
1589 pSWP
[itemCount
].x
= pSWP
[usClient
].x
;
1590 pSWP
[itemCount
].y
= pSWP
[usClient
].y
;
1591 pSWP
[itemCount
].cx
= pSWP
[usClient
].cx
;
1592 pSWP
[itemCount
].cy
= height
;
1593 pSWP
[itemCount
].fl
= SWP_SIZE
|
1596 pSWP
[itemCount
].hwnd
= m_frameStatusBar
->GetHWND();
1597 pSWP
[itemCount
].hwndInsertBehind
= HWND_TOP
;
1598 pSWP
[usClient
].cy
-= height
;
1599 pSWP
[usClient
].y
+= height
;
1605 mRc
= MRFROMSHORT(itemCount
);
1611 mRc
= wxWindow::OS2WindowProc( uMessage
1615 return (MRESULT
)mRc
;
1616 } // wxFrame::OS2WindowProc
1619 void wxFrame::SetClient(WXHWND c_Hwnd
)
1621 // Are we really need to implement it?
1624 void wxFrame::SetClient(wxWindow
* c_Window
)
1626 wxWindow
*oldClient
= this->GetClient();
1627 bool clientHasFocus
= oldClient
&& (oldClient
== wxWindow::FindFocus());
1629 if(oldClient
== c_Window
) // nothing to do
1632 if(c_Window
== NULL
) // just need to remove old client
1634 if(oldClient
== NULL
) // nothing to do
1637 if( clientHasFocus
)
1640 oldClient
->Enable( FALSE
);
1641 oldClient
->Show( FALSE
);
1642 ::WinSetWindowUShort(oldClient
->GetHWND(), QWS_ID
, (USHORT
)oldClient
->GetId());
1643 // to avoid OS/2 bug need to update frame
1644 ::WinSendMsg((HWND
)this->GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1648 // else need to change client
1649 if( clientHasFocus
)
1652 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1655 oldClient
->Enable( FALSE
);
1656 oldClient
->Show( FALSE
);
1657 ::WinSetWindowUShort(oldClient
->GetHWND(), QWS_ID
, (USHORT
)oldClient
->GetId());
1660 c_Window
->Reparent( this );
1661 ::WinSetWindowUShort(c_Window
->GetHWND(), QWS_ID
, FID_CLIENT
);
1663 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1665 c_Window
->Show(); // ensure client is showing
1667 if( this->IsShown() )
1670 ::WinSendMsg(GetHWND(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1674 wxWindow
*wxFrame::GetClient()
1676 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(GetHWND(), FID_CLIENT
));