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 #ifndef __WXUNIVERSAL__
72 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
75 // ============================================================================
77 // ============================================================================
79 // ----------------------------------------------------------------------------
80 // static class members
81 // ----------------------------------------------------------------------------
84 #if wxUSE_NATIVE_STATUSBAR
85 bool wxFrameOS2::m_bUseNativeStatusBar
= TRUE
;
87 bool wxFrameOS2::m_bUseNativeStatusBar
= FALSE
;
90 #endif //wxUSE_STATUSBAR
92 // ----------------------------------------------------------------------------
93 // creation/destruction
94 // ----------------------------------------------------------------------------
96 void wxFrameOS2::Init()
103 // Data to save/restore when calling ShowFullScreen
105 m_lFsOldWindowStyle
= 0L;
106 m_nFsStatusBarFields
= 0;
107 m_nFsStatusBarHeight
= 0;
108 m_nFsToolBarHeight
= 0;
109 m_bFsIsMaximized
= FALSE
;
110 m_bFsIsShowing
= FALSE
;
112 m_pWinLastFocused
= (wxWindow
*)NULL
;
122 memset(&m_vSwp
, 0, sizeof(SWP
));
123 memset(&m_vSwpClient
, 0, sizeof(SWP
));
124 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
125 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
126 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
127 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
128 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
129 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
130 } // end of wxFrameOS2::Init
132 bool wxFrameOS2::Create(
135 , const wxString
& rsTitle
136 , const wxPoint
& rPos
137 , const wxSize
& rSize
139 , const wxString
& rsName
144 int nWidth
= rSize
.x
;
145 int nHeight
= rSize
.y
;
149 m_windowStyle
= lulStyle
;
150 m_frameMenuBar
= NULL
;
152 m_frameToolBar
= NULL
;
153 #endif //wxUSE_TOOLBAR
156 m_frameStatusBar
= NULL
;
157 #endif //wxUSE_STATUSBAR
159 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
164 m_windowId
= (int)NewControlId();
167 pParent
->AddChild(this);
171 if ((m_windowStyle
& wxFRAME_FLOAT_ON_PARENT
) == 0)
174 bOk
= OS2Create( m_windowId
188 wxTopLevelWindows
.Append(this);
189 wxModelessWindows
.Append(this);
192 } // end of wxFrameOS2::Create
194 wxFrameOS2::~wxFrameOS2()
196 m_isBeingDeleted
= TRUE
;
198 wxTopLevelWindows
.DeleteObject(this);
202 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
204 wxTheApp
->SetTopWindow(NULL
);
206 if (wxTheApp
->GetExitOnFrameDelete())
208 ::WinPostMsg(NULL
, WM_QUIT
, 0, 0);
212 wxModelessWindows
.DeleteObject(this);
215 // For some reason, wxWindows can activate another task altogether
216 // when a frame is destroyed after a modal dialog has been invoked.
217 // Try to bring the parent to the top.
219 // MT:Only do this if this frame is currently the active window, else weird
220 // things start to happen.
222 if (wxGetActiveWindow() == this)
224 if (GetParent() && GetParent()->GetHWND())
226 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
236 } // end of wxFrameOS2::~wxFrame
239 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
241 void wxFrameOS2::DoGetClientSize(
247 ::WinQueryWindowRect(GetHwnd(), &vRect
);
250 // No need to use statusbar code as in WIN32 as the FORMATFRAME
251 // window procedure ensures PM knows about the new frame client
252 // size internally. A ::WinQueryWindowRect is all that is needed!
256 *pX
= vRect
.xRight
- vRect
.xLeft
;
258 *pY
= vRect
.yTop
- vRect
.yBottom
;
259 } // end of wxFrameOS2::DoGetClientSize
262 // Set the client size (i.e. leave the calculation of borders etc.
265 void wxFrameOS2::DoSetClientSize(
270 HWND hWnd
= GetHwnd();
274 ::WinQueryWindowRect(GetHwnd(), &vRect
);
275 ::WinQueryWindowRect(GetHwnd(), &vRect2
);
278 // Find the difference between the entire window (title bar and all)
279 // and the client area; add this to the new client size to move the
280 // window. Remember OS/2's backwards y coord system!
282 int nActualWidth
= vRect2
.xRight
- vRect2
.xLeft
- vRect
.xRight
+ nWidth
;
283 int nActualHeight
= vRect2
.yTop
+ vRect2
.yTop
- vRect
.yTop
+ nHeight
;
286 if ( GetStatusBar() )
291 GetStatusBar()->GetClientSize( &nStatusX
294 nActualHeight
+= nStatusY
;
296 #endif // wxUSE_STATUSBAR
298 wxPoint
vPoint(GetClientAreaOrigin());
299 nActualWidth
+= vPoint
.y
;
300 nActualHeight
+= vPoint
.x
;
304 vPointl
.x
= vRect2
.xLeft
;
305 vPointl
.y
= vRect2
.yTop
;
307 ::WinSetWindowPos( hWnd
313 ,SWP_MOVE
| SWP_SIZE
| SWP_SHOW
316 wxSizeEvent
vEvent( wxSize( nWidth
321 vEvent
.SetEventObject(this);
322 GetEventHandler()->ProcessEvent(vEvent
);
323 } // end of wxFrameOS2::DoSetClientSize
325 void wxFrameOS2::DoGetSize(
332 ::WinQueryWindowRect(m_hFrame
, &vRect
);
333 *pWidth
= vRect
.xRight
- vRect
.xLeft
;
334 *pHeight
= vRect
.yTop
- vRect
.yBottom
;
335 } // end of wxFrameOS2::DoGetSize
337 void wxFrameOS2::DoGetPosition(
345 ::WinQueryWindowRect(m_hFrame
, &vRect
);
347 *pX
= vRect
.xRight
- vRect
.xLeft
;
348 *pY
= vRect
.yTop
- vRect
.yBottom
;
349 } // end of wxFrameOS2::DoGetPosition
351 // ----------------------------------------------------------------------------
352 // variations around ::ShowWindow()
353 // ----------------------------------------------------------------------------
355 void wxFrameOS2::DoShowWindow(
359 ::WinShowWindow(m_hFrame
, (BOOL
)bShowCmd
);
360 m_bIconized
= bShowCmd
== SWP_MINIMIZE
;
361 } // end of wxFrameOS2::DoShowWindow
363 bool wxFrameOS2::Show(
369 DoShowWindow((int)bShow
);
373 wxActivateEvent
vEvent(wxEVT_ACTIVATE
, TRUE
, m_windowId
);
375 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
376 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
377 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
378 ::WinEnableWindow(m_hFrame
, TRUE
);
379 vEvent
.SetEventObject(this);
380 GetEventHandler()->ProcessEvent(vEvent
);
385 // Try to highlight the correct window (the parent)
389 HWND hWndParent
= GetHwndOf(GetParent());
391 ::WinQueryWindowPos(hWndParent
, &vSwp
);
392 m_bIconized
= vSwp
.fl
& SWP_MINIMIZE
;
394 ::WinSetWindowPos( hWndParent
400 ,SWP_ZORDER
| SWP_ACTIVATE
| SWP_SHOW
| SWP_MOVE
402 ::WinEnableWindow(hWndParent
, TRUE
);
406 } // end of wxFrameOS2::Show
408 void wxFrameOS2::Iconize(
412 DoShowWindow(bIconize
? SWP_MINIMIZE
: SWP_RESTORE
);
413 } // end of wxFrameOS2::Iconize
415 void wxFrameOS2::Maximize(
418 DoShowWindow(bMaximize
? SWP_MAXIMIZE
: SWP_RESTORE
);
419 } // end of wxFrameOS2::Maximize
421 void wxFrameOS2::Restore()
423 DoShowWindow(SWP_RESTORE
);
424 } // end of wxFrameOS2::Restore
426 bool wxFrameOS2::IsIconized() const
430 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
432 if (vSwp
.fl
& SWP_MINIMIZE
)
433 ((wxFrame
*)this)->m_bIconized
= TRUE
;
435 ((wxFrame
*)this)->m_bIconized
= FALSE
;
437 } // end of wxFrameOS2::IsIconized
440 bool wxFrameOS2::IsMaximized() const
445 ::WinQueryWindowPos(m_hFrame
, &vSwp
);
446 return (vSwp
.fl
& SWP_MAXIMIZE
);
447 } // end of wxFrameOS2::IsMaximized
449 void wxFrameOS2::SetIcon(
453 wxFrameBase::SetIcon(rIcon
);
455 if ((m_icon
.GetHICON()) != NULLHANDLE
)
457 ::WinSendMsg( m_hFrame
459 ,(MPARAM
)((HPOINTER
)m_icon
.GetHICON())
462 ::WinSendMsg( m_hFrame
468 } // end of wxFrameOS2::SetIcon
471 wxStatusBar
* wxFrameOS2::OnCreateStatusBar(
475 , const wxString
& rName
478 wxStatusBar
* pStatusBar
= NULL
;
483 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
492 ::WinSetParent( pStatusBar
->GetHWND()
496 ::WinSetOwner( pStatusBar
->GetHWND()
502 if(::WinIsWindowShowing(m_hFrame
))
503 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
506 } // end of wxFrameOS2::OnCreateStatusBar
508 void wxFrameOS2::PositionStatusBar()
515 // Native status bar positions itself
517 if (m_frameStatusBar
)
526 ::WinQueryWindowRect(m_hFrame
, &vRect
);
527 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
529 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
530 nWidth
= vRect
.xRight
- vRect
.xLeft
;
532 m_frameStatusBar
->GetSize( &nStatbarWidth
537 // Since we wish the status bar to be directly under the client area,
538 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
540 m_frameStatusBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
541 ,vRect
.yBottom
- vFRect
.yBottom
545 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
547 vError
= ::WinGetLastError(vHabmain
);
548 sError
= wxPMErrorToStr(vError
);
549 wxLogError("Error setting parent for StautsBar. Error: %s\n", sError
);
553 } // end of wxFrameOS2::PositionStatusBar
554 #endif // wxUSE_STATUSBAR
556 void wxFrameOS2::DetachMenuBar()
560 m_frameMenuBar
->Detach();
561 m_frameMenuBar
= NULL
;
563 } // end of wxFrameOS2::DetachMenuBar
565 void wxFrameOS2::SetMenuBar(
571 HWND hTitlebar
= NULLHANDLE
;
572 HWND hHScroll
= NULLHANDLE
;
573 HWND hVScroll
= NULLHANDLE
;
574 HWND hMenuBar
= NULLHANDLE
;
586 // Actually remove the menu from the frame
588 m_hMenu
= (WXHMENU
)0;
589 InternalSetMenuBar();
591 else // set new non NULL menu bar
593 m_frameMenuBar
= NULL
;
596 // Can set a menubar several times.
597 // TODO: how to prevent a memory leak if you have a currently-unattached
598 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
599 // there are problems for MDI).
601 if (pMenuBar
->GetHMenu())
603 m_hMenu
= pMenuBar
->GetHMenu();
608 m_hMenu
= pMenuBar
->Create();
612 InternalSetMenuBar();
613 m_frameMenuBar
= pMenuBar
;
614 pMenuBar
->Attach((wxFrame
*)this);
616 } // end of wxFrameOS2::SetMenuBar
618 void wxFrameOS2::AttachMenuBar(
622 m_frameMenuBar
= pMenubar
;
627 // Actually remove the menu from the frame
629 m_hMenu
= (WXHMENU
)0;
630 InternalSetMenuBar();
632 else // Set new non NULL menu bar
635 // Can set a menubar several times.
637 if (pMenubar
->GetHMenu())
639 m_hMenu
= pMenubar
->GetHMenu();
643 if (pMenubar
->IsAttached())
646 m_hMenu
= pMenubar
->Create();
651 InternalSetMenuBar();
653 } // end of wxFrameOS2::AttachMenuBar
655 void wxFrameOS2::InternalSetMenuBar()
660 // Set the parent and owner of the menubar to be the frame
662 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
664 vError
= ::WinGetLastError(vHabmain
);
665 sError
= wxPMErrorToStr(vError
);
666 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
669 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
671 vError
= ::WinGetLastError(vHabmain
);
672 sError
= wxPMErrorToStr(vError
);
673 wxLogError("Error setting parent for submenu. Error: %s\n", sError
);
675 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
676 } // end of wxFrameOS2::InternalSetMenuBar
679 // Responds to colour changes, and passes event on to children
681 void wxFrameOS2::OnSysColourChanged(
682 wxSysColourChangedEvent
& rEvent
685 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
689 if (m_frameStatusBar
)
691 wxSysColourChangedEvent vEvent2
;
693 vEvent2
.SetEventObject(m_frameStatusBar
);
694 m_frameStatusBar
->GetEventHandler()->ProcessEvent(vEvent2
);
696 #endif //wxUSE_STATUSBAR
699 // Propagate the event to the non-top-level children
701 wxWindow::OnSysColourChanged(rEvent
);
702 } // end of wxFrameOS2::OnSysColourChanged
704 // Pass TRUE to show full screen, FALSE to restore.
705 bool wxFrameOS2::ShowFullScreen(
715 m_bFsIsShowing
= TRUE
;
719 wxToolBar
* pTheToolBar
= GetToolBar();
720 #endif //wxUSE_TOOLBAR
723 wxStatusBar
* pTheStatusBar
= GetStatusBar();
724 #endif //wxUSE_STATUSBAR
730 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
731 #endif //wxUSE_TOOLBAR
735 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
736 #endif //wxUSE_STATUSBAR
740 // Zap the toolbar, menubar, and statusbar
742 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
744 pTheToolBar
->SetSize(-1,0);
745 pTheToolBar
->Show(FALSE
);
747 #endif //wxUSE_TOOLBAR
749 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
751 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
752 ::WinSetOwner(m_hMenu
, m_hFrame
);
753 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
758 // Save the number of fields in the statusbar
760 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
762 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
763 SetStatusBar((wxStatusBar
*) NULL
);
764 delete pTheStatusBar
;
767 m_nFsStatusBarFields
= 0;
768 #endif //wxUSE_STATUSBAR
771 // Zap the frame borders
775 // Save the 'normal' window style
777 m_lFsOldWindowStyle
= ::WinQueryWindowULong(m_hFrame
, QWL_STYLE
);
780 // Save the old position, width & height, maximize state
782 m_vFsOldSize
= GetRect();
783 m_bFsIsMaximized
= IsMaximized();
786 // Decide which window style flags to turn off
788 LONG lNewStyle
= m_lFsOldWindowStyle
;
791 if (lStyle
& wxFULLSCREEN_NOBORDER
)
792 lOffFlags
|= FCF_BORDER
;
793 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
794 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
796 lNewStyle
&= (~lOffFlags
);
799 // Change our window style to be compatible with full-screen mode
801 ::WinSetWindowULong((HWND
)m_hFrame
, QWL_STYLE
, (ULONG
)lNewStyle
);
804 // Resize to the size of the desktop
810 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
811 nWidth
= vRect
.xRight
- vRect
.xLeft
;
813 // Rmember OS/2 is backwards!
815 nHeight
= vRect
.yTop
- vRect
.yBottom
;
822 // Now flush the window style cache and actually go full-screen
824 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
833 wxSizeEvent
vEvent( wxSize( nWidth
839 GetEventHandler()->ProcessEvent(vEvent
);
847 m_bFsIsShowing
= FALSE
;
850 wxToolBar
* pTheToolBar
= GetToolBar();
853 // Restore the toolbar, menubar, and statusbar
855 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
857 pTheToolBar
->SetSize(-1, m_nFsToolBarHeight
);
858 pTheToolBar
->Show(TRUE
);
860 #endif //wxUSE_TOOLBAR
863 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
865 CreateStatusBar(m_nFsStatusBarFields
);
866 // PositionStatusBar();
868 #endif //wxUSE_STATUSBAR
870 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
872 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
873 ::WinSetOwner(m_hMenu
, m_hFrame
);
874 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
876 Maximize(m_bFsIsMaximized
);
878 ::WinSetWindowULong( m_hFrame
880 ,(ULONG
)m_lFsOldWindowStyle
882 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
892 } // end of wxFrameOS2::ShowFullScreen
897 bool wxFrameOS2::OS2Create(
900 , const wxChar
* zWclass
902 , const wxChar
* zTitle
910 ULONG ulCreateFlags
= 0L;
911 ULONG ulStyleFlags
= 0L;
912 ULONG ulExtraFlags
= 0L;
913 FRAMECDATA vFrameCtlData
;
914 HWND hParent
= NULLHANDLE
;
915 HWND hTitlebar
= NULLHANDLE
;
916 HWND hHScroll
= NULLHANDLE
;
917 HWND hVScroll
= NULLHANDLE
;
918 HWND hFrame
= NULLHANDLE
;
919 HWND hClient
= NULLHANDLE
;
926 m_hDefaultIcon
= (WXHICON
) (wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
: wxDEFAULT_FRAME_ICON
);
929 hParent
= GetWinHwnd(pParent
);
931 hParent
= HWND_DESKTOP
;
933 if (ulStyle
== wxDEFAULT_FRAME_STYLE
)
934 ulCreateFlags
= FCF_SIZEBORDER
| FCF_TITLEBAR
| FCF_SYSMENU
|
935 FCF_MINMAX
| FCF_TASKLIST
;
938 if ((ulStyle
& wxCAPTION
) == wxCAPTION
)
939 ulCreateFlags
= FCF_TASKLIST
;
941 ulCreateFlags
= FCF_NOMOVEWITHOWNER
;
943 if ((ulStyle
& wxVSCROLL
) == wxVSCROLL
)
944 ulCreateFlags
|= FCF_VERTSCROLL
;
945 if ((ulStyle
& wxHSCROLL
) == wxHSCROLL
)
946 ulCreateFlags
|= FCF_HORZSCROLL
;
947 if (ulStyle
& wxMINIMIZE_BOX
)
948 ulCreateFlags
|= FCF_MINBUTTON
;
949 if (ulStyle
& wxMAXIMIZE_BOX
)
950 ulCreateFlags
|= FCF_MAXBUTTON
;
951 if (ulStyle
& wxTHICK_FRAME
)
952 ulCreateFlags
|= FCF_DLGBORDER
;
953 if (ulStyle
& wxSYSTEM_MENU
)
954 ulCreateFlags
|= FCF_SYSMENU
;
955 if (ulStyle
& wxCAPTION
)
956 ulCreateFlags
|= FCF_TASKLIST
;
957 if (ulStyle
& wxCLIP_CHILDREN
)
959 // Invalid for frame windows under PM
962 if (ulStyle
& wxTINY_CAPTION_VERT
)
963 ulCreateFlags
|= FCF_TASKLIST
;
964 if (ulStyle
& wxTINY_CAPTION_HORIZ
)
965 ulCreateFlags
|= FCF_TASKLIST
;
967 if ((ulStyle
& wxTHICK_FRAME
) == 0)
968 ulCreateFlags
|= FCF_BORDER
;
969 if (ulStyle
& wxFRAME_TOOL_WINDOW
)
970 ulExtraFlags
= kFrameToolWindow
;
972 if (ulStyle
& wxSTAY_ON_TOP
)
973 ulCreateFlags
|= FCF_SYSMODAL
;
975 if ((ulStyle
& wxMINIMIZE
) || (ulStyle
& wxICONIZE
))
976 ulStyleFlags
|= WS_MINIMIZED
;
977 if (ulStyle
& wxMAXIMIZE
)
978 ulStyleFlags
|= WS_MAXIMIZED
;
981 // Clear the visible flag, we always call show
983 ulStyleFlags
&= (unsigned long)~WS_VISIBLE
;
987 // Set the frame control block
989 vFrameCtlData
.cb
= sizeof(vFrameCtlData
);
990 vFrameCtlData
.flCreateFlags
= ulCreateFlags
;
991 vFrameCtlData
.hmodResources
= 0L;
992 vFrameCtlData
.idResources
= 0;
995 // Create the frame window: We break ranks with other ports now
996 // and instead of calling down into the base wxWindow class' OS2Create
997 // we do all our own stuff here. We will set the needed pieces
998 // of wxWindow manually, here.
1001 hFrame
= ::WinCreateStdWindow( hParent
1002 ,ulStyleFlags
// frame-window style
1003 ,&ulCreateFlags
// window style
1004 ,(PSZ
)zWclass
// class name
1005 ,(PSZ
)zTitle
// window title
1006 ,0L // default client style
1007 ,NULLHANDLE
// resource in executable file
1009 ,&hClient
// receives client window handle
1013 vError
= ::WinGetLastError(vHabmain
);
1014 sError
= wxPMErrorToStr(vError
);
1015 wxLogError("Error creating frame. Error: %s\n", sError
);
1020 // wxWindow class' m_hWnd set here and needed associations
1024 wxAssociateWinWithHandle(m_hWnd
, this);
1025 wxAssociateWinWithHandle(m_hFrame
, this);
1027 m_backgroundColour
.Set(wxString("GREY"));
1029 LONG lColor
= (LONG
)m_backgroundColour
.GetPixel();
1031 if (!::WinSetPresParam( m_hWnd
1037 vError
= ::WinGetLastError(vHabmain
);
1038 sError
= wxPMErrorToStr(vError
);
1039 wxLogError("Error creating frame. Error: %s\n", sError
);
1044 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
1045 // we manually subclass here because we don't want to use the main wxWndProc
1048 m_fnOldWndProc
= (WXFARPROC
) ::WinSubclassWindow(m_hFrame
, (PFNWP
)wxFrameMainWndProc
);
1051 // Now size everything. If adding a menu the client will need to be resized.
1054 if (!::WinSetWindowPos( m_hFrame
1060 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1063 vError
= ::WinGetLastError(vHabmain
);
1064 sError
= wxPMErrorToStr(vError
);
1065 wxLogError("Error sizing frame. Error: %s\n", sError
);
1069 // We may have to be smarter here when variable sized toolbars are added!
1071 if (!::WinSetWindowPos( m_hWnd
1077 ,SWP_SIZE
| SWP_MOVE
| SWP_ACTIVATE
| SWP_ZORDER
1080 vError
= ::WinGetLastError(vHabmain
);
1081 sError
= wxPMErrorToStr(vError
);
1082 wxLogError("Error sizing client. Error: %s\n", sError
);
1086 } // end of wxFrameOS2::OS2Create
1089 // Default activation behaviour - set the focus for the first child
1092 void wxFrameOS2::OnActivate(
1093 wxActivateEvent
& rEvent
1096 if ( rEvent
.GetActive() )
1098 // restore focus to the child which was last focused
1099 wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd
);
1101 wxWindow
* pParent
= m_pWinLastFocused
? m_pWinLastFocused
->GetParent()
1108 wxSetFocusToChild( pParent
1112 else // deactivating
1115 // Remember the last focused child if it is our child
1117 m_pWinLastFocused
= FindFocus();
1119 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1121 pNode
= pNode
->GetNext())
1123 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1124 // but how to do it without duplicating the code?
1127 wxWindow
* pChild
= pNode
->GetData();
1129 if (!pChild
->IsTopLevel()
1131 && !wxDynamicCast(pChild
, wxToolBar
)
1132 #endif // wxUSE_TOOLBAR
1134 && !wxDynamicCast(pChild
, wxStatusBar
)
1135 #endif // wxUSE_STATUSBAR
1143 } // end of wxFrameOS2::OnActivate
1145 // ----------------------------------------------------------------------------
1146 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1147 // from the client area, so the client area is what's really available for the
1149 // ----------------------------------------------------------------------------
1151 // Checks if there is a toolbar, and returns the first free client position
1152 wxPoint
wxFrameOS2::GetClientAreaOrigin() const
1154 wxPoint
vPoint(0, 0);
1162 GetToolBar()->GetSize( &nWidth
1166 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1172 // PM is backwards from windows
1173 vPoint
.y
+= nHeight
;
1176 #endif //wxUSE_TOOLBAR
1178 } // end of wxFrameOS2::GetClientAreaOrigin
1180 // ----------------------------------------------------------------------------
1181 // tool/status bar stuff
1182 // ----------------------------------------------------------------------------
1186 wxToolBar
* wxFrameOS2::CreateToolBar(
1189 , const wxString
& rName
1192 if (wxFrameBase::CreateToolBar( lStyle
1199 return m_frameToolBar
;
1200 } // end of wxFrameOS2::CreateToolBar
1202 void wxFrameOS2::PositionToolBar()
1207 ::WinQueryWindowRect(GetHwnd(), &vRect
);
1215 GetStatusBar()->GetClientSize( &nStatusX
1218 // PM is backwards from windows
1219 vRect
.yBottom
+= nStatusY
;
1221 #endif // wxUSE_STATUSBAR
1223 if ( m_frameToolBar
)
1228 m_frameToolBar
->GetSize( &nToolbarWidth
1232 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
1234 nToolbarHeight
= vRect
.yBottom
;
1238 nToolbarWidth
= vRect
.xRight
;
1242 // Use the 'real' PM position here
1244 GetToolBar()->SetSize( 0
1248 ,wxSIZE_NO_ADJUSTMENTS
1251 } // end of wxFrameOS2::PositionToolBar
1252 #endif // wxUSE_TOOLBAR
1254 // ----------------------------------------------------------------------------
1255 // frame state (iconized/maximized/...)
1256 // ----------------------------------------------------------------------------
1259 // propagate our state change to all child frames: this allows us to emulate X
1260 // Windows behaviour where child frames float independently of the parent one
1261 // on the desktop, but are iconized/restored with it
1263 void wxFrameOS2::IconizeChildFrames(
1267 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
1269 pNode
= pNode
->GetNext() )
1271 wxWindow
* pWin
= pNode
->GetData();
1273 if (pWin
->IsKindOf(CLASSINFO(wxFrame
)) )
1275 ((wxFrame
*)pWin
)->Iconize(bIconize
);
1278 } // end of wxFrameOS2::IconizeChildFrames
1280 // ===========================================================================
1281 // message processing
1282 // ===========================================================================
1284 // ---------------------------------------------------------------------------
1286 // ---------------------------------------------------------------------------
1287 bool wxFrameOS2::OS2TranslateMessage(
1292 // try the menu bar accels
1294 wxMenuBar
* pMenuBar
= GetMenuBar();
1300 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
1301 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
1304 #endif //wxUSE_ACCEL
1305 } // end of wxFrameOS2::OS2TranslateMessage
1307 // ---------------------------------------------------------------------------
1308 // our private (non virtual) message handlers
1309 // ---------------------------------------------------------------------------
1310 bool wxFrameOS2::HandlePaint()
1314 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
1319 // Icons in PM are the same as "pointers"
1324 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
1326 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1329 // Hold a pointer to the dc so long as the OnPaint() message
1330 // is being processed
1333 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
1336 // Erase background before painting or we get white background
1338 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
1345 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
1347 static const int nIconWidth
= 32;
1348 static const int nIconHeight
= 32;
1349 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
1350 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
1352 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
1359 return(wxWindow::HandlePaint());
1364 // nothing to paint - processed
1368 } // end of wxFrameOS2::HandlePaint
1370 bool wxFrameOS2::HandleSize(
1376 bool bProcessed
= FALSE
;
1382 // Only do it it if we were iconized before, otherwise resizing the
1383 // parent frame has a curious side effect of bringing it under it's
1389 // restore all child frames too
1391 IconizeChildFrames(FALSE
);
1392 (void)SendIconizeEvent(FALSE
);
1399 m_bIconized
= FALSE
;
1404 // Iconize all child frames too
1406 IconizeChildFrames(TRUE
);
1407 (void)SendIconizeEvent();
1415 // forward WM_SIZE to status bar control
1417 #if wxUSE_NATIVE_STATUSBAR
1418 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
1420 wxSizeEvent
vEvent( wxSize( nX
1423 ,m_frameStatusBar
->GetId()
1426 vEvent
.SetEventObject(m_frameStatusBar
);
1427 m_frameStatusBar
->OnSize(vEvent
);
1429 #endif // wxUSE_NATIVE_STATUSBAR
1431 PositionStatusBar();
1434 #endif // wxUSE_TOOLBAR
1436 wxSizeEvent
vEvent( wxSize( nX
1442 vEvent
.SetEventObject(this);
1443 bProcessed
= GetEventHandler()->ProcessEvent(vEvent
);
1446 } // end of wxFrameOS2::HandleSize
1448 bool wxFrameOS2::HandleCommand(
1457 // In case it's e.g. a toolbar.
1459 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1462 return pWin
->OS2Command( nCmd
1468 // Handle here commands from menus and accelerators
1470 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1472 if (wxCurrentPopupMenu
)
1474 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1476 wxCurrentPopupMenu
= NULL
;
1478 return pPopupMenu
->OS2Command( nCmd
1483 if (ProcessCommand(nId
))
1489 } // end of wxFrameOS2::HandleCommand
1491 bool wxFrameOS2::HandleMenuSelect(
1502 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1504 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1506 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1508 vEvent
.SetEventObject(this);
1509 GetEventHandler()->ProcessEvent(vEvent
); // return value would be ignored by PM
1513 } // end of wxFrameOS2::HandleMenuSelect
1515 // ---------------------------------------------------------------------------
1516 // Main Frame window proc
1517 // ---------------------------------------------------------------------------
1518 MRESULT EXPENTRY
wxFrameMainWndProc(
1525 MRESULT rc
= (MRESULT
)0;
1526 bool bProcessed
= FALSE
;
1527 wxFrame
* pWnd
= NULL
;
1529 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1532 case WM_QUERYFRAMECTLCOUNT
:
1533 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1535 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1537 rc
= MRFROMSHORT(uItemCount
);
1541 case WM_FORMATFRAME
:
1542 /////////////////////////////////////////////////////////////////////////////////
1543 // Applications that subclass frame controls may find that the frame is already
1544 // subclassed the number of frame controls is variable.
1545 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1546 // subclassed by calling the previous window procedure and modifying its result.
1547 ////////////////////////////////////////////////////////////////////////////////
1557 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1558 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1559 if(pWnd
->m_frameStatusBar
)
1561 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1562 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1563 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1564 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1566 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1568 vSwpStb
.x
= vRectl
.xLeft
- vRstb
.xLeft
;
1569 vSwpStb
.y
= vRectl
.yBottom
- vRstb
.yBottom
;
1570 vSwpStb
.cx
= vRectl
.xRight
- vRectl
.xLeft
- 1; //?? -1 ??
1571 vSwpStb
.cy
= nHeight
;
1572 vSwpStb
.fl
= SWP_SIZE
|SWP_MOVE
| SWP_SHOW
;
1573 vSwpStb
.hwnd
= pWnd
->m_frameStatusBar
->GetHWND();
1574 vSwpStb
.hwndInsertBehind
= HWND_TOP
;
1576 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1577 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1578 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1579 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1580 for(i
= 0; i
< nItemCount
; i
++)
1582 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1584 pSWP
[i
].x
= vRectl
.xLeft
;
1585 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1586 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1587 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1588 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1589 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1593 rc
= MRFROMSHORT(nItemCount
);
1598 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1599 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1601 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1604 } // end of wxFrameMainWndProc
1606 MRESULT EXPENTRY
wxFrameWndProc(
1614 // Trace all ulMsgs - useful for the debugging
1617 wxFrame
* pWnd
= NULL
;
1619 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1620 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1623 // When we get the first message for the HWND we just created, we associate
1624 // it with wxWindow stored in wxWndHook
1627 MRESULT rc
= (MRESULT
)0;
1628 bool bProcessed
= FALSE
;
1631 // Stop right here if we don't have a valid handle in our wxWindow object.
1633 if (pWnd
&& !pWnd
->GetHWND())
1635 pWnd
->SetHWND((WXHWND
) hWnd
);
1636 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1642 rc
= pWnd
->OS2WindowProc(ulMsg
, wParam
, lParam
);
1644 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1647 } // end of wxFrameWndProc
1649 MRESULT
wxFrameOS2::OS2WindowProc(
1656 bool bProcessed
= FALSE
;
1662 // If we can't close, tell the system that we processed the
1663 // message - otherwise it would close us
1665 bProcessed
= !Close();
1669 bProcessed
= HandlePaint();
1670 mRc
= (MRESULT
)FALSE
;
1673 case WM_ERASEBACKGROUND
:
1675 // Returning TRUE to requests PM to paint the window background
1676 // in SYSCLR_WINDOW. We capture this here because the PS returned
1677 // in Frames is the PS for the whole frame, which we can't really
1678 // use at all. If you want to paint a different background, do it
1679 // in an OnPaint using a wxPaintDC.
1681 mRc
= (MRESULT
)(TRUE
);
1690 UnpackCommand( (WXWPARAM
)wParam
1697 bProcessed
= HandleCommand( wId
1710 UnpackMenuSelect( wParam
1716 bProcessed
= HandleMenuSelect( wItem
1720 mRc
= (MRESULT
)TRUE
;
1726 SHORT nScxold
= SHORT1FROMMP(wParam
); // Old horizontal size.
1727 SHORT nScyold
= SHORT2FROMMP(wParam
); // Old vertical size.
1728 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1729 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1731 lParam
= MRFROM2SHORT( nScxnew
- 20
1735 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1736 mRc
= (MRESULT
)FALSE
;
1739 case CM_QUERYDRAGIMAGE
:
1744 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1746 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1747 mRc
= (MRESULT
)hIcon
;
1748 bProcessed
= mRc
!= 0;
1754 mRc
= wxWindow::OS2WindowProc( uMessage
1758 return (MRESULT
)mRc
;
1759 } // wxFrameOS2::OS2WindowProc
1761 void wxFrameOS2::SetClient(WXHWND c_Hwnd
)
1763 // Duh...nothing to do under OS/2
1766 void wxFrameOS2::SetClient(
1770 wxWindow
* pOldClient
= this->GetClient();
1771 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1773 if(pOldClient
== pWindow
) // nothing to do
1775 if(pWindow
== NULL
) // just need to remove old client
1777 if(pOldClient
== NULL
) // nothing to do
1780 if(bClientHasFocus
)
1783 pOldClient
->Enable( FALSE
);
1784 pOldClient
->Show( FALSE
);
1785 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1786 // to avoid OS/2 bug need to update frame
1787 ::WinSendMsg((HWND
)this->GetFrame(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1792 // Else need to change client
1797 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1800 pOldClient
->Enable(FALSE
);
1801 pOldClient
->Show(FALSE
);
1802 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1804 pWindow
->Reparent(this);
1805 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1806 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1808 pWindow
->Show(); // ensure client is showing
1809 if( this->IsShown() )
1812 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1816 wxWindow
* wxFrameOS2::GetClient()
1818 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(m_hFrame
, FID_CLIENT
));