1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/frame.cpp
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"
16 #include "wx/object.h"
17 #include "wx/dynarray.h"
20 #include "wx/string.h"
28 #include "wx/dialog.h"
29 #include "wx/settings.h"
30 #include "wx/dcclient.h"
32 #include "wx/toolbar.h"
33 #include "wx/statusbr.h"
34 #include "wx/menuitem.h"
37 #include "wx/os2/private.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 #if wxUSE_MENUS_NATIVE
44 extern wxMenu
*wxCurrentPopupMenu
;
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
)
52 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
)
55 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
57 // ============================================================================
59 // ============================================================================
61 // ----------------------------------------------------------------------------
62 // static class members
63 // ----------------------------------------------------------------------------
66 #if wxUSE_NATIVE_STATUSBAR
67 bool wxFrame::m_bUseNativeStatusBar
= true;
69 bool wxFrame::m_bUseNativeStatusBar
= false;
72 #endif //wxUSE_STATUSBAR
74 // ----------------------------------------------------------------------------
75 // creation/destruction
76 // ----------------------------------------------------------------------------
80 m_nFsStatusBarFields
= 0;
81 m_nFsStatusBarHeight
= 0;
82 m_nFsToolBarHeight
= 0;
84 m_bWasMinimized
= false;
87 m_frameMenuBar
= NULL
;
88 m_frameToolBar
= NULL
;
89 m_frameStatusBar
= NULL
;
91 m_hTitleBar
= NULLHANDLE
;
92 m_hHScroll
= NULLHANDLE
;
93 m_hVScroll
= NULLHANDLE
;
98 memset(&m_vSwpTitleBar
, 0, sizeof(SWP
));
99 memset(&m_vSwpMenuBar
, 0, sizeof(SWP
));
100 memset(&m_vSwpHScroll
, 0, sizeof(SWP
));
101 memset(&m_vSwpVScroll
, 0, sizeof(SWP
));
102 memset(&m_vSwpStatusBar
, 0, sizeof(SWP
));
103 memset(&m_vSwpToolBar
, 0, sizeof(SWP
));
106 } // end of wxFrame::Init
108 bool wxFrame::Create( wxWindow
* pParent
,
110 const wxString
& rsTitle
,
114 const wxString
& rsName
)
116 if (!wxTopLevelWindow::Create( pParent
126 } // end of wxFrame::Create
130 m_isBeingDeleted
= true;
132 } // end of wxFrame::~wxFrame
135 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
137 void wxFrame::DoGetClientSize(
142 wxTopLevelWindow::DoGetClientSize( pX
146 // No need to use statusbar code as in WIN32 as the FORMATFRAME
147 // window procedure ensures PM knows about the new frame client
148 // size internally. A ::WinQueryWindowRect (that is called in
149 // wxWindow's GetClient size from above) is all that is needed!
151 } // end of wxFrame::DoGetClientSize
154 // Set the client size (i.e. leave the calculation of borders etc.
157 void wxFrame::DoSetClientSize(
163 // Statusbars are not part of the OS/2 Client but parent frame
164 // so no statusbar consideration
166 wxTopLevelWindow::DoSetClientSize( nWidth
169 } // end of wxFrame::DoSetClientSize
171 // ----------------------------------------------------------------------------
172 // wxFrame: various geometry-related functions
173 // ----------------------------------------------------------------------------
175 void wxFrame::Raise()
177 wxFrameBase::Raise();
178 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
189 wxStatusBar
* wxFrame::OnCreateStatusBar(
193 , const wxString
& rName
196 wxStatusBar
* pStatusBar
= NULL
;
199 pStatusBar
= wxFrameBase::OnCreateStatusBar( nNumber
208 wxClientDC
vDC(pStatusBar
);
212 // Set the height according to the font and the border size
214 vDC
.SetFont(pStatusBar
->GetFont()); // Screws up the menues for some reason
215 vDC
.GetTextExtent( wxT("X")
220 int nHeight
= ((11 * nY
) / 10 + 2 * pStatusBar
->GetBorderY());
222 pStatusBar
->SetSize( wxDefaultCoord
228 ::WinSetParent( pStatusBar
->GetHWND(), m_hFrame
, FALSE
);
229 ::WinSetOwner( pStatusBar
->GetHWND(), m_hFrame
);
233 if(::WinIsWindowShowing(m_hFrame
))
234 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
237 } // end of wxFrame::OnCreateStatusBar
239 void wxFrame::PositionStatusBar()
246 // Native status bar positions itself
248 if (m_frameStatusBar
)
257 ::WinQueryWindowRect(m_hFrame
, &vRect
);
259 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
261 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
262 nWidth
= vRect
.xRight
- vRect
.xLeft
;
263 nY
= nY
- (vRect
.yBottom
- vFRect
.yBottom
);
265 m_frameStatusBar
->GetSize( &nStatbarWidth
269 nY
= nY
- nStatbarHeight
;
271 // Since we wish the status bar to be directly under the client area,
272 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
274 m_frameStatusBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
279 if (!::WinQueryWindowPos(m_frameStatusBar
->GetHWND(), &vSwp
))
281 vError
= ::WinGetLastError(vHabmain
);
282 sError
= wxPMErrorToStr(vError
);
283 wxLogError(_T("Error setting parent for StatusBar. Error: %s\n"), sError
.c_str());
287 } // end of wxFrame::PositionStatusBar
288 #endif // wxUSE_STATUSBAR
291 wxToolBar
* wxFrame::OnCreateToolBar( long lStyle
, wxWindowID vId
, const wxString
& rsName
)
293 wxToolBar
* pToolBar
= wxFrameBase::OnCreateToolBar( lStyle
298 ::WinSetParent( pToolBar
->GetHWND(), m_hFrame
, FALSE
);
299 ::WinSetOwner( pToolBar
->GetHWND(), m_hFrame
);
301 } // end of WinGuiBase_CFrame::OnCreateToolBar
304 #if wxUSE_MENUS_NATIVE
305 void wxFrame::DetachMenuBar()
309 m_frameMenuBar
->Detach();
310 m_frameMenuBar
= NULL
;
312 } // end of wxFrame::DetachMenuBar
314 void wxFrame::SetMenuBar(
325 // Actually remove the menu from the frame
327 m_hMenu
= (WXHMENU
)0;
328 InternalSetMenuBar();
330 else // set new non NULL menu bar
332 m_frameMenuBar
= NULL
;
335 // Can set a menubar several times.
336 // TODO: how to prevent a memory leak if you have a currently-unattached
337 // menubar? wxWidgets assumes that the frame will delete the menu (otherwise
338 // there are problems for MDI).
340 if (pMenuBar
->GetHMenu())
342 m_hMenu
= pMenuBar
->GetHMenu();
347 m_hMenu
= pMenuBar
->Create();
351 InternalSetMenuBar();
352 m_frameMenuBar
= pMenuBar
;
353 pMenuBar
->Attach((wxFrame
*)this);
355 } // end of wxFrame::SetMenuBar
357 void wxFrame::AttachMenuBar(
361 wxFrameBase::AttachMenuBar(pMenubar
);
363 m_frameMenuBar
= pMenubar
;
368 // Actually remove the menu from the frame
370 m_hMenu
= (WXHMENU
)0;
371 InternalSetMenuBar();
373 else // Set new non NULL menu bar
376 // Can set a menubar several times.
378 if (pMenubar
->GetHMenu())
380 m_hMenu
= pMenubar
->GetHMenu();
384 if (pMenubar
->IsAttached())
387 m_hMenu
= pMenubar
->Create();
392 InternalSetMenuBar();
394 } // end of wxFrame::AttachMenuBar
396 void wxFrame::InternalSetMenuBar()
401 // Set the parent and owner of the menubar to be the frame
403 if (!::WinSetParent(m_hMenu
, m_hFrame
, FALSE
))
405 vError
= ::WinGetLastError(vHabmain
);
406 sError
= wxPMErrorToStr(vError
);
407 wxLogError(_T("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
410 if (!::WinSetOwner(m_hMenu
, m_hFrame
))
412 vError
= ::WinGetLastError(vHabmain
);
413 sError
= wxPMErrorToStr(vError
);
414 wxLogError(_T("Error setting parent for submenu. Error: %s\n"), sError
.c_str());
416 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
417 } // end of wxFrame::InternalSetMenuBar
418 #endif // wxUSE_MENUS_NATIVE
421 // Responds to colour changes, and passes event on to children
423 void wxFrame::OnSysColourChanged(
424 wxSysColourChangedEvent
& rEvent
427 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
));
431 if (m_frameStatusBar
)
433 wxSysColourChangedEvent vEvent2
;
435 vEvent2
.SetEventObject(m_frameStatusBar
);
436 m_frameStatusBar
->HandleWindowEvent(vEvent2
);
438 #endif //wxUSE_STATUSBAR
441 // Propagate the event to the non-top-level children
443 wxWindow::OnSysColourChanged(rEvent
);
444 } // end of wxFrame::OnSysColourChanged
446 // Pass true to show full screen, false to restore.
447 bool wxFrame::ShowFullScreen( bool bShow
, long lStyle
)
454 m_bFsIsShowing
= true;
458 wxToolBar
* pTheToolBar
= GetToolBar();
459 #endif //wxUSE_TOOLBAR
462 wxStatusBar
* pTheStatusBar
= GetStatusBar();
463 #endif //wxUSE_STATUSBAR
469 pTheToolBar
->GetSize(&nDummyWidth
, &m_nFsToolBarHeight
);
470 #endif //wxUSE_TOOLBAR
474 pTheStatusBar
->GetSize(&nDummyWidth
, &m_nFsStatusBarHeight
);
475 #endif //wxUSE_STATUSBAR
479 // Zap the toolbar, menubar, and statusbar
481 if ((lStyle
& wxFULLSCREEN_NOTOOLBAR
) && pTheToolBar
)
483 pTheToolBar
->SetSize(wxDefaultCoord
,0);
484 pTheToolBar
->Show(false);
486 #endif //wxUSE_TOOLBAR
488 if (lStyle
& wxFULLSCREEN_NOMENUBAR
)
490 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
491 ::WinSetOwner(m_hMenu
, m_hFrame
);
492 ::WinSendMsg((HWND
)m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
497 // Save the number of fields in the statusbar
499 if ((lStyle
& wxFULLSCREEN_NOSTATUSBAR
) && pTheStatusBar
)
501 m_nFsStatusBarFields
= pTheStatusBar
->GetFieldsCount();
503 delete pTheStatusBar
;
506 m_nFsStatusBarFields
= 0;
507 #endif //wxUSE_STATUSBAR
510 // Zap the frame borders
514 // Save the 'normal' window style
516 m_lFsOldWindowStyle
= ::WinQueryWindowULong(m_hFrame
, QWL_STYLE
);
519 // Save the old position, width & height, maximize state
521 m_vFsOldSize
= GetRect();
522 m_bFsIsMaximized
= IsMaximized();
525 // Decide which window style flags to turn off
527 LONG lNewStyle
= m_lFsOldWindowStyle
;
530 if (lStyle
& wxFULLSCREEN_NOBORDER
)
531 lOffFlags
|= FCF_BORDER
;
532 if (lStyle
& wxFULLSCREEN_NOCAPTION
)
533 lOffFlags
|= (FCF_TASKLIST
| FCF_SYSMENU
);
535 lNewStyle
&= (~lOffFlags
);
538 // Change our window style to be compatible with full-screen mode
540 ::WinSetWindowULong((HWND
)m_hFrame
, QWL_STYLE
, (ULONG
)lNewStyle
);
543 // Resize to the size of the desktop
549 ::WinQueryWindowRect(HWND_DESKTOP
, &vRect
);
550 nWidth
= vRect
.xRight
- vRect
.xLeft
;
552 // Remember OS/2 is backwards!
554 nHeight
= vRect
.yTop
- vRect
.yBottom
;
556 SetSize( nWidth
, nHeight
);
559 // Now flush the window style cache and actually go full-screen
561 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
570 wxSize
sz( nWidth
, nHeight
);
571 wxSizeEvent
vEvent( sz
, GetId() );
573 HandleWindowEvent(vEvent
);
581 m_bFsIsShowing
= false;
584 wxToolBar
* pTheToolBar
= GetToolBar();
587 // Restore the toolbar, menubar, and statusbar
589 if (pTheToolBar
&& (m_lFsStyle
& wxFULLSCREEN_NOTOOLBAR
))
591 pTheToolBar
->SetSize(wxDefaultCoord
, m_nFsToolBarHeight
);
592 pTheToolBar
->Show(true);
594 #endif //wxUSE_TOOLBAR
597 if ((m_lFsStyle
& wxFULLSCREEN_NOSTATUSBAR
) && (m_nFsStatusBarFields
> 0))
599 CreateStatusBar(m_nFsStatusBarFields
);
600 // PositionStatusBar();
602 #endif //wxUSE_STATUSBAR
604 if ((m_lFsStyle
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu
!= 0))
606 ::WinSetParent(m_hMenu
, m_hFrame
, FALSE
);
607 ::WinSetOwner(m_hMenu
, m_hFrame
);
608 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)FCF_MENU
, (MPARAM
)0);
610 Maximize(m_bFsIsMaximized
);
612 ::WinSetWindowULong( m_hFrame
614 ,(ULONG
)m_lFsOldWindowStyle
616 ::WinSetWindowPos( (HWND
) GetParent()->GetHWND()
625 return wxFrameBase::ShowFullScreen(bShow
, lStyle
);
626 } // end of wxFrame::ShowFullScreen
631 // ----------------------------------------------------------------------------
632 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
633 // from the client area, so the client area is what's really available for the
635 // ----------------------------------------------------------------------------
637 // Checks if there is a toolbar, and returns the first free client position
638 wxPoint
wxFrame::GetClientAreaOrigin() const
640 wxPoint vPoint
= wxTopLevelWindow::GetClientAreaOrigin();
643 // In OS/2 the toolbar and statusbar are frame extensions so there is no
644 // adjustment. The client is supposedly resized for a toolbar in OS/2
645 // as it is for the status bar.
648 } // end of wxFrame::GetClientAreaOrigin
650 // ----------------------------------------------------------------------------
651 // tool/status bar stuff
652 // ----------------------------------------------------------------------------
656 wxToolBar
* wxFrame::CreateToolBar(
659 , const wxString
& rName
662 if (wxFrameBase::CreateToolBar( lStyle
669 return m_frameToolBar
;
670 } // end of wxFrame::CreateToolBar
672 void wxFrame::PositionToolBar()
674 wxToolBar
* pToolBar
= GetToolBar();
687 ::WinQueryWindowRect(m_hFrame
, &vRect
);
688 vPos
.y
= (wxCoord
)vRect
.yTop
;
689 ::WinMapWindowPoints(m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRect
, 2);
691 ::WinCalcFrameRect(m_hFrame
, &vRect
, TRUE
);
693 vPos
.y
= (wxCoord
)(vFRect
.yTop
- vRect
.yTop
);
694 pToolBar
->GetSize( &vTWidth
698 if (pToolBar
->GetWindowStyleFlag() & wxTB_TOP
)
700 vWidth
= (wxCoord
)(vRect
.xRight
- vRect
.xLeft
);
701 pToolBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
707 else if (pToolBar
->GetWindowStyleFlag() & wxTB_BOTTOM
)
710 wxCoord vSheight
= 0;
712 if (m_frameStatusBar
)
713 m_frameStatusBar
->GetSize( &vSwidth
716 vWidth
= (wxCoord
)(vRect
.xRight
- vRect
.xLeft
);
717 pToolBar
->SetSize( vRect
.xLeft
- vFRect
.xLeft
718 ,vFRect
.yTop
- vRect
.yBottom
- vTHeight
- vSheight
723 else if (pToolBar
->GetWindowStyleFlag() & wxTB_LEFT
)
726 wxCoord vSheight
= 0;
728 if (m_frameStatusBar
)
729 m_frameStatusBar
->GetSize( &vSwidth
732 vHeight
= (wxCoord
)(vRect
.yTop
- vRect
.yBottom
);
733 pToolBar
->SetSize( vRect
.xLeft
- vRect
.xLeft
742 wxCoord vSheight
= 0;
744 if (m_frameStatusBar
)
745 m_frameStatusBar
->GetSize( &vSwidth
748 vHeight
= (wxCoord
)(vRect
.yTop
- vRect
.yBottom
);
749 pToolBar
->SetSize( vRect
.xRight
- vFRect
.xLeft
- vTWidth
755 if( ::WinIsWindowShowing(m_hFrame
) )
756 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
757 } // end of wxFrame::PositionToolBar
758 #endif // wxUSE_TOOLBAR
760 // ----------------------------------------------------------------------------
761 // frame state (iconized/maximized/...)
762 // ----------------------------------------------------------------------------
765 // propagate our state change to all child frames: this allows us to emulate X
766 // Windows behaviour where child frames float independently of the parent one
767 // on the desktop, but are iconized/restored with it
769 void wxFrame::IconizeChildFrames( bool WXUNUSED(bIconize
) )
771 // FIXME: Generic MDI does not use Frames for the Childs, so this does _not_
772 // work. Possibly, the right thing is simply to eliminate this
773 // functions and all the calls to it from within this file.
775 for (wxWindowList::Node
* pNode
= GetChildren().GetFirst();
777 pNode
= pNode
->GetNext() )
779 wxWindow
* pWin
= pNode
->GetData();
780 wxFrame
* pFrame
= wxDynamicCast(pWin
, wxFrame
);
783 #if wxUSE_MDI_ARCHITECTURE
784 && !wxDynamicCast(pFrame
, wxMDIChildFrame
)
785 #endif // wxUSE_MDI_ARCHITECTURE
789 // We don't want to restore the child frames which had been
790 // iconized even before we were iconized, so save the child frame
791 // status when iconizing the parent frame and check it when
796 pFrame
->m_bWasMinimized
= pFrame
->IsIconized();
800 // This test works for both iconizing and restoring
802 if (!pFrame
->m_bWasMinimized
)
803 pFrame
->Iconize(bIconize
);
807 } // end of wxFrame::IconizeChildFrames
809 WXHICON
wxFrame::GetDefaultIcon() const
811 return (WXHICON
)(wxSTD_FRAME_ICON
? wxSTD_FRAME_ICON
812 : wxDEFAULT_FRAME_ICON
);
814 // ===========================================================================
815 // message processing
816 // ===========================================================================
818 // ---------------------------------------------------------------------------
820 // ---------------------------------------------------------------------------
821 bool wxFrame::OS2TranslateMessage( WXMSG
* pMsg
)
824 // try the menu bar accels
826 wxMenuBar
* pMenuBar
= GetMenuBar();
831 #if wxUSE_ACCEL && wxUSE_MENUS_NATIVE
832 const wxAcceleratorTable
& rAcceleratorTable
= pMenuBar
->GetAccelTable();
833 return rAcceleratorTable
.Translate(GetHWND(), pMsg
);
837 } // end of wxFrame::OS2TranslateMessage
839 // ---------------------------------------------------------------------------
840 // our private (non virtual) message handlers
841 // ---------------------------------------------------------------------------
842 bool wxFrame::HandlePaint()
846 if (::WinQueryUpdateRect(GetHWND(), &vRect
))
851 // Icons in PM are the same as "pointers"
853 const wxIcon
& vIcon
= GetIcon();
857 hIcon
= (HPOINTER
)::WinSendMsg(m_hFrame
, WM_QUERYICON
, 0L, 0L);
859 hIcon
= (HPOINTER
)m_hDefaultIcon
;
862 // Hold a pointer to the dc so long as the OnPaint() message
863 // is being processed
866 HPS hPs
= ::WinBeginPaint(GetHwnd(), NULLHANDLE
, &vRect2
);
869 // Erase background before painting or we get white background
871 OS2DefWindowProc(WM_ERASEBACKGROUND
, (MPARAM
)hPs
, (MPARAM
)&vRect2
);
877 ::WinQueryWindowRect(GetHwnd(), &vRect3
);
879 static const int nIconWidth
= 32;
880 static const int nIconHeight
= 32;
881 int nIconX
= (int)((vRect3
.xRight
- nIconWidth
)/2);
882 int nIconY
= (int)((vRect3
.yBottom
+ nIconHeight
)/2);
884 ::WinDrawPointer(hPs
, nIconX
, nIconY
, hIcon
, DP_NORMAL
);
890 if (!wxWindow::HandlePaint())
895 hPS
= ::WinBeginPaint( GetHwnd()
901 ::GpiCreateLogColorTable( hPS
905 ,(LONG
)wxTheColourDatabase
->m_nSize
906 ,(PLONG
)wxTheColourDatabase
->m_palTable
908 ::GpiCreateLogColorTable( hPS
918 ,GetBackgroundColour().GetPixel()
927 } // end of wxFrame::HandlePaint
929 bool wxFrame::HandleSize( int nX
, int nY
, WXUINT nId
)
931 bool bProcessed
= false;
937 // Only do it it if we were iconized before, otherwise resizing the
938 // parent frame has a curious side effect of bringing it under it's
944 // restore all child frames too
946 IconizeChildFrames(false);
947 (void)SendIconizeEvent(false);
959 // Iconize all child frames too
961 IconizeChildFrames(true);
962 (void)SendIconizeEvent();
970 // forward WM_SIZE to status bar control
972 #if wxUSE_NATIVE_STATUSBAR
973 if (m_frameStatusBar
&& m_frameStatusBar
->IsKindOf(CLASSINFO(wxStatusBar95
)))
975 wxSizeEvent
vEvent( wxSize( nX
978 ,m_frameStatusBar
->GetId()
981 vEvent
.SetEventObject(m_frameStatusBar
);
982 m_frameStatusBar
->OnSize(vEvent
);
984 #endif // wxUSE_NATIVE_STATUSBAR
989 #endif // wxUSE_TOOLBAR
991 bProcessed
= wxWindow::HandleSize( nX
997 } // end of wxFrame::HandleSize
999 bool wxFrame::HandleCommand( WXWORD nId
,
1006 // In case it's e.g. a toolbar.
1008 wxWindow
* pWin
= wxFindWinFromHandle(hControl
);
1011 return pWin
->OS2Command( nCmd
, nId
);
1015 // Handle here commands from menus and accelerators
1017 if (nCmd
== CMDSRC_MENU
|| nCmd
== CMDSRC_ACCELERATOR
)
1019 #if wxUSE_MENUS_NATIVE
1020 if (wxCurrentPopupMenu
)
1022 wxMenu
* pPopupMenu
= wxCurrentPopupMenu
;
1024 wxCurrentPopupMenu
= NULL
;
1026 return pPopupMenu
->OS2Command( nCmd
, nId
);
1030 if (ProcessCommand(nId
))
1036 } // end of wxFrame::HandleCommand
1038 bool wxFrame::HandleMenuSelect( WXWORD nItem
,
1047 rc
= ::WinSendMsg(hMenu
, MM_QUERYITEM
, MPFROM2SHORT(nItem
, TRUE
), (MPARAM
)&mItem
);
1049 if(rc
&& !(mItem
.afStyle
& (MIS_SUBMENU
| MIS_SEPARATOR
)))
1051 wxMenuEvent
vEvent(wxEVT_MENU_HIGHLIGHT
, nItem
);
1053 vEvent
.SetEventObject(this);
1054 HandleWindowEvent(vEvent
); // return value would be ignored by PM
1058 DoGiveHelp(wxEmptyString
, true);
1063 } // end of wxFrame::HandleMenuSelect
1065 // ---------------------------------------------------------------------------
1066 // Main Frame window proc
1067 // ---------------------------------------------------------------------------
1068 MRESULT EXPENTRY
wxFrameMainWndProc( HWND hWnd
,
1073 MRESULT rc
= (MRESULT
)0;
1074 bool bProcessed
= false;
1075 wxFrame
* pWnd
= NULL
;
1077 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1080 case WM_QUERYFRAMECTLCOUNT
:
1081 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1083 USHORT uItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1085 rc
= MRFROMSHORT(uItemCount
);
1089 case WM_FORMATFRAME
:
1090 /////////////////////////////////////////////////////////////////////////////////
1091 // Applications that subclass frame controls may find that the frame is already
1092 // subclassed the number of frame controls is variable.
1093 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1094 // subclassed by calling the previous window procedure and modifying its result.
1095 ////////////////////////////////////////////////////////////////////////////////
1107 pSWP
= (PSWP
)PVOIDFROMMP(wParam
);
1108 nItemCount
= SHORT1FROMMR(pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
));
1109 if(pWnd
->m_frameStatusBar
)
1111 ::WinQueryWindowRect(pWnd
->m_frameStatusBar
->GetHWND(), &vRstb
);
1112 pWnd
->m_frameStatusBar
->GetSize(NULL
, &nHeight
);
1114 if(pWnd
->m_frameToolBar
)
1116 ::WinQueryWindowRect(pWnd
->m_frameToolBar
->GetHWND(), &vRtlb
);
1117 pWnd
->m_frameToolBar
->GetSize(&nWidth
, &nHeight2
);
1119 ::WinQueryWindowRect(pWnd
->m_hFrame
, &vRectl
);
1120 ::WinMapWindowPoints(pWnd
->m_hFrame
, HWND_DESKTOP
, (PPOINTL
)&vRectl
, 2);
1121 ::WinCalcFrameRect(pWnd
->m_hFrame
, &vRectl
, TRUE
);
1122 ::WinMapWindowPoints(HWND_DESKTOP
, pWnd
->m_hFrame
, (PPOINTL
)&vRectl
, 2);
1123 for(i
= 0; i
< nItemCount
; i
++)
1125 if(pWnd
->m_hWnd
&& pSWP
[i
].hwnd
== pWnd
->m_hWnd
)
1127 if (pWnd
->m_frameToolBar
&& pWnd
->m_frameToolBar
->GetWindowStyleFlag() & wxTB_TOP
)
1129 pSWP
[i
].x
= vRectl
.xLeft
;
1130 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1131 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1132 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- (nHeight
+ nHeight2
);
1134 else if (pWnd
->m_frameToolBar
&& pWnd
->m_frameToolBar
->GetWindowStyleFlag() & wxTB_BOTTOM
)
1136 pSWP
[i
].x
= vRectl
.xLeft
;
1137 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
+ nHeight2
;
1138 pSWP
[i
].cx
= vRectl
.xRight
- vRectl
.xLeft
;
1139 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- (nHeight
+ nHeight2
);
1141 else if (pWnd
->m_frameToolBar
&& pWnd
->m_frameToolBar
->GetWindowStyleFlag() & wxTB_LEFT
)
1143 pSWP
[i
].x
= vRectl
.xLeft
+ nWidth
;
1144 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1145 pSWP
[i
].cx
= vRectl
.xRight
- (vRectl
.xLeft
+ nWidth
);
1146 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1150 pSWP
[i
].x
= vRectl
.xLeft
;
1151 pSWP
[i
].y
= vRectl
.yBottom
+ nHeight
;
1152 pSWP
[i
].cx
= vRectl
.xRight
- (vRectl
.xLeft
+ nWidth
);
1153 pSWP
[i
].cy
= vRectl
.yTop
- vRectl
.yBottom
- nHeight
;
1155 pSWP
[i
].fl
= SWP_SIZE
| SWP_MOVE
| SWP_SHOW
;
1156 pSWP
[i
].hwndInsertBehind
= HWND_TOP
;
1160 rc
= MRFROMSHORT(nItemCount
);
1165 if(pWnd
&& pWnd
->m_fnOldWndProc
)
1166 rc
= pWnd
->m_fnOldWndProc(hWnd
, ulMsg
, wParam
, lParam
);
1168 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1171 } // end of wxFrameMainWndProc
1173 MRESULT EXPENTRY
wxFrameWndProc(
1181 // Trace all ulMsgs - useful for the debugging
1184 wxFrame
* pWnd
= NULL
;
1186 parentHwnd
= WinQueryWindow(hWnd
,QW_PARENT
);
1187 pWnd
= (wxFrame
*) wxFindWinFromHandle((WXHWND
) hWnd
);
1190 // When we get the first message for the HWND we just created, we associate
1191 // it with wxWindow stored in wxWndHook
1194 MRESULT rc
= (MRESULT
)0;
1197 // Stop right here if we don't have a valid handle in our wxWindow object.
1199 if (pWnd
&& !pWnd
->GetHWND())
1201 pWnd
->SetHWND((WXHWND
) hWnd
);
1202 rc
= pWnd
->OS2DefWindowProc(ulMsg
, wParam
, lParam
);
1208 rc
= pWnd
->OS2WindowProc(ulMsg
, wParam
, lParam
);
1210 rc
= ::WinDefWindowProc(hWnd
, ulMsg
, wParam
, lParam
);
1213 } // end of wxFrameWndProc
1215 MRESULT
wxFrame::OS2WindowProc( WXUINT uMessage
,
1220 bool bProcessed
= false;
1226 // If we can't close, tell the system that we processed the
1227 // message - otherwise it would close us
1229 bProcessed
= !Close();
1233 bProcessed
= HandlePaint();
1234 mRc
= (MRESULT
)FALSE
;
1237 case WM_ERASEBACKGROUND
:
1239 // Returning TRUE to requests PM to paint the window background
1240 // in SYSCLR_WINDOW. We capture this here because the PS returned
1241 // in Frames is the PS for the whole frame, which we can't really
1242 // use at all. If you want to paint a different background, do it
1243 // in an OnPaint using a wxPaintDC.
1245 mRc
= (MRESULT
)(TRUE
);
1254 UnpackCommand( (WXWPARAM
)wParam
1261 bProcessed
= HandleCommand( wId
1274 UnpackMenuSelect( wParam
1280 bProcessed
= HandleMenuSelect( wItem
1284 mRc
= (MRESULT
)TRUE
;
1290 SHORT nScxnew
= SHORT1FROMMP(lParam
); // New horizontal size.
1291 SHORT nScynew
= SHORT2FROMMP(lParam
); // New vertical size.
1293 lParam
= MRFROM2SHORT( nScxnew
- 20
1297 bProcessed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), (WXUINT
)wParam
);
1298 mRc
= (MRESULT
)FALSE
;
1301 case CM_QUERYDRAGIMAGE
:
1303 const wxIcon
& vIcon
= GetIcon();
1307 hIcon
= (HPOINTER
)::WinSendMsg(GetHWND(), WM_QUERYICON
, 0L, 0L);
1309 hIcon
= (HPOINTER
)m_hDefaultIcon
;
1310 mRc
= (MRESULT
)hIcon
;
1311 bProcessed
= mRc
!= 0;
1317 mRc
= wxWindow::OS2WindowProc( uMessage
1321 return (MRESULT
)mRc
;
1322 } // wxFrame::OS2WindowProc
1324 void wxFrame::SetClient(WXHWND
WXUNUSED(c_Hwnd
))
1326 // Duh...nothing to do under OS/2
1329 void wxFrame::SetClient( wxWindow
* pWindow
)
1331 wxWindow
* pOldClient
= this->GetClient();
1332 bool bClientHasFocus
= pOldClient
&& (pOldClient
== wxWindow::FindFocus());
1334 if(pOldClient
== pWindow
) // nothing to do
1336 if(pWindow
== NULL
) // just need to remove old client
1338 if(pOldClient
== NULL
) // nothing to do
1341 if(bClientHasFocus
)
1344 pOldClient
->Enable( false );
1345 pOldClient
->Show( false );
1346 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1347 // to avoid OS/2 bug need to update frame
1348 ::WinSendMsg((HWND
)this->GetFrame(), WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1353 // Else need to change client
1358 ::WinEnableWindowUpdate((HWND
)GetHWND(), FALSE
);
1361 pOldClient
->Enable(false);
1362 pOldClient
->Show(false);
1363 ::WinSetWindowUShort(pOldClient
->GetHWND(), QWS_ID
, (USHORT
)pOldClient
->GetId());
1365 pWindow
->Reparent(this);
1366 ::WinSetWindowUShort(pWindow
->GetHWND(), QWS_ID
, FID_CLIENT
);
1367 ::WinEnableWindowUpdate((HWND
)GetHWND(), TRUE
);
1369 pWindow
->Show(); // ensure client is showing
1370 if( this->IsShown() )
1373 ::WinSendMsg(m_hFrame
, WM_UPDATEFRAME
, (MPARAM
)~0, 0);
1377 wxWindow
* wxFrame::GetClient()
1379 return wxFindWinFromHandle((WXHWND
)::WinWindowFromID(m_hFrame
, FID_CLIENT
));