From 859e65deb544f039ff4a889da0a8047a0b8c9ca2 Mon Sep 17 00:00:00 2001 From: David Webster <Dave.Webster@bhmi.com> Date: Sun, 10 Feb 2002 04:34:34 +0000 Subject: [PATCH] New positioning code, eliminating a lot of extra, unnecessary methods git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14099 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/os2/frame.cpp | 1 - src/os2/toplevel.cpp | 175 ++++++-------------------------- src/os2/window.cpp | 237 ++++++++++++++++++++++--------------------- src/os2/wx23.def | 6 +- 4 files changed, 152 insertions(+), 267 deletions(-) diff --git a/src/os2/frame.cpp b/src/os2/frame.cpp index a273ada371..c2e3d87c83 100644 --- a/src/os2/frame.cpp +++ b/src/os2/frame.cpp @@ -1079,7 +1079,6 @@ bool wxFrame::HandleSize( vEvent.SetEventObject(this); bProcessed = GetEventHandler()->ProcessEvent(vEvent); - AlterChildPos(); } return bProcessed; } // end of wxFrame::HandleSize diff --git a/src/os2/toplevel.cpp b/src/os2/toplevel.cpp index 6be4e147df..55794c5bfe 100644 --- a/src/os2/toplevel.cpp +++ b/src/os2/toplevel.cpp @@ -291,6 +291,7 @@ bool wxTopLevelWindowOS2::CreateDialog( ,nHeight ,SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW ); + ::WinQueryWindowPos(GetHwnd(), GetSwp()); m_hFrame = m_hWnd; SubclassWin(m_hWnd); return TRUE; @@ -501,152 +502,6 @@ wxTopLevelWindowOS2::~wxTopLevelWindowOS2() } } // end of wxTopLevelWindowOS2::~wxTopLevelWindowOS2 -// -// IF we have child controls in the Frame's client we need to alter -// the y position, because, OS/2 controls are positioned relative to -// wxWindows orgin (top left) not the OS/2 origin (bottom left) -// -void wxTopLevelWindowOS2::AlterChildPos() -{ - // - // OS/2 is the only OS concerned about this - // - wxWindow* pChild = NULL; - wxControl* pCtrl = NULL; - RECTL vRect; - SWP vSwp; - - if (GetAutoLayout) - // - // Auto layouts taken care of elsewhere - // - return; - - ::WinQueryWindowRect(GetHwnd(), &vRect); - for (wxWindowList::Node* pNode = GetChildren().GetFirst(); - pNode; - pNode = pNode->GetNext()) - { - wxWindow* pChild = pNode->GetData(); - - ::WinQueryWindowPos(pChild->GetHWND(), &vSwp); - vSwp.y += (vRect.yTop - m_vSwpClient.cy); - if (pChild->IsKindOf(CLASSINFO(wxControl))) - { - pCtrl = wxDynamicCast(pChild, wxControl); - // - // Must deal with controls that have margins like ENTRYFIELD. The SWP - // struct of such a control will have and origin offset from its intended - // position by the width of the margins. - // - vSwp.y -= pCtrl->GetYComp(); - vSwp.x -= pCtrl->GetXComp(); - } - ::WinSetWindowPos( pChild->GetHWND() - ,HWND_TOP - ,vSwp.x - ,vSwp.y - ,vSwp.cx - ,vSwp.cy - ,SWP_MOVE - ); - ::WinQueryWindowPos(pChild->GetHWND(), &vSwp); - pChild = NULL; - } - ::WinQueryWindowPos(GetHwnd(), &m_vSwpClient); -} // end of wxTopLevelWindowOS2::AlterChildPos - -void wxTopLevelWindowOS2::UpdateInternalSize( - wxWindow* pChild -, int nChildWidth -, int nChildHeight -) -{ - int nWidthAdjust = 0; - int nHeightAdjust = 0; - int nPosX; - int nPosY; - bool bNewYSize = FALSE; - bool bNewXSize = FALSE; - - // - // Under OS/2, if we have a srolled window as the child, the - // scrollbars will be SIBLINGS of the scrolled window. So, in - // order to be able to display the scrollbars properly we have to - // resize the scrolled window. Of course, that means dealing with - // child windows of that window as well, because OS/2 does not - // tend to put them in the right place. - // - if (nChildHeight != m_vSwpClient.cy) - bNewYSize = TRUE; - if (nChildWidth != m_vSwpClient.cx) - bNewXSize = TRUE; - if (bNewXSize || bNewYSize) - pChild->SetSize( 0 - ,0 - ,nChildWidth - ,nChildHeight - ); - if(bNewYSize) - { - // - // This is needed SetSize will mess up the OS/2 child window - // positioning because we position in wxWindows coordinates, - // not OS/2 coordinates. - // - pChild->MoveChildren(m_vSwpClient.cy - nChildHeight); - pChild->Refresh(); - } - - if (pChild->GetScrollBarHorz() != NULLHANDLE || - pChild->GetScrollBarVert() != NULLHANDLE) - { - if (bNewXSize || bNewYSize) - { - pChild->GetSize( &nChildWidth - ,&nChildHeight - ); - if (pChild->GetScrollBarHorz() != NULLHANDLE) - nHeightAdjust = 20; - if (pChild->GetScrollBarVert() != NULLHANDLE) - nWidthAdjust = 20; - pChild->GetPosition( &nPosX - ,&nPosY - ); - ::WinSetWindowPos( pChild->GetHWND() - ,HWND_TOP - ,nPosX - ,nPosY + nHeightAdjust - ,nChildWidth - nWidthAdjust - ,nChildHeight - nHeightAdjust - ,SWP_MOVE | SWP_SIZE - ); - } - if (bNewYSize && !m_sbInitialized) - { - // - // Only need to readjust child control positions of - // scrolled windows once on initialization. After that - // the sizing takes care of things itself. - // - pChild->MoveChildren(nHeightAdjust); - m_sbInitialized = TRUE; - } - if (bNewXSize || bNewYSize) - { - // - // Always refresh to keep scollbars visible. They are - // children of the Toplevel window, not the child panel. - // - pChild->Refresh(); - } - } - // - // This brings the internal "last size" up to date. - // - ::WinQueryWindowPos(GetHwnd(), &m_vSwpClient); -} // end of wxTopLevelWindowOS2::UpdateInternalSize - // ---------------------------------------------------------------------------- // wxTopLevelWindowOS2 client size // ---------------------------------------------------------------------------- @@ -739,6 +594,34 @@ bool wxTopLevelWindowOS2::Show( ::WinQueryWindowPos(m_hWnd, &m_vSwpClient); ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0); ::WinEnableWindow(m_hFrame, TRUE); + + // + // Deal with children + // + MoveChildren(m_vSwpClient.cy - vSwp.cy); + + + // + // Need to handle the case of a single child that not a control + // as this is probably a panel with its own children + // + if (GetChildren().GetCount() > 0) + { + for (wxWindowList::Node* pNode = GetChildren().GetFirst(); + pNode; + pNode = pNode->GetNext()) + { + wxWindow* pChild = pNode->GetData(); + + if ( GetChildren().GetCount() == 1 && + !pChild->IsKindOf(CLASSINFO(wxControl)) + ) + pChild->MoveChildren(m_vSwpClient.cy - vSwp.cy); + pChild->Refresh(); + pChild = NULL; + } + } + vEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(vEvent); } diff --git a/src/os2/window.cpp b/src/os2/window.cpp index 935143f040..61e1e63601 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -1,4 +1,3 @@ -///////////////////////////////////////////////////////////////////////////// // Name: windows.cpp // Purpose: wxWindow // Author: David Webster @@ -767,6 +766,7 @@ void wxWindowOS2::SetScrollbar( SBCDATA vInfo; ULONG ulStyle = WS_VISIBLE | WS_SYNCPAINT; SWP vSwp; + SWP vSwpOwner; RECTL vRect; HWND hWndParent; HWND hWndClient; @@ -789,6 +789,7 @@ void wxWindowOS2::SetScrollbar( hWndClient = hWndParent; } ::WinQueryWindowPos(hWndClient, &vSwp); + ::WinQueryWindowPos(hWnd, &vSwpOwner); if (nPageSize > 1 && nRange > 0) { @@ -805,6 +806,18 @@ void wxWindowOS2::SetScrollbar( ulStyle |= SBS_HORZ; if (m_hWndScrollBarHorz == 0L) { + // + // Since the scrollbars are usually created before the owner is + // sized either via an OnSize event directly or via sizers or + // layout constraints, we will initially just use the coords of + // the parent window (this is usually a frame client window). But + // the bars themselves, are children of the parent frame (i.e + // siblings of the frame client. The owner, however is the actual + // window being scrolled (or at least the one responsible for + // handling the scroll events). The owner will be resized later, + // as it is usually a child of a top level window, and when that + // is done its scrollbars will be resized and repositioned as well. + // m_hWndScrollBarHorz = ::WinCreateWindow( hWndParent ,WC_SCROLLBAR ,(PSZ)NULL @@ -822,11 +835,22 @@ void wxWindowOS2::SetScrollbar( } else { + // + // The owner (the scrolled window) is a child of the Frame's + // client window, usually. The scrollbars are children of the + // frame, itself, and thus are positioned relative to the frame's + // origin, not the frame's client window origin. + // The starting x position is the same as the starting x position + // of the owner, but in terms of the parent frame. + // The starting y position is 20 pels below the origin of the + // owner in terms of the parent frame. + // The horz bar is the same width as the owner and 20 pels high. + // ::WinSetWindowPos( m_hWndScrollBarHorz ,HWND_TOP - ,vSwp.x - ,vSwp.y - ,vSwp.cx - 20 + ,vSwp.x + vSwpOwner.x + ,(vSwp.y + vSwpOwner.y) - 20 + ,vSwpOwner.cx ,20 ,SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER ); @@ -849,6 +873,18 @@ void wxWindowOS2::SetScrollbar( ulStyle |= SBS_VERT; if (m_hWndScrollBarVert == 0L) { + // + // Since the scrollbars are usually created before the owner is + // sized either via an OnSize event directly or via sizers or + // layout constraints, we will initially just use the coords of + // the parent window (this is usually a frame client window). But + // the bars themselves, are children of the parent frame (i.e + // siblings of the frame client. The owner, however is the actual + // window being scrolled (or at least the one responsible for + // handling the scroll events). The owner will be resized later, + // as it is usually a child of a top level window, and when that + // is done its scrollbars will be resized and repositioned as well. + // m_hWndScrollBarVert = ::WinCreateWindow( hWndParent ,WC_SCROLLBAR ,(PSZ)NULL @@ -866,12 +902,28 @@ void wxWindowOS2::SetScrollbar( } else { + ::WinQueryWindowPos(hWnd, &vSwpOwner); + // + // The owner (the scrolled window) is a child of the Frame's + // client window, usually. The scrollbars are children of the + // frame, itself and thus are positioned relative to the frame's + // origin, not the frame's client window's origin. + // Thus, the x position will be frame client's x (usually a few + // pels inside the parent frame, plus the width of the owner. + // Since we may be using sizers or layout constraints for multiple + // child scrolled windows, the y position will be the frame client's + // y pos plus the scrolled windows y position, yielding the y + // position of the scrollbar relative to the parent frame (the vert + // scrollbar is on the right and starts at the bottom of the + // owner window). + // It is 20 pels wide and the same height as the owner. + // ::WinSetWindowPos( m_hWndScrollBarVert ,HWND_TOP - ,vSwp.x + vSwp.cx - 20 - ,vSwp.y + 20 + ,vSwp.x + vSwpOwner.x + vSwpOwner.cx + ,vSwp.y + vSwpOwner.y ,20 - ,vSwp.cy - 20 + ,vSwpOwner.cy ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW ); ::WinSendMsg( m_hWndScrollBarVert @@ -1523,6 +1575,55 @@ void wxWindowOS2::DoMoveWindow( ,(LONG)nHeight ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW ); + if (m_vWinSwp.cx == 0 && m_vWinSwp.cy == 0 && m_vWinSwp.fl == 0) + // + // Uninitialized + // + ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp); + else + { + int nYDiff = m_vWinSwp.cy - nHeight; + + // + // Handle resizing of scrolled windows. The target or window to + // be scrolled is the owner (gets the scroll notificaitons). The + // parent is usually the parent frame of the scrolled panel window. + // In order to show the scrollbars the target window will be shrunk + // by the size of the scroll bar widths (20) and moved in the X and Y + // directon. That value will be computed as part of the diff for + // moving the children. Everytime the window is sized the + // toplevel OnSize is going to resize the panel to fit the client + // or the whole sizer and will need to me resized. This will send + // a WM_SIZE out which will be intercepted by the ScrollHelper + // which will cause the scrollbars to be displayed via the SetScrollbar + // call in CWindow. + // + if ( pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) || + pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) + ) + { + int nAdjustWidth = 0; + int nAdjustHeight = 0; + SWP vSwpScroll; + + if (GetScrollBarHorz() != NULLHANDLE) + nAdjustHeight = 20L; + if (GetScrollBarVert() != NULLHANDLE) + nAdjustWidth = 20L; + ::WinQueryWindowPos(GetHWND(), &vSwpScroll); + ::WinSetWindowPos( GetHWND() + ,HWND_TOP + ,vSwpScroll.x + ,vSwpScroll.y + nAdjustHeight + ,vSwpScroll.cx - nAdjustWidth + ,vSwpScroll.cy - nAdjustHeight + ,SWP_MOVE | SWP_SIZE + ); + nYDiff += 20; + } + MoveChildren(nYDiff); + ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp); + } } // end of wxWindowOS2::DoMoveWindow // @@ -4018,6 +4119,7 @@ void wxWindowOS2::MoveChildren( ,vSwp.cy ,SWP_MOVE | SWP_ZORDER ); + ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp()); if (pWin->IsKindOf(CLASSINFO(wxRadioBox))) { wxRadioBox* pRadioBox; @@ -4062,6 +4164,8 @@ void wxWindowOS2::MoveChildren( // // 3) The controls are children of a panel, which in turn is a child of // a frame. +// The panel may be one of many, in which case the same treatment +// as 1 applies. It may be the only child, though. // This is the nastiest case. A panel is created as the only child of // the frame and as such, when a frame has only one child, the child is // expanded to fit the entire client area of the frame. Because the @@ -4102,12 +4206,16 @@ int wxWindowOS2::GetOS2ParentHeight( else return(pParent->GetClientSize().y); } - // - // Case 3 -- this is for any window that is the sole child of a Frame. - // The grandparent must exist and it must be of type CFrame - // and it's height must be different. Otherwise the standard - // applies. + // Case 3a -- One of many Frame children. Will be positioned normally + // + else if (pParent->GetChildren().GetCount() > 1) + return(pParent->GetClientSize().y); + // + // Case 3b -- this is for any window that is the sole child of a Frame. + // The grandparent must exist and it must be of type CFrame + // and it's height must be different. Otherwise the standard + // applies. // else { @@ -4142,111 +4250,6 @@ int wxWindowOS2::GetOS2ParentHeight( // OS/2 needs a lot extra manipulation to deal with layouts // for canvas windows, particularly scrolled ones. // -void wxWindowOS2::OS2Layout( - int nWidth -, int nHeight -) -{ - // - // Frames laying out canvas windows need the held. - // Dialogs or Frames laying out child controls do not. - // - if (IsKindOf(CLASSINFO(wxFrame))) - { - RECTL vRectFrame; - RECTL vRectClient; - RECTL vRectChild; - RECTL vRectHorz; - RECTL vRectVert; - SWP vSwpFrame; - SWP vSwpClient; - SWP vSwpChild; - SWP vSwpHorz; - SWP vSwpVert; - wxFrame* pFrame = wxDynamicCast(this, wxFrame); - bool bNewYSize = FALSE; - bool bNewXSize = FALSE; - - ::WinQueryWindowPos(pFrame->GetFrame(), &vSwpFrame); - ::WinQueryWindowPos(GetHwnd(), &vSwpClient); - - if (vSwpClient.cy != pFrame->GetSwpClient()->cy) - bNewYSize = TRUE; - if (vSwpClient.cx != pFrame->GetSwpClient()->cx) - bNewXSize = TRUE; - - for (wxWindowList::Node* pNode = GetChildren().GetFirst(); - pNode; - pNode = pNode->GetNext()) - { - wxWindow* pChild = pNode->GetData(); - int nWidthAdjust = 0; - int nHeightAdjust = 0; - - if ( pChild->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) || - pChild->IsKindOf(CLASSINFO(wxScrolledWindow)) - ) - { - if(bNewYSize) - { - // - // This is needed SetSize will mess up the OS/2 child window - // positioning because we position in wxWindows coordinates, - // not OS/2 coordinates. - // - pChild->MoveChildren(pFrame->GetSwpClient()->cy - vSwpClient.cy); - pChild->Refresh(); - } - ::WinQueryWindowPos(pChild->GetHWND(), &vSwpChild); - - // - // Reset the child window size to account for scrollbars - // - if (pChild->GetScrollBarHorz() != NULLHANDLE) - nHeightAdjust = 20; - if (pChild->GetScrollBarVert() != NULLHANDLE) - nWidthAdjust = 20; - ::WinSetWindowPos( pChild->GetHWND() - ,HWND_TOP - ,vSwpChild.x - ,vSwpChild.y + nHeightAdjust - ,vSwpChild.cx - nWidthAdjust - ,vSwpChild.cy - nHeightAdjust - ,SWP_MOVE | SWP_SIZE - ); - - // - // Reset the scrollbar sizes...they will be all messed up after - // auto layouts - // - if (pChild->GetScrollBarHorz() != NULLHANDLE) - { - ::WinSetWindowPos( pChild->GetScrollBarHorz() - ,HWND_TOP - ,vSwpClient.x + vSwpChild.x - ,vSwpClient.y + vSwpChild.y - ,vSwpChild.cx - 20 - ,20 - ,SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER - ); - } - if (pChild->GetScrollBarVert() != NULLHANDLE) - { - ::WinSetWindowPos( pChild->GetScrollBarVert() - ,HWND_TOP - ,vSwpClient.x + vSwpChild.x + vSwpChild.cx - 20 - ,vSwpClient.y + vSwpChild.y + 20 - ,20 - ,vSwpChild.cy - 20 - ,SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER - ); - } - } - } - ::WinQueryWindowPos(GetHwnd(), pFrame->GetSwpClient()); - } -} // end of wxWindowOS2::OS2Layout - wxWindowCreationHook::wxWindowCreationHook( wxWindow* pWinBeingCreated ) diff --git a/src/os2/wx23.def b/src/os2/wx23.def index dd05b8a7b0..e7c596211e 100644 --- a/src/os2/wx23.def +++ b/src/os2/wx23.def @@ -4,7 +4,7 @@ DATA MULTIPLE NONSHARED READWRITE LOADONCALL CODE LOADONCALL EXPORTS -;From library: H:\Dev\Wx2\WxWindows\lib\wx.lib +;From library: F:\DEV\WX2\WXWINDOWS\LIB\wx.lib ;From object file: dummy.cpp ;PUBDEFs (Symbols available from object file): wxDummyChar @@ -1777,7 +1777,7 @@ EXPORTS wxEVT_NC_LEFT_DCLICK wxEVT_INIT_DIALOG wxEVT_COMMAND_SET_FOCUS - ;From object file: H:\DEV\WX2\WXWINDOWS\src\common\extended.c + ;From object file: F:\DEV\WX2\WXWINDOWS\src\common\extended.c ;PUBDEFs (Symbols available from object file): ConvertToIeeeExtended ConvertFromIeeeExtended @@ -5810,7 +5810,7 @@ EXPORTS Read32__17wxTextInputStreamFv ;wxTextInputStream::SkipIfEndOfLine(char) SkipIfEndOfLine__17wxTextInputStreamFc - ;From object file: H:\DEV\WX2\WXWINDOWS\src\common\unzip.c + ;From object file: F:\DEV\WX2\WXWINDOWS\src\common\unzip.c ;PUBDEFs (Symbols available from object file): unzReadCurrentFile unzGetCurrentFileInfo -- 2.47.2