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
[];
57 #if wxUSE_MENUS_NATIVE
58 extern wxMenu
*wxCurrentPopupMenu
;
61 extern void wxAssociateWinWithHandle( HWND hWnd
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
69 BEGIN_EVENT_TABLE(wxFrameOS2
, wxFrameBase
)
70 EVT_ACTIVATE(wxFrameOS2::OnActivate
)
71 EVT_SYS_COLOUR_CHANGED(wxFrameOS2::OnSysColourChanged
)
74 #ifndef __WXUNIVERSAL__
75 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
78 // ============================================================================
80 // ============================================================================
82 // ----------------------------------------------------------------------------
83 // static class members
84 // ----------------------------------------------------------------------------
87 #if wxUSE_NATIVE_STATUSBAR
88 bool wxFrameOS2::m_bUseNativeStatusBar
= TRUE
;
90 bool wxFrameOS2::m_bUseNativeStatusBar
= FALSE
;
93 #endif //wxUSE_STATUSBAR
95 // ----------------------------------------------------------------------------
96 // creation/destruction
97 // ----------------------------------------------------------------------------
99 void wxFrameOS2::Init()
106 // Data to save/restore when calling ShowFullScreen
108 m_lFsOldWindowStyle
= 0L;
109 m_nFsStatusBarFields
= 0;
110 m_nFsStatusBarHeight
= 0;
111 m_nFsToolBarHeight
= 0;
112 m_bFsIsMaximized
= FALSE
;
113 m_bFsIsShowing
= FALSE
;
115 m_pWinLastFocused
= (wxWindow
*)NULL
;
125 memset(&m_vSwp
, 0, sizeof(SWP
));
126 memset(&m_vSwpClient
, 0, sizeof(SWP
));
127 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
128 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
129 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
130 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
131 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
132 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
133 } // end of wxFrameOS2::Init
135 bool wxFrameOS2::Create(
138 , const wxString
& rsTitle
139 , const wxPoint
& rPos
140 , const wxSize
& rSize
142 , const wxString
& rsName
147 int nWidth
= rSize
.x
;
148 int nHeight
= rSize
.y
;
152 m_windowStyle
= lulStyle
;
153 m_frameMenuBar
= NULL
;
155 m_frameToolBar
= NULL
;
156 #endif //wxUSE_TOOLBAR
159 m_frameStatusBar
= NULL
;
160 #endif //wxUSE_STATUSBAR
162 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
167 m_windowId
= (int)NewControlId();
170 pParent
->AddChild(this);
174 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
177 bOk
= OS2Create( m_windowId
191 wxTopLevelWindows
.Append(this);
192 wxModelessWindows
.Append(this);
195 } // end of wxFrameOS2::Create
197 wxFrameOS2::~wxFrameOS2()
199 m_isBeingDeleted
= TRUE
;
201 wxTopLevelWindows
.DeleteObject(this);
205 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
207 wxTheApp
->SetTopWindow(NULL
);
209 if (wxTheApp
->GetExitOnFrameDelete())
211 ::WinPostMsg(NULL
, WM_QUIT
, 0, 0);
215 wxModelessWindows
.DeleteObject(this);
218 // For some reason, wxWindows can activate another task altogether
219 // when a frame is destroyed after a modal dialog has been invoked.
220 // Try to bring the parent to the top.
222 // MT:Only do this if this frame is currently the active window, else weird
223 // things start to happen.
225 if (wxGetActiveWindow() == this)
227 if (GetParent() && GetParent()->GetHWND())
229 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
239 } // end of wxFrameOS2::~wxFrame
242 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
244 void wxFrameOS2::DoGetClientSize(
250 ::WinQueryWindowRect(GetHwnd(), &vRect
);
253 // No need to use statusbar code as in WIN32 as the FORMATFRAME
254 // window procedure ensures PM knows about the new frame client
255 // size internally. A ::WinQueryWindowRect is all that is needed!
259 *pX
= vRect
.xRight
- vRect
.xLeft
;
261 *pY
= vRect
.yTop
- vRect
.yBottom
;
262 } // end of wxFrameOS2::DoGetClientSize
265 // Set the client size (i.e. leave the calculation of borders etc.
268 void wxFrameOS2::DoSetClientSize(
273 HWND hWnd
= GetHwnd();
277 ::WinQueryWindowRect(GetHwnd(), &vRect
);
278 ::WinQueryWindowRect(GetHwnd(), &vRect2
);
281 // Find the difference between the entire window (title bar and all)
282 // and the client area; add this to the new client size to move the
283 // window. Remember OS/2's backwards y coord system!
285 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
286 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
289 if ( GetStatusBar() )
294 GetStatusBar()->GetClientSize( &nStatusX
297 nActualHeight
+= nStatusY
;
299 #endif // wxUSE_STATUSBAR
301 wxPoint
vPoint(GetClientAreaOrigin());
302 nActualWidth
+= vPoint
.y
;
303 nActualHeight
+= vPoint
.x
;
307 vPointl
.x
= vRect2
.xLeft
;
308 vPointl
.y
= vRect2
.yTop
;
310 ::WinSetWindowPos( hWnd
316 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
319 wxSizeEvent
vEvent( wxSize( nWidth
324 vEvent
.SetEventObject(this);
325 GetEventHandler()->ProcessEvent(vEvent
);
326 } // end of wxFrameOS2::DoSetClientSize
328 void wxFrameOS2::DoGetSize(
335 ::WinQueryWindowRect(m_hFrame
, &vRect
);
336 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
337 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
338 } // end of wxFrameOS2::DoGetSize
340 void wxFrameOS2::DoGetPosition(
348 ::WinQueryWindowRect(m_hFrame
, &vRect
);
350 *pX
= vRect
.xRight
- vRect
.xLeft
;
351 *pY
= vRect
.yTop
- vRect
.yBottom
;
352 } // end of wxFrameOS2::DoGetPosition
354 // ----------------------------------------------------------------------------
355 // variations around ::ShowWindow()
356 // ----------------------------------------------------------------------------
358 void wxFrameOS2::DoShowWindow(
362 ::WinShowWindow(m_hFrame
, (BOOL
)bShowCmd
);
363 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
364 } // end of wxFrameOS2::DoShowWindow
366 bool wxFrameOS2::Show(
372 DoShowWindow((int)bShow
);
376 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
378 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
379 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
380 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
381 ::WinEnableWindow(m_hFrame
, TRUE
);
382 vEvent
.SetEventObject(this);
383 GetEventHandler()->ProcessEvent(vEvent
);
388 // Try to highlight the correct window (the parent)
392 HWND hWndParent
= GetHwndOf(GetParent());
394 ::WinQueryWindowPos(hWndParent
, &vSwp
);
395 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
397 ::WinSetWindowPos( hWndParent
403 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
405 ::WinEnableWindow(hWndParent
, TRUE
);
409 } // end of wxFrameOS2::Show
411 void wxFrameOS2::Iconize(
415 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
416 } // end of wxFrameOS2::Iconize
418 void wxFrameOS2::Maximize(
421 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
422 } // end of wxFrameOS2::Maximize
424 void wxFrameOS2::Restore()
426 DoShowWindow(SWP_RESTORE
);
427 } // end of wxFrameOS2::Restore
429 bool wxFrameOS2::IsIconized() const
433 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
435 if (vSwp
.fl
& SWP_MINIMIZE
)
436 ((wxFrame
*)this)->m_bIconized
= TRUE
;
438 ((wxFrame
*)this)->m_bIconized
= FALSE
;
440 } // end of wxFrameOS2::IsIconized
443 bool wxFrameOS2::IsMaximized() const
448 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
449 return (vSwp
.fl
& SWP_MAXIMIZE
);
450 } // end of wxFrameOS2::IsMaximized
452 void wxFrameOS2::SetIcon(
456 wxFrameBase::SetIcon(rIcon
);
458 if ((m_icon
.GetHICON()) != NULLHANDLE
)
460 ::WinSendMsg( m_hFrame
462 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
465 ::WinSendMsg( m_hFrame
471 } // end of wxFrameOS2::SetIcon
474 wxStatusBar
* wxFrameOS2::OnCreateStatusBar(
478 , const wxString
& rName
481 wxStatusBar
* pStatusBar
= NULL
;
486 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
495 ::WinSetParent( pStatusBar
->GetHWND()
499 ::WinSetOwner( pStatusBar
->GetHWND()
505 if(::WinIsWindowShowing(m_hFrame
))
506 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
509 } // end of wxFrameOS2::OnCreateStatusBar
511 void wxFrameOS2::PositionStatusBar()
518 // Native status bar positions itself
520 if (m_frameStatusBar
)
529 ::WinQueryWindowRect(m_hFrame
, &vRect
);
530 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
532 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
533 nWidth
= vRect
.xRight
- vRect
.xLeft
;
535 m_frameStatusBar
->GetSize( &nStatbarWidth
540 // Since we wish the status bar to be directly under the client area,
541 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
543 m_frameStatusBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
544 ,vRect
.yBottom
- vFRect
.yBottom
548 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
550 vError
= ::WinGetLastError(vHabmain
);
551 sError
= wxPMErrorToStr(vError
);
552 wxLogError("Error setting parent for StautsBar. Error: %s\n", sError
);
556 } // end of wxFrameOS2::PositionStatusBar
557 #endif // wxUSE_STATUSBAR
559 #if wxUSE_MENUS_NATIVE
560 void wxFrameOS2::DetachMenuBar()
564 m_frameMenuBar
->Detach();
565 m_frameMenuBar
= NULL
;
567 } // end of wxFrameOS2::DetachMenuBar
569 void wxFrameOS2::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((wxFrame
*)this);
620 } // end of wxFrameOS2::SetMenuBar
622 void wxFrameOS2::AttachMenuBar(
626 wxFrameBase::AttachMenuBar(pMenubar
);
628 m_frameMenuBar
= pMenubar
;
633 // Actually remove the menu from the frame
635 m_hMenu
= (WXHMENU
)0;
636 InternalSetMenuBar();
638 else // Set new non NULL menu bar
641 // Can set a menubar several times.
643 if (pMenubar
->GetHMenu())
645 m_hMenu
= pMenubar
->GetHMenu();
649 if (pMenubar
->IsAttached())
652 m_hMenu
= pMenubar
->Create();
657 InternalSetMenuBar();
659 } // end of wxFrameOS2::AttachMenuBar
661 void wxFrameOS2::InternalSetMenuBar()
666 // Set the parent and owner of the menubar to be the frame
668 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
670 vError
= ::WinGetLastError(vHabmain
);
671 sError
= wxPMErrorToStr(vError
);
672 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
675 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
677 vError
= ::WinGetLastError(vHabmain
);
678 sError
= wxPMErrorToStr(vError
);
679 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
681 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
682 } // end of wxFrameOS2::InternalSetMenuBar
683 #endif // wxUSE_MENUS_NATIVE
686 // Responds to colour changes, and passes event on to children
688 void wxFrameOS2::OnSysColourChanged(
689 wxSysColourChangedEvent
& rEvent
692 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
696 if (m_frameStatusBar
)
698 wxSysColourChangedEvent vEvent2
;
700 vEvent2
.SetEventObject(m_frameStatusBar
);
701 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
703 #endif //wxUSE_STATUSBAR
706 // Propagate the event to the non-top-level children
708 wxWindow::OnSysColourChanged(rEvent
);
709 } // end of wxFrameOS2::OnSysColourChanged
711 // Pass TRUE to show full screen, FALSE to restore.
712 bool wxFrameOS2::ShowFullScreen(
722 m_bFsIsShowing
= TRUE
;
726 wxToolBar
* pTheToolBar
= GetToolBar();
727 #endif //wxUSE_TOOLBAR
730 wxStatusBar
* pTheStatusBar
= GetStatusBar();
731 #endif //wxUSE_STATUSBAR
737 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
738 #endif //wxUSE_TOOLBAR
742 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
743 #endif //wxUSE_STATUSBAR
747 // Zap the toolbar, menubar, and statusbar
749 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
751 pTheToolBar
->SetSize(-1,0);
752 pTheToolBar
->Show(FALSE
);
754 #endif //wxUSE_TOOLBAR
756 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
758 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
759 ::WinSetOwner(m_hMenu
, m_hFrame
);
760 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
765 // Save the number of fields in the statusbar
767 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
769 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
770 SetStatusBar((wxStatusBar
*) NULL
);
771 delete pTheStatusBar
;
774 m_nFsStatusBarFields
= 0;
775 #endif //wxUSE_STATUSBAR
778 // Zap the frame borders
782 // Save the 'normal' window style
784 m_lFsOldWindowStyle
= ::WinQueryWindowULong(m_hFrame
, QWL_STYLE
);
787 // Save the old position, width & height, maximize state
789 m_vFsOldSize
= GetRect();
790 m_bFsIsMaximized
= IsMaximized();
793 // Decide which window style flags to turn off
795 LONG lNewStyle
= m_lFsOldWindowStyle
;
798 if (lStyle
& wxFULLSCREEN_NOBORDER
)
799 lOffFlags
|= FCF_BORDER
;
800 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
801 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
803 lNewStyle
&= (~lOffFlags
);
806 // Change our window style to be compatible with full-screen mode
808 ::WinSetWindowULong((HWND
)m_hFrame
, QWL_STYLE
, (ULONG
)lNewStyle
);
811 // Resize to the size of the desktop
817 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
818 nWidth
= vRect
.xRight
- vRect
.xLeft
;
820 // Rmember OS/2 is backwards!
822 nHeight
= vRect
.yTop
- vRect
.yBottom
;
829 // Now flush the window style cache and actually go full-screen
831 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
840 wxSizeEvent
vEvent( wxSize( nWidth
846 GetEventHandler()->ProcessEvent(vEvent
);
854 m_bFsIsShowing
= FALSE
;
857 wxToolBar
* pTheToolBar
= GetToolBar();
860 // Restore the toolbar, menubar, and statusbar
862 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
864 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
865 pTheToolBar
->Show(TRUE
);
867 #endif //wxUSE_TOOLBAR
870 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
872 CreateStatusBar(m_nFsStatusBarFields
);
873 // PositionStatusBar();
875 #endif //wxUSE_STATUSBAR
877 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
879 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
880 ::WinSetOwner(m_hMenu
, m_hFrame
);
881 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
883 Maximize(m_bFsIsMaximized
);
885 ::WinSetWindowULong( m_hFrame
887 ,(ULONG
)m_lFsOldWindowStyle
889 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
899 } // end of wxFrameOS2::ShowFullScreen
904 bool wxFrameOS2::OS2Create(
907 , const wxChar
* zWclass
909 , const wxChar
* zTitle
917 ULONG ulCreateFlags
= 0L;
918 ULONG ulStyleFlags
= 0L;
919 ULONG ulExtraFlags
= 0L;
920 FRAMECDATA vFrameCtlData
;
921 HWND hParent
= NULLHANDLE
;
922 HWND hTitlebar
= NULLHANDLE
;
923 HWND hHScroll
= NULLHANDLE
;
924 HWND hVScroll
= NULLHANDLE
;
925 HWND hFrame
= NULLHANDLE
;
926 HWND hClient
= NULLHANDLE
;
933 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
936 hParent
= GetWinHwnd(pParent
);
938 hParent
= HWND_DESKTOP
;
940 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
941 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
942 FCF_MINMAX
| FCF_TASKLIST
;
945 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
946 ulCreateFlags
= FCF_TASKLIST
;
948 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
950 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
951 ulCreateFlags
|= FCF_VERTSCROLL
;
952 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
953 ulCreateFlags
|= FCF_HORZSCROLL
;
954 if (ulStyle
& wxMINIMIZE_BOX
)
955 ulCreateFlags
|= FCF_MINBUTTON
;
956 if (ulStyle
& wxMAXIMIZE_BOX
)
957 ulCreateFlags
|= FCF_MAXBUTTON
;
958 if (ulStyle
& wxTHICK_FRAME
)
959 ulCreateFlags
|= FCF_DLGBORDER
;
960 if (ulStyle
& wxSYSTEM_MENU
)
961 ulCreateFlags
|= FCF_SYSMENU
;
962 if (ulStyle
& wxCAPTION
)
963 ulCreateFlags
|= FCF_TASKLIST
;
964 if (ulStyle
& wxCLIP_CHILDREN
)
966 // Invalid for frame windows under PM
969 if (ulStyle
& wxTINY_CAPTION_VERT
)
970 ulCreateFlags
|= FCF_TASKLIST
;
971 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
972 ulCreateFlags
|= FCF_TASKLIST
;
974 if ((ulStyle
& wxTHICK_FRAME
) == 0)
975 ulCreateFlags
|= FCF_BORDER
;
976 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
977 ulExtraFlags
= kFrameToolWindow
;
979 if (ulStyle
& wxSTAY_ON_TOP
)
980 ulCreateFlags
|= FCF_SYSMODAL
;
982 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
983 ulStyleFlags
|= WS_MINIMIZED
;
984 if (ulStyle
& wxMAXIMIZE
)
985 ulStyleFlags
|= WS_MAXIMIZED
;
988 // Clear the visible flag, we always call show
990 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
994 // Set the frame control block
996 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
997 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
998 vFrameCtlData
.hmodResources
= 0L;
999 vFrameCtlData
.idResources
= 0;
1002 // Create the frame window: We break ranks with other ports now
1003 // and instead of calling down into the base wxWindow class' OS2Create
1004 // we do all our own stuff here. We will set the needed pieces
1005 // of wxWindow manually, here.
1008 hFrame
= ::WinCreateStdWindow( hParent
1009 ,ulStyleFlags
// frame-window style
1010 ,&ulCreateFlags
// window style
1011 ,(PSZ
)zWclass
// class name
1012 ,(PSZ
)zTitle
// window title
1013 ,0L // default client style
1014 ,NULLHANDLE
// resource in executable file
1016 ,&hClient
// receives client window handle
1020 vError
= ::WinGetLastError(vHabmain
);
1021 sError
= wxPMErrorToStr(vError
);
1022 wxLogError("Error creating frame. Error: %s\n", sError
);
1027 // wxWindow class' m_hWnd set here and needed associations
1031 wxAssociateWinWithHandle(m_hWnd
, this);
1032 wxAssociateWinWithHandle(m_hFrame
, this);
1034 m_backgroundColour
.Set(wxString("GREY"));
1036 LONG lColor
= (LONG
)m_backgroundColour
.GetPixel();
1038 if (!::WinSetPresParam( m_hWnd
1044 vError
= ::WinGetLastError(vHabmain
);
1045 sError
= wxPMErrorToStr(vError
);
1046 wxLogError("Error creating frame. Error: %s\n", sError
);
1051 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
1052 // we manually subclass here because we don't want to use the main wxWndProc
1055 m_fnOldWndProc
= (WXFARPROC
) ::WinSubclassWindow(m_hFrame
, (PFNWP
)wxFrameMainWndProc
);
1058 // Now size everything. If adding a menu the client will need to be resized.
1061 if (!::WinSetWindowPos( m_hFrame
1067 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1070 vError
= ::WinGetLastError(vHabmain
);
1071 sError
= wxPMErrorToStr(vError
);
1072 wxLogError("Error sizing frame. Error: %s\n", sError
);
1076 // We may have to be smarter here when variable sized toolbars are added!
1078 if (!::WinSetWindowPos( m_hWnd
1084 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1087 vError
= ::WinGetLastError(vHabmain
);
1088 sError
= wxPMErrorToStr(vError
);
1089 wxLogError("Error sizing client. Error: %s\n", sError
);
1093 } // end of wxFrameOS2::OS2Create
1096 // Default activation behaviour - set the focus for the first child
1099 void wxFrameOS2::OnActivate(
1100 wxActivateEvent
& rEvent
1103 if ( rEvent
.GetActive() )
1105 // restore focus to the child which was last focused
1106 wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd
);
1108 wxWindow
* pParent
= m_pWinLastFocused
? m_pWinLastFocused
->GetParent()
1115 wxSetFocusToChild( pParent
1119 else // deactivating
1122 // Remember the last focused child if it is our child
1124 m_pWinLastFocused
= FindFocus();
1126 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1128 pNode
= pNode
->GetNext())
1130 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1131 // but how to do it without duplicating the code?
1134 wxWindow
* pChild
= pNode
->GetData();
1136 if (!pChild
->IsTopLevel()
1138 && !wxDynamicCast(pChild
, wxToolBar
)
1139 #endif // wxUSE_TOOLBAR
1141 && !wxDynamicCast(pChild
, wxStatusBar
)
1142 #endif // wxUSE_STATUSBAR
1150 } // end of wxFrameOS2::OnActivate
1152 // ----------------------------------------------------------------------------
1153 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1154 // from the client area, so the client area is what's really available for the
1156 // ----------------------------------------------------------------------------
1158 // Checks if there is a toolbar, and returns the first free client position
1159 wxPoint
wxFrameOS2::GetClientAreaOrigin() const
1161 wxPoint
vPoint(0, 0);
1169 GetToolBar()->GetSize( &nWidth
1173 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1179 // PM is backwards from windows
1180 vPoint
.y
+= nHeight
;
1183 #endif //wxUSE_TOOLBAR
1185 } // end of wxFrameOS2::GetClientAreaOrigin
1187 // ----------------------------------------------------------------------------
1188 // tool/status bar stuff
1189 // ----------------------------------------------------------------------------
1193 wxToolBar
* wxFrameOS2::CreateToolBar(
1196 , const wxString
& rName
1199 if (wxFrameBase::CreateToolBar( lStyle
1206 return m_frameToolBar
;
1207 } // end of wxFrameOS2::CreateToolBar
1209 void wxFrameOS2::PositionToolBar()
1214 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1222 GetStatusBar()->GetClientSize( &nStatusX
1225 // PM is backwards from windows
1226 vRect
.yBottom
+= nStatusY
;
1228 #endif // wxUSE_STATUSBAR
1230 if ( m_frameToolBar
)
1235 m_frameToolBar
->GetSize( &nToolbarWidth
1239 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1241 nToolbarHeight
= vRect
.yBottom
;
1245 nToolbarWidth
= vRect
.xRight
;
1249 // Use the 'real' PM position here
1251 GetToolBar()->SetSize( 0
1255 ,wxSIZE_NO_ADJUSTMENTS
1258 } // end of wxFrameOS2::PositionToolBar
1259 #endif // wxUSE_TOOLBAR
1261 // ----------------------------------------------------------------------------
1262 // frame state (iconized/maximized/...)
1263 // ----------------------------------------------------------------------------
1266 // propagate our state change to all child frames: this allows us to emulate X
1267 // Windows behaviour where child frames float independently of the parent one
1268 // on the desktop, but are iconized/restored with it
1270 void wxFrameOS2::IconizeChildFrames(
1274 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1276 pNode
= pNode
->GetNext() )
1278 wxWindow
* pWin
= pNode
->GetData();
1280 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1282 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1285 } // end of wxFrameOS2::IconizeChildFrames
1287 // ===========================================================================
1288 // message processing
1289 // ===========================================================================
1291 // ---------------------------------------------------------------------------
1293 // ---------------------------------------------------------------------------
1294 bool wxFrameOS2::OS2TranslateMessage(
1299 // try the menu bar accels
1301 wxMenuBar
* pMenuBar
= GetMenuBar();
1306 #if wxUSE_ACCEL && wxUSE_MENUS_NATIVE
1307 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1308 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1311 #endif //wxUSE_ACCEL
1312 } // end of wxFrameOS2::OS2TranslateMessage
1314 // ---------------------------------------------------------------------------
1315 // our private (non virtual) message handlers
1316 // ---------------------------------------------------------------------------
1317 bool wxFrameOS2::HandlePaint()
1321 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1326 // Icons in PM are the same as "pointers"
1331 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1333 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1336 // Hold a pointer to the dc so long as the OnPaint() message
1337 // is being processed
1340 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1343 // Erase background before painting or we get white background
1345 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1352 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1354 static const int nIconWidth
= 32;
1355 static const int nIconHeight
= 32;
1356 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1357 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1359 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1366 return(wxWindow::HandlePaint());
1371 // nothing to paint - processed
1375 } // end of wxFrameOS2::HandlePaint
1377 bool wxFrameOS2::HandleSize(
1383 bool bProcessed
= FALSE
;
1389 // Only do it it if we were iconized before, otherwise resizing the
1390 // parent frame has a curious side effect of bringing it under it's
1396 // restore all child frames too
1398 IconizeChildFrames(FALSE
);
1399 (void)SendIconizeEvent(FALSE
);
1406 m_bIconized
= FALSE
;
1411 // Iconize all child frames too
1413 IconizeChildFrames(TRUE
);
1414 (void)SendIconizeEvent();
1422 // forward WM_SIZE to status bar control
1424 #if wxUSE_NATIVE_STATUSBAR
1425 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1427 wxSizeEvent
vEvent( wxSize( nX
1430 ,m_frameStatusBar
->GetId()
1433 vEvent
.SetEventObject(m_frameStatusBar
);
1434 m_frameStatusBar
->OnSize(vEvent
);
1436 #endif // wxUSE_NATIVE_STATUSBAR
1438 PositionStatusBar();
1441 #endif // wxUSE_TOOLBAR
1443 wxSizeEvent
vEvent( wxSize( nX
1449 vEvent
.SetEventObject(this);
1450 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1453 } // end of wxFrameOS2::HandleSize
1455 bool wxFrameOS2::HandleCommand(
1464 // In case it's e.g. a toolbar.
1466 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1469 return pWin
->OS2Command( nCmd
1475 // Handle here commands from menus and accelerators
1477 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1479 #if wxUSE_MENUS_NATIVE
1480 if (wxCurrentPopupMenu
)
1482 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1484 wxCurrentPopupMenu
= NULL
;
1486 return pPopupMenu
->OS2Command( nCmd
1493 if (ProcessCommand(nId
))
1499 } // end of wxFrameOS2::HandleCommand
1501 bool wxFrameOS2::HandleMenuSelect(
1512 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1514 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1516 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1518 vEvent
.SetEventObject(this);
1519 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1523 } // end of wxFrameOS2::HandleMenuSelect
1525 // ---------------------------------------------------------------------------
1526 // Main Frame window proc
1527 // ---------------------------------------------------------------------------
1528 MRESULT EXPENTRY
wxFrameMainWndProc(
1535 MRESULT rc
= (MRESULT
)0;
1536 bool bProcessed
= FALSE
;
1537 wxFrame
* pWnd
= NULL
;
1539 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1542 case WM_QUERYFRAMECTLCOUNT
:
1543 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1545 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1547 rc
= MRFROMSHORT(uItemCount
);
1551 case WM_FORMATFRAME
:
1552 /////////////////////////////////////////////////////////////////////////////////
1553 // Applications that subclass frame controls may find that the frame is already
1554 // subclassed the number of frame controls is variable.
1555 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1556 // subclassed by calling the previous window procedure and modifying its result.
1557 ////////////////////////////////////////////////////////////////////////////////
1567 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1568 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1569 if(pWnd
->m_frameStatusBar
)
1571 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1572 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1573 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1574 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1576 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1578 vSwpStb
.x
= vRectl
.xLeft
- vRstb
.xLeft
;
1579 vSwpStb
.y
= vRectl
.yBottom
- vRstb
.yBottom
;
1580 vSwpStb
.cx
= vRectl
.xRight
- vRectl
.xLeft
- 1; //?? -1 ??
1581 vSwpStb
.cy
= nHeight
;
1582 vSwpStb
.fl
= SWP_SIZE
|SWP_MOVE
| SWP_SHOW
;
1583 vSwpStb
.hwnd
= pWnd
->m_frameStatusBar
->GetHWND();
1584 vSwpStb
.hwndInsertBehind
= HWND_TOP
;
1586 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1587 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1588 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1589 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1590 for(i
= 0; i
< nItemCount
; i
++)
1592 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1594 pSWP
[i
].x
= vRectl
.xLeft
;
1595 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1596 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1597 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1598 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1599 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1603 rc
= MRFROMSHORT(nItemCount
);
1608 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1609 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1611 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1614 } // end of wxFrameMainWndProc
1616 MRESULT EXPENTRY
wxFrameWndProc(
1624 // Trace all ulMsgs - useful for the debugging
1627 wxFrame
* pWnd
= NULL
;
1629 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1630 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1633 // When we get the first message for the HWND we just created, we associate
1634 // it with wxWindow stored in wxWndHook
1637 MRESULT rc
= (MRESULT
)0;
1638 bool bProcessed
= FALSE
;
1641 // Stop right here if we don't have a valid handle in our wxWindow object.
1643 if (pWnd
&& !pWnd
->GetHWND())
1645 pWnd
->SetHWND((WXHWND
) hWnd
);
1646 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1652 rc
= pWnd
->OS2WindowProc(ulMsg
, wParam
, lParam
);
1654 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1657 } // end of wxFrameWndProc
1659 MRESULT
wxFrameOS2::OS2WindowProc(
1666 bool bProcessed
= FALSE
;
1672 // If we can't close, tell the system that we processed the
1673 // message - otherwise it would close us
1675 bProcessed
= !Close();
1679 bProcessed
= HandlePaint();
1680 mRc
= (MRESULT
)FALSE
;
1683 case WM_ERASEBACKGROUND
:
1685 // Returning TRUE to requests PM to paint the window background
1686 // in SYSCLR_WINDOW. We capture this here because the PS returned
1687 // in Frames is the PS for the whole frame, which we can't really
1688 // use at all. If you want to paint a different background, do it
1689 // in an OnPaint using a wxPaintDC.
1691 mRc
= (MRESULT
)(TRUE
);
1700 UnpackCommand( (WXWPARAM
)wParam
1707 bProcessed
= HandleCommand( wId
1720 UnpackMenuSelect( wParam
1726 bProcessed
= HandleMenuSelect( wItem
1730 mRc
= (MRESULT
)TRUE
;
1736 SHORT nScxold
= SHORT1FROMMP(wParam
); // Old horizontal size.
1737 SHORT nScyold
= SHORT2FROMMP(wParam
); // Old vertical size.
1738 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1739 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1741 lParam
= MRFROM2SHORT( nScxnew
- 20
1745 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1746 mRc
= (MRESULT
)FALSE
;
1749 case CM_QUERYDRAGIMAGE
:
1754 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1756 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1757 mRc
= (MRESULT
)hIcon
;
1758 bProcessed
= mRc
!= 0;
1764 mRc
= wxWindow::OS2WindowProc( uMessage
1768 return (MRESULT
)mRc
;
1769 } // wxFrameOS2::OS2WindowProc
1771 void wxFrameOS2::SetClient(WXHWND c_Hwnd
)
1773 // Duh...nothing to do under OS/2
1776 void wxFrameOS2::SetClient(
1780 wxWindow
* pOldClient
= this->GetClient();
1781 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1783 if(pOldClient
== pWindow
) // nothing to do
1785 if(pWindow
== NULL
) // just need to remove old client
1787 if(pOldClient
== NULL
) // nothing to do
1790 if(bClientHasFocus
)
1793 pOldClient
->Enable( FALSE
);
1794 pOldClient
->Show( FALSE
);
1795 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1796 // to avoid OS/2 bug need to update frame
1797 ::WinSendMsg((HWND
)this->GetFrame(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1802 // Else need to change client
1807 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1810 pOldClient
->Enable(FALSE
);
1811 pOldClient
->Show(FALSE
);
1812 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1814 pWindow
->Reparent(this);
1815 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1816 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1818 pWindow
->Show(); // ensure client is showing
1819 if( this->IsShown() )
1822 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1826 wxWindow
* wxFrameOS2::GetClient()
1828 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(m_hFrame
, FID_CLIENT
));