1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
17 #include "wx/object.h"
18 #include "wx/dynarray.h"
21 #include "wx/string.h"
30 #include "wx/dialog.h"
31 #include "wx/settings.h"
32 #include "wx/dcclient.h"
35 #include "wx/os2/private.h"
38 #include "wx/statusbr.h"
39 #include "wx/generic/statusbr.h"
40 #endif // wxUSE_STATUSBAR
43 #include "wx/toolbar.h"
44 #endif // wxUSE_TOOLBAR
46 #include "wx/menuitem.h"
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 extern wxWindowList wxModelessWindows
;
54 extern wxList WXDLLEXPORT wxPendingDelete
;
55 extern wxChar wxFrameClassName
[];
56 extern wxMenu
*wxCurrentPopupMenu
;
58 extern void wxAssociateWinWithHandle( HWND hWnd
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 BEGIN_EVENT_TABLE(wxFrameOS2
, wxFrameBase
)
67 EVT_ACTIVATE(wxFrameOS2::OnActivate
)
68 EVT_SYS_COLOUR_CHANGED(wxFrameOS2::OnSysColourChanged
)
71 IMPLEMENT_DYNAMIC_CLASS(wxFrameOS2
, wxWindow
)
73 #ifndef __WXUNIVERSAL__
74 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxFrameMSW
)
77 // ============================================================================
79 // ============================================================================
81 // ----------------------------------------------------------------------------
82 // static class members
83 // ----------------------------------------------------------------------------
86 #if wxUSE_NATIVE_STATUSBAR
87 bool wxFrameOS2::m_bUseNativeStatusBar
= TRUE
;
89 bool wxFrameOS2::m_bUseNativeStatusBar
= FALSE
;
92 #endif //wxUSE_STATUSBAR
94 // ----------------------------------------------------------------------------
95 // creation/destruction
96 // ----------------------------------------------------------------------------
98 void wxFrameOS2::Init()
105 // Data to save/restore when calling ShowFullScreen
107 m_lFsOldWindowStyle
= 0L;
108 m_nFsStatusBarFields
= 0;
109 m_nFsStatusBarHeight
= 0;
110 m_nFsToolBarHeight
= 0;
111 m_bFsIsMaximized
= FALSE
;
112 m_bFsIsShowing
= FALSE
;
114 m_pWinLastFocused
= (wxWindow
*)NULL
;
124 memset(&m_vSwp
, 0, sizeof(SWP
));
125 memset(&m_vSwpClient
, 0, sizeof(SWP
));
126 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
127 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
128 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
129 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
130 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
131 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
132 } // end of wxFrameOS2::Init
134 bool wxFrameOS2::Create(
137 , const wxString
& rsTitle
138 , const wxPoint
& rPos
139 , const wxSize
& rSize
141 , const wxString
& rsName
146 int nWidth
= rSize
.x
;
147 int nHeight
= rSize
.y
;
151 m_windowStyle
= lulStyle
;
152 m_frameMenuBar
= NULL
;
154 m_frameToolBar
= NULL
;
155 #endif //wxUSE_TOOLBAR
158 m_frameStatusBar
= NULL
;
159 #endif //wxUSE_STATUSBAR
161 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
166 m_windowId
= (int)NewControlId();
169 pParent
->AddChild(this);
173 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
176 bOk
= OS2Create( m_windowId
190 wxTopLevelWindows
.Append(this);
191 wxModelessWindows
.Append(this);
194 } // end of wxFrameOS2::Create
196 wxFrameOS2::~wxFrameOS2()
198 m_isBeingDeleted
= TRUE
;
200 wxTopLevelWindows
.DeleteObject(this);
204 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
206 wxTheApp
->SetTopWindow(NULL
);
208 if (wxTheApp
->GetExitOnFrameDelete())
210 ::WinPostMsg(NULL
, WM_QUIT
, 0, 0);
214 wxModelessWindows
.DeleteObject(this);
217 // For some reason, wxWindows can activate another task altogether
218 // when a frame is destroyed after a modal dialog has been invoked.
219 // Try to bring the parent to the top.
221 // MT:Only do this if this frame is currently the active window, else weird
222 // things start to happen.
224 if (wxGetActiveWindow() == this)
226 if (GetParent() && GetParent()->GetHWND())
228 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
238 } // end of wxFrameOS2::~wxFrame
241 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
243 void wxFrameOS2::DoGetClientSize(
249 ::WinQueryWindowRect(GetHwnd(), &vRect
);
252 // No need to use statusbar code as in WIN32 as the FORMATFRAME
253 // window procedure ensures PM knows about the new frame client
254 // size internally. A ::WinQueryWindowRect is all that is needed!
258 *pX
= vRect
.xRight
- vRect
.xLeft
;
260 *pY
= vRect
.yTop
- vRect
.yBottom
;
261 } // end of wxFrameOS2::DoGetClientSize
264 // Set the client size (i.e. leave the calculation of borders etc.
267 void wxFrameOS2::DoSetClientSize(
272 HWND hWnd
= GetHwnd();
276 ::WinQueryWindowRect(GetHwnd(), &vRect
);
277 ::WinQueryWindowRect(GetHwnd(), &vRect2
);
280 // Find the difference between the entire window (title bar and all)
281 // and the client area; add this to the new client size to move the
282 // window. Remember OS/2's backwards y coord system!
284 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
285 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
288 if ( GetStatusBar() )
293 GetStatusBar()->GetClientSize( &nStatusX
296 nActualHeight
+= nStatusY
;
298 #endif // wxUSE_STATUSBAR
300 wxPoint
vPoint(GetClientAreaOrigin());
301 nActualWidth
+= vPoint
.y
;
302 nActualHeight
+= vPoint
.x
;
306 vPointl
.x
= vRect2
.xLeft
;
307 vPointl
.y
= vRect2
.yTop
;
309 ::WinSetWindowPos( hWnd
315 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
318 wxSizeEvent
vEvent( wxSize( nWidth
323 vEvent
.SetEventObject(this);
324 GetEventHandler()->ProcessEvent(vEvent
);
325 } // end of wxFrameOS2::DoSetClientSize
327 void wxFrameOS2::DoGetSize(
334 ::WinQueryWindowRect(m_hFrame
, &vRect
);
335 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
336 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
337 } // end of wxFrameOS2::DoGetSize
339 void wxFrameOS2::DoGetPosition(
347 ::WinQueryWindowRect(m_hFrame
, &vRect
);
349 *pX
= vRect
.xRight
- vRect
.xLeft
;
350 *pY
= vRect
.yTop
- vRect
.yBottom
;
351 } // end of wxFrameOS2::DoGetPosition
353 // ----------------------------------------------------------------------------
354 // variations around ::ShowWindow()
355 // ----------------------------------------------------------------------------
357 void wxFrameOS2::DoShowWindow(
361 ::WinShowWindow(m_hFrame
, (BOOL
)bShowCmd
);
362 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
363 } // end of wxFrameOS2::DoShowWindow
365 bool wxFrameOS2::Show(
371 DoShowWindow((int)bShow
);
375 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
377 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
378 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
379 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
380 ::WinEnableWindow(m_hFrame
, TRUE
);
381 vEvent
.SetEventObject(this);
382 GetEventHandler()->ProcessEvent(vEvent
);
387 // Try to highlight the correct window (the parent)
391 HWND hWndParent
= GetHwndOf(GetParent());
393 ::WinQueryWindowPos(hWndParent
, &vSwp
);
394 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
396 ::WinSetWindowPos( hWndParent
402 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
404 ::WinEnableWindow(hWndParent
, TRUE
);
408 } // end of wxFrameOS2::Show
410 void wxFrameOS2::Iconize(
414 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
415 } // end of wxFrameOS2::Iconize
417 void wxFrameOS2::Maximize(
420 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
421 } // end of wxFrameOS2::Maximize
423 void wxFrameOS2::Restore()
425 DoShowWindow(SWP_RESTORE
);
426 } // end of wxFrameOS2::Restore
428 bool wxFrameOS2::IsIconized() const
432 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
434 if (vSwp
.fl
& SWP_MINIMIZE
)
435 ((wxFrame
*)this)->m_bIconized
= TRUE
;
437 ((wxFrame
*)this)->m_bIconized
= FALSE
;
439 } // end of wxFrameOS2::IsIconized
442 bool wxFrameOS2::IsMaximized() const
447 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
448 return (vSwp
.fl
& SWP_MAXIMIZE
);
449 } // end of wxFrameOS2::IsMaximized
451 void wxFrameOS2::SetIcon(
455 wxFrameBase::SetIcon(rIcon
);
457 if ((m_icon
.GetHICON()) != NULLHANDLE
)
459 ::WinSendMsg( m_hFrame
461 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
464 ::WinSendMsg( m_hFrame
470 } // end of wxFrameOS2::SetIcon
473 wxStatusBar
* wxFrameOS2::OnCreateStatusBar(
477 , const wxString
& rName
480 wxStatusBar
* pStatusBar
= NULL
;
485 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
494 ::WinSetParent( pStatusBar
->GetHWND()
498 ::WinSetOwner( pStatusBar
->GetHWND()
504 if(::WinIsWindowShowing(m_hFrame
))
505 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
508 } // end of wxFrameOS2::OnCreateStatusBar
510 void wxFrameOS2::PositionStatusBar()
517 // Native status bar positions itself
519 if (m_frameStatusBar
)
528 ::WinQueryWindowRect(m_hFrame
, &vRect
);
529 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
531 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
532 nWidth
= vRect
.xRight
- vRect
.xLeft
;
534 m_frameStatusBar
->GetSize( &nStatbarWidth
539 // Since we wish the status bar to be directly under the client area,
540 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
542 m_frameStatusBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
543 ,vRect
.yBottom
- vFRect
.yBottom
547 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
549 vError
= ::WinGetLastError(vHabmain
);
550 sError
= wxPMErrorToStr(vError
);
551 wxLogError("Error setting parent for StautsBar. Error: %s\n", sError
);
555 } // end of wxFrameOS2::PositionStatusBar
556 #endif // wxUSE_STATUSBAR
558 void wxFrameOS2::DetachMenuBar()
562 m_frameMenuBar
->Detach();
563 m_frameMenuBar
= NULL
;
565 } // end of wxFrameOS2::DetachMenuBar
567 void wxFrameOS2::SetMenuBar(
573 HWND hTitlebar
= NULLHANDLE
;
574 HWND hHScroll
= NULLHANDLE
;
575 HWND hVScroll
= NULLHANDLE
;
576 HWND hMenuBar
= NULLHANDLE
;
588 // Actually remove the menu from the frame
590 m_hMenu
= (WXHMENU
)0;
591 InternalSetMenuBar();
593 else // set new non NULL menu bar
595 m_frameMenuBar
= NULL
;
598 // Can set a menubar several times.
599 // TODO: how to prevent a memory leak if you have a currently-unattached
600 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
601 // there are problems for MDI).
603 if (pMenuBar
->GetHMenu())
605 m_hMenu
= pMenuBar
->GetHMenu();
610 m_hMenu
= pMenuBar
->Create();
614 InternalSetMenuBar();
615 m_frameMenuBar
= pMenuBar
;
616 pMenuBar
->Attach((wxFrame
*)this);
618 } // end of wxFrameOS2::SetMenuBar
620 void wxFrameOS2::AttachMenuBar(
624 m_frameMenuBar
= pMenubar
;
629 // Actually remove the menu from the frame
631 m_hMenu
= (WXHMENU
)0;
632 InternalSetMenuBar();
634 else // Set new non NULL menu bar
637 // Can set a menubar several times.
639 if (pMenubar
->GetHMenu())
641 m_hMenu
= pMenubar
->GetHMenu();
645 if (pMenubar
->IsAttached())
648 m_hMenu
= pMenubar
->Create();
653 InternalSetMenuBar();
655 } // end of wxFrameOS2::AttachMenuBar
657 void wxFrameOS2::InternalSetMenuBar()
662 // Set the parent and owner of the menubar to be the frame
664 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
666 vError
= ::WinGetLastError(vHabmain
);
667 sError
= wxPMErrorToStr(vError
);
668 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
671 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
673 vError
= ::WinGetLastError(vHabmain
);
674 sError
= wxPMErrorToStr(vError
);
675 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
677 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
678 } // end of wxFrameOS2::InternalSetMenuBar
681 // Responds to colour changes, and passes event on to children
683 void wxFrameOS2::OnSysColourChanged(
684 wxSysColourChangedEvent
& rEvent
687 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
691 if (m_frameStatusBar
)
693 wxSysColourChangedEvent vEvent2
;
695 vEvent2
.SetEventObject(m_frameStatusBar
);
696 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
698 #endif //wxUSE_STATUSBAR
701 // Propagate the event to the non-top-level children
703 wxWindow::OnSysColourChanged(rEvent
);
704 } // end of wxFrameOS2::OnSysColourChanged
706 // Pass TRUE to show full screen, FALSE to restore.
707 bool wxFrameOS2::ShowFullScreen(
717 m_bFsIsShowing
= TRUE
;
721 wxToolBar
* pTheToolBar
= GetToolBar();
722 #endif //wxUSE_TOOLBAR
725 wxStatusBar
* pTheStatusBar
= GetStatusBar();
726 #endif //wxUSE_STATUSBAR
732 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
733 #endif //wxUSE_TOOLBAR
737 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
738 #endif //wxUSE_STATUSBAR
742 // Zap the toolbar, menubar, and statusbar
744 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
746 pTheToolBar
->SetSize(-1,0);
747 pTheToolBar
->Show(FALSE
);
749 #endif //wxUSE_TOOLBAR
751 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
753 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
754 ::WinSetOwner(m_hMenu
, m_hFrame
);
755 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
760 // Save the number of fields in the statusbar
762 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
764 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
765 SetStatusBar((wxStatusBar
*) NULL
);
766 delete pTheStatusBar
;
769 m_nFsStatusBarFields
= 0;
770 #endif //wxUSE_STATUSBAR
773 // Zap the frame borders
777 // Save the 'normal' window style
779 m_lFsOldWindowStyle
= ::WinQueryWindowULong(m_hFrame
, QWL_STYLE
);
782 // Save the old position, width & height, maximize state
784 m_vFsOldSize
= GetRect();
785 m_bFsIsMaximized
= IsMaximized();
788 // Decide which window style flags to turn off
790 LONG lNewStyle
= m_lFsOldWindowStyle
;
793 if (lStyle
& wxFULLSCREEN_NOBORDER
)
794 lOffFlags
|= FCF_BORDER
;
795 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
796 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
798 lNewStyle
&= (~lOffFlags
);
801 // Change our window style to be compatible with full-screen mode
803 ::WinSetWindowULong((HWND
)m_hFrame
, QWL_STYLE
, (ULONG
)lNewStyle
);
806 // Resize to the size of the desktop
812 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
813 nWidth
= vRect
.xRight
- vRect
.xLeft
;
815 // Rmember OS/2 is backwards!
817 nHeight
= vRect
.yTop
- vRect
.yBottom
;
824 // Now flush the window style cache and actually go full-screen
826 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
835 wxSizeEvent
vEvent( wxSize( nWidth
841 GetEventHandler()->ProcessEvent(vEvent
);
849 m_bFsIsShowing
= FALSE
;
852 wxToolBar
* pTheToolBar
= GetToolBar();
855 // Restore the toolbar, menubar, and statusbar
857 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
859 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
860 pTheToolBar
->Show(TRUE
);
862 #endif //wxUSE_TOOLBAR
865 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
867 CreateStatusBar(m_nFsStatusBarFields
);
868 // PositionStatusBar();
870 #endif //wxUSE_STATUSBAR
872 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
874 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
875 ::WinSetOwner(m_hMenu
, m_hFrame
);
876 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
878 Maximize(m_bFsIsMaximized
);
880 ::WinSetWindowULong( m_hFrame
882 ,(ULONG
)m_lFsOldWindowStyle
884 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
894 } // end of wxFrameOS2::ShowFullScreen
899 bool wxFrameOS2::OS2Create(
902 , const wxChar
* zWclass
904 , const wxChar
* zTitle
912 ULONG ulCreateFlags
= 0L;
913 ULONG ulStyleFlags
= 0L;
914 ULONG ulExtraFlags
= 0L;
915 FRAMECDATA vFrameCtlData
;
916 HWND hParent
= NULLHANDLE
;
917 HWND hTitlebar
= NULLHANDLE
;
918 HWND hHScroll
= NULLHANDLE
;
919 HWND hVScroll
= NULLHANDLE
;
920 HWND hFrame
= NULLHANDLE
;
921 HWND hClient
= NULLHANDLE
;
928 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
931 hParent
= GetWinHwnd(pParent
);
933 hParent
= HWND_DESKTOP
;
935 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
936 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
937 FCF_MINMAX
| FCF_TASKLIST
;
940 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
941 ulCreateFlags
= FCF_TASKLIST
;
943 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
945 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
946 ulCreateFlags
|= FCF_VERTSCROLL
;
947 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
948 ulCreateFlags
|= FCF_HORZSCROLL
;
949 if (ulStyle
& wxMINIMIZE_BOX
)
950 ulCreateFlags
|= FCF_MINBUTTON
;
951 if (ulStyle
& wxMAXIMIZE_BOX
)
952 ulCreateFlags
|= FCF_MAXBUTTON
;
953 if (ulStyle
& wxTHICK_FRAME
)
954 ulCreateFlags
|= FCF_DLGBORDER
;
955 if (ulStyle
& wxSYSTEM_MENU
)
956 ulCreateFlags
|= FCF_SYSMENU
;
957 if (ulStyle
& wxCAPTION
)
958 ulCreateFlags
|= FCF_TASKLIST
;
959 if (ulStyle
& wxCLIP_CHILDREN
)
961 // Invalid for frame windows under PM
964 if (ulStyle
& wxTINY_CAPTION_VERT
)
965 ulCreateFlags
|= FCF_TASKLIST
;
966 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
967 ulCreateFlags
|= FCF_TASKLIST
;
969 if ((ulStyle
& wxTHICK_FRAME
) == 0)
970 ulCreateFlags
|= FCF_BORDER
;
971 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
972 ulExtraFlags
= kFrameToolWindow
;
974 if (ulStyle
& wxSTAY_ON_TOP
)
975 ulCreateFlags
|= FCF_SYSMODAL
;
977 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
978 ulStyleFlags
|= WS_MINIMIZED
;
979 if (ulStyle
& wxMAXIMIZE
)
980 ulStyleFlags
|= WS_MAXIMIZED
;
983 // Clear the visible flag, we always call show
985 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
989 // Set the frame control block
991 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
992 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
993 vFrameCtlData
.hmodResources
= 0L;
994 vFrameCtlData
.idResources
= 0;
997 // Create the frame window: We break ranks with other ports now
998 // and instead of calling down into the base wxWindow class' OS2Create
999 // we do all our own stuff here. We will set the needed pieces
1000 // of wxWindow manually, here.
1003 hFrame
= ::WinCreateStdWindow( hParent
1004 ,ulStyleFlags
// frame-window style
1005 ,&ulCreateFlags
// window style
1006 ,(PSZ
)zWclass
// class name
1007 ,(PSZ
)zTitle
// window title
1008 ,0L // default client style
1009 ,NULLHANDLE
// resource in executable file
1011 ,&hClient
// receives client window handle
1015 vError
= ::WinGetLastError(vHabmain
);
1016 sError
= wxPMErrorToStr(vError
);
1017 wxLogError("Error creating frame. Error: %s\n", sError
);
1022 // wxWindow class' m_hWnd set here and needed associations
1026 wxAssociateWinWithHandle(m_hWnd
, this);
1027 wxAssociateWinWithHandle(m_hFrame
, this);
1029 m_backgroundColour
.Set(wxString("GREY"));
1031 LONG lColor
= (LONG
)m_backgroundColour
.GetPixel();
1033 if (!::WinSetPresParam( m_hWnd
1039 vError
= ::WinGetLastError(vHabmain
);
1040 sError
= wxPMErrorToStr(vError
);
1041 wxLogError("Error creating frame. Error: %s\n", sError
);
1046 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
1047 // we manually subclass here because we don't want to use the main wxWndProc
1050 m_fnOldWndProc
= (WXFARPROC
) ::WinSubclassWindow(m_hFrame
, (PFNWP
)wxFrameMainWndProc
);
1053 // Now size everything. If adding a menu the client will need to be resized.
1056 if (!::WinSetWindowPos( m_hFrame
1062 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1065 vError
= ::WinGetLastError(vHabmain
);
1066 sError
= wxPMErrorToStr(vError
);
1067 wxLogError("Error sizing frame. Error: %s\n", sError
);
1071 // We may have to be smarter here when variable sized toolbars are added!
1073 if (!::WinSetWindowPos( m_hWnd
1079 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1082 vError
= ::WinGetLastError(vHabmain
);
1083 sError
= wxPMErrorToStr(vError
);
1084 wxLogError("Error sizing client. Error: %s\n", sError
);
1088 } // end of wxFrameOS2::OS2Create
1091 // Default activation behaviour - set the focus for the first child
1094 void wxFrameOS2::OnActivate(
1095 wxActivateEvent
& rEvent
1098 if ( rEvent
.GetActive() )
1100 // restore focus to the child which was last focused
1101 wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd
);
1103 wxWindow
* pParent
= m_pWinLastFocused
? m_pWinLastFocused
->GetParent()
1110 wxSetFocusToChild( pParent
1114 else // deactivating
1117 // Remember the last focused child if it is our child
1119 m_pWinLastFocused
= FindFocus();
1121 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1123 pNode
= pNode
->GetNext())
1125 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1126 // but how to do it without duplicating the code?
1129 wxWindow
* pChild
= pNode
->GetData();
1131 if (!pChild
->IsTopLevel()
1133 && !wxDynamicCast(pChild
, wxToolBar
)
1134 #endif // wxUSE_TOOLBAR
1136 && !wxDynamicCast(pChild
, wxStatusBar
)
1137 #endif // wxUSE_STATUSBAR
1145 } // end of wxFrameOS2::OnActivate
1147 // ----------------------------------------------------------------------------
1148 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1149 // from the client area, so the client area is what's really available for the
1151 // ----------------------------------------------------------------------------
1153 // Checks if there is a toolbar, and returns the first free client position
1154 wxPoint
wxFrameOS2::GetClientAreaOrigin() const
1156 wxPoint
vPoint(0, 0);
1164 GetToolBar()->GetSize( &nWidth
1168 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1174 // PM is backwards from windows
1175 vPoint
.y
+= nHeight
;
1178 #endif //wxUSE_TOOLBAR
1180 } // end of wxFrameOS2::GetClientAreaOrigin
1182 // ----------------------------------------------------------------------------
1183 // tool/status bar stuff
1184 // ----------------------------------------------------------------------------
1188 wxToolBar
* wxFrameOS2::CreateToolBar(
1191 , const wxString
& rName
1194 if (wxFrameBase::CreateToolBar( lStyle
1201 return m_frameToolBar
;
1202 } // end of wxFrameOS2::CreateToolBar
1204 void wxFrameOS2::PositionToolBar()
1209 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1217 GetStatusBar()->GetClientSize( &nStatusX
1220 // PM is backwards from windows
1221 vRect
.yBottom
+= nStatusY
;
1223 #endif // wxUSE_STATUSBAR
1225 if ( m_frameToolBar
)
1230 m_frameToolBar
->GetSize( &nToolbarWidth
1234 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1236 nToolbarHeight
= vRect
.yBottom
;
1240 nToolbarWidth
= vRect
.xRight
;
1244 // Use the 'real' PM position here
1246 GetToolBar()->SetSize( 0
1250 ,wxSIZE_NO_ADJUSTMENTS
1253 } // end of wxFrameOS2::PositionToolBar
1254 #endif // wxUSE_TOOLBAR
1256 // ----------------------------------------------------------------------------
1257 // frame state (iconized/maximized/...)
1258 // ----------------------------------------------------------------------------
1261 // propagate our state change to all child frames: this allows us to emulate X
1262 // Windows behaviour where child frames float independently of the parent one
1263 // on the desktop, but are iconized/restored with it
1265 void wxFrameOS2::IconizeChildFrames(
1269 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1271 pNode
= pNode
->GetNext() )
1273 wxWindow
* pWin
= pNode
->GetData();
1275 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1277 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1280 } // end of wxFrameOS2::IconizeChildFrames
1282 // ===========================================================================
1283 // message processing
1284 // ===========================================================================
1286 // ---------------------------------------------------------------------------
1288 // ---------------------------------------------------------------------------
1289 bool wxFrameOS2::OS2TranslateMessage(
1294 // try the menu bar accels
1296 wxMenuBar
* pMenuBar
= GetMenuBar();
1302 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1303 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1306 #endif //wxUSE_ACCEL
1307 } // end of wxFrameOS2::OS2TranslateMessage
1309 // ---------------------------------------------------------------------------
1310 // our private (non virtual) message handlers
1311 // ---------------------------------------------------------------------------
1312 bool wxFrameOS2::HandlePaint()
1316 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1321 // Icons in PM are the same as "pointers"
1326 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1328 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1331 // Hold a pointer to the dc so long as the OnPaint() message
1332 // is being processed
1335 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1338 // Erase background before painting or we get white background
1340 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1347 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1349 static const int nIconWidth
= 32;
1350 static const int nIconHeight
= 32;
1351 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1352 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1354 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1361 return(wxWindow::HandlePaint());
1366 // nothing to paint - processed
1370 } // end of wxFrameOS2::HandlePaint
1372 bool wxFrameOS2::HandleSize(
1378 bool bProcessed
= FALSE
;
1384 // Only do it it if we were iconized before, otherwise resizing the
1385 // parent frame has a curious side effect of bringing it under it's
1391 // restore all child frames too
1393 IconizeChildFrames(FALSE
);
1394 (void)SendIconizeEvent(FALSE
);
1401 m_bIconized
= FALSE
;
1406 // Iconize all child frames too
1408 IconizeChildFrames(TRUE
);
1409 (void)SendIconizeEvent();
1417 // forward WM_SIZE to status bar control
1419 #if wxUSE_NATIVE_STATUSBAR
1420 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1422 wxSizeEvent
vEvent( wxSize( nX
1425 ,m_frameStatusBar
->GetId()
1428 vEvent
.SetEventObject(m_frameStatusBar
);
1429 m_frameStatusBar
->OnSize(vEvent
);
1431 #endif // wxUSE_NATIVE_STATUSBAR
1433 PositionStatusBar();
1436 #endif // wxUSE_TOOLBAR
1438 wxSizeEvent
vEvent( wxSize( nX
1444 vEvent
.SetEventObject(this);
1445 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1448 } // end of wxFrameOS2::HandleSize
1450 bool wxFrameOS2::HandleCommand(
1459 // In case it's e.g. a toolbar.
1461 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1464 return pWin
->OS2Command( nCmd
1470 // Handle here commands from menus and accelerators
1472 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1474 if (wxCurrentPopupMenu
)
1476 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1478 wxCurrentPopupMenu
= NULL
;
1480 return pPopupMenu
->OS2Command( nCmd
1485 if (ProcessCommand(nId
))
1491 } // end of wxFrameOS2::HandleCommand
1493 bool wxFrameOS2::HandleMenuSelect(
1504 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1506 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1508 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1510 vEvent
.SetEventObject(this);
1511 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1515 } // end of wxFrameOS2::HandleMenuSelect
1517 // ---------------------------------------------------------------------------
1518 // Main Frame window proc
1519 // ---------------------------------------------------------------------------
1520 MRESULT EXPENTRY
wxFrameMainWndProc(
1527 MRESULT rc
= (MRESULT
)0;
1528 bool bProcessed
= FALSE
;
1529 wxFrame
* pWnd
= NULL
;
1531 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1534 case WM_QUERYFRAMECTLCOUNT
:
1535 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1537 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1539 rc
= MRFROMSHORT(uItemCount
);
1543 case WM_FORMATFRAME
:
1544 /////////////////////////////////////////////////////////////////////////////////
1545 // Applications that subclass frame controls may find that the frame is already
1546 // subclassed the number of frame controls is variable.
1547 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1548 // subclassed by calling the previous window procedure and modifying its result.
1549 ////////////////////////////////////////////////////////////////////////////////
1559 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1560 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1561 if(pWnd
->m_frameStatusBar
)
1563 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1564 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1565 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1566 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1568 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1570 vSwpStb
.x
= vRectl
.xLeft
- vRstb
.xLeft
;
1571 vSwpStb
.y
= vRectl
.yBottom
- vRstb
.yBottom
;
1572 vSwpStb
.cx
= vRectl
.xRight
- vRectl
.xLeft
- 1; //?? -1 ??
1573 vSwpStb
.cy
= nHeight
;
1574 vSwpStb
.fl
= SWP_SIZE
|SWP_MOVE
| SWP_SHOW
;
1575 vSwpStb
.hwnd
= pWnd
->m_frameStatusBar
->GetHWND();
1576 vSwpStb
.hwndInsertBehind
= HWND_TOP
;
1578 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1579 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1580 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1581 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1582 for(i
= 0; i
< nItemCount
; i
++)
1584 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1586 pSWP
[i
].x
= vRectl
.xLeft
;
1587 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1588 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1589 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1590 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1591 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1595 rc
= MRFROMSHORT(nItemCount
);
1600 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1601 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1603 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1606 } // end of wxFrameMainWndProc
1608 MRESULT EXPENTRY
wxFrameWndProc(
1616 // Trace all ulMsgs - useful for the debugging
1619 wxFrame
* pWnd
= NULL
;
1621 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1622 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1625 // When we get the first message for the HWND we just created, we associate
1626 // it with wxWindow stored in wxWndHook
1629 MRESULT rc
= (MRESULT
)0;
1630 bool bProcessed
= FALSE
;
1633 // Stop right here if we don't have a valid handle in our wxWindow object.
1635 if (pWnd
&& !pWnd
->GetHWND())
1637 pWnd
->SetHWND((WXHWND
) hWnd
);
1638 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1644 rc
= pWnd
->OS2WindowProc(ulMsg
, wParam
, lParam
);
1646 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1649 } // end of wxFrameWndProc
1651 MRESULT
wxFrameOS2::OS2WindowProc(
1658 bool bProcessed
= FALSE
;
1664 // If we can't close, tell the system that we processed the
1665 // message - otherwise it would close us
1667 bProcessed
= !Close();
1671 bProcessed
= HandlePaint();
1672 mRc
= (MRESULT
)FALSE
;
1675 case WM_ERASEBACKGROUND
:
1677 // Returning TRUE to requests PM to paint the window background
1678 // in SYSCLR_WINDOW. We capture this here because the PS returned
1679 // in Frames is the PS for the whole frame, which we can't really
1680 // use at all. If you want to paint a different background, do it
1681 // in an OnPaint using a wxPaintDC.
1683 mRc
= (MRESULT
)(TRUE
);
1692 UnpackCommand( (WXWPARAM
)wParam
1699 bProcessed
= HandleCommand( wId
1712 UnpackMenuSelect( wParam
1718 bProcessed
= HandleMenuSelect( wItem
1722 mRc
= (MRESULT
)TRUE
;
1728 SHORT nScxold
= SHORT1FROMMP(wParam
); // Old horizontal size.
1729 SHORT nScyold
= SHORT2FROMMP(wParam
); // Old vertical size.
1730 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1731 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1733 lParam
= MRFROM2SHORT( nScxnew
- 20
1737 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1738 mRc
= (MRESULT
)FALSE
;
1741 case CM_QUERYDRAGIMAGE
:
1746 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1748 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1749 mRc
= (MRESULT
)hIcon
;
1750 bProcessed
= mRc
!= 0;
1756 mRc
= wxWindow::OS2WindowProc( uMessage
1760 return (MRESULT
)mRc
;
1761 } // wxFrameOS2::OS2WindowProc
1763 void wxFrameOS2::SetClient(WXHWND c_Hwnd
)
1765 // Duh...nothing to do under OS/2
1768 void wxFrameOS2::SetClient(
1772 wxWindow
* pOldClient
= this->GetClient();
1773 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1775 if(pOldClient
== pWindow
) // nothing to do
1777 if(pWindow
== NULL
) // just need to remove old client
1779 if(pOldClient
== NULL
) // nothing to do
1782 if(bClientHasFocus
)
1785 pOldClient
->Enable( FALSE
);
1786 pOldClient
->Show( FALSE
);
1787 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1788 // to avoid OS/2 bug need to update frame
1789 ::WinSendMsg((HWND
)this->GetFrame(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1794 // Else need to change client
1799 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1802 pOldClient
->Enable(FALSE
);
1803 pOldClient
->Show(FALSE
);
1804 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1806 pWindow
->Reparent(this);
1807 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1808 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1810 pWindow
->Show(); // ensure client is showing
1811 if( this->IsShown() )
1814 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1818 wxWindow
* wxFrameOS2::GetClient()
1820 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(m_hFrame
, FID_CLIENT
));