X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fb83aca503d1d34532288b73fe85b9857a677e88..72c71d39724af116d419295b684dd2946efb3da3:/src/os2/window.cpp diff --git a/src/os2/window.cpp b/src/os2/window.cpp index eda3bf9747..d032c864b7 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -273,8 +273,10 @@ void wxWindow::Init() // // wxWnd // - m_hMenu = 0; - m_hWnd = 0; + m_hMenu = 0L; + m_hWnd = 0L; + m_hWndScrollBarHorz = 0L; + m_hWndScrollBarVert = 0L; // // Pass WM_GETDLGCODE to DefWindowProc() @@ -329,6 +331,7 @@ bool wxWindow::Create( ) { HWND hParent = NULLHANDLE; + wxPoint vPos = rPos; // The OS/2 position wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent")); @@ -344,11 +347,32 @@ bool wxWindow::Create( if (pParent) { + int nTempy; + pParent->AddChild(this); hParent = GetWinHwnd(pParent); + // + // OS2 uses normal coordinates, no bassackwards Windows ones + // + nTempy = pParent->GetSize().y - (vPos.y + rSize.y); +#if 0 + if (nTempy < 0) + { + nTempy = pParent->GetSize().y + (vPos.y + rSize.y); + pParent->SetSize(0, 0, pParent->GetSize().x, nTempy); + nTempy = pParent->GetSize().y - (vPos.y + rSize.y); + } +#endif + vPos.y = nTempy; } else - hParent = HWND_DESKTOP; + { + RECTL vRect; + + ::WinQueryWindowRect(HWND_DESKTOP, &vRect); + hParent = HWND_DESKTOP; + vPos.y = vRect.yTop - (vPos.y + rSize.y); + } ULONG ulCreateFlags = 0L; @@ -382,8 +406,8 @@ bool wxWindow::Create( ,(PSZ)wxCanvasClassName ,rName.c_str() ,ulCreateFlags - ,rPos.x - ,rPos.y + ,vPos.x + ,vPos.y ,WidthDefault(rSize.x) ,HeightDefault(rSize.y) ,NULLHANDLE @@ -589,7 +613,24 @@ void wxWindow::SetScrollRange( , bool bRefresh ) { - ::WinSendMsg(GetHwnd(), SBM_SETSCROLLBAR, (MPARAM)0, MPFROM2SHORT(0, nRange)); + int nRange1 = nRange; + int nPageSize = GetScrollPage(nOrient); + + if (nPpageSize > 1 && nRange > 0) + { + nRange1 += (nPageSize - 1); + } + + if (nOrient == wxHORIZONTAL) + { + ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETSCROLLBAR, (MPARAM)0, MPFROM2SHORT(0, (SHORT)nRange1)); + ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0); + } + else + { + ::WinSendMsg(m_hWndScrollBarVert, SBM_SETSCROLLBAR, (MPARAM)0, MPFROM2SHORT(0, (SHORT)nRange1)); + ::WinSendMsg(m_hWndScrollBarVert, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0); + } } // end of wxWindow::SetScrollRange void wxWindow::SetScrollPage( @@ -598,11 +639,11 @@ void wxWindow::SetScrollPage( , bool bRefresh ) { - if ( orient == wxHORIZONTAL ) - m_xThumbSize = page; + if (nOrient == wxHORIZONTAL ) + m_nXThumbSize = nPage; else - m_yThumbSize = page; -} + m_nYThumbSize = nPage; +} // end of wxWindow::SetScrollPage int wxWindow::OldGetScrollRange( int nOrient @@ -634,7 +675,10 @@ int wxWindow::GetScrollPos( int nOrient ) const { - return((int)::WinSendMsg(GetHwnd(), SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL)); + if (nOrient == wxHORIZONTAL) + return((int)::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL)); + else + return((int)::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL)); } // end of wxWindow::GetScrollPos int wxWindow::GetScrollRange( @@ -643,7 +687,10 @@ int wxWindow::GetScrollRange( { MRESULT mr; - mr = ::WinSendMsg(GetHwnd(), SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL); + if (nOrient == wxHORIZONTAL) + mr = ::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL); + else + mr = ::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL); return((int)SHORT2FROMMR(mr)); } // end of wxWindow::GetScrollRange @@ -651,12 +698,10 @@ int wxWindow::GetScrollThumb( int nOrient ) const { - WNDPARAMS vWndParams; - PSBCDATA pSbcd; - - ::WinSendMsg(GetHwnd(), WM_QUERYWINDOWPARAMS, (MPARAM)&vWndParams, (MPARAM)NULL); - pSbcd = (PSBCDATA)vWndParams.pCtlData; - return((int)pSbcd->posThumb); + if (nOrient == wxHORIZONTAL ) + return m_nXThumbSize; + else + return m_nYThumbSize; } // end of wxWindow::GetScrollThumb void wxWindow::SetScrollPos( @@ -665,7 +710,10 @@ void wxWindow::SetScrollPos( , bool bRefresh ) { - ::WinSendMsg(GetHwnd(), SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL); + if (nOrient == wxHORIZONTAL ) + ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL); + else + ::WinSendMsg(m_hWndScrollBarVert, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL); } // end of wxWindow::SetScrollPos( void wxWindow::SetScrollbar( @@ -676,13 +724,129 @@ void wxWindow::SetScrollbar( , bool bRefresh ) { - ::WinSendMsg(GetHwnd(), SBM_SETSCROLLBAR, (MPARAM)nPos, MPFROM2SHORT(0, nRange)); - if (nOrient == wxHORIZONTAL) + int nOldRange = nRange - nThumbVisible; + int nRange1 = nOldRange; + int nPageSize = nThumbVisible; + SBCDATA vInfo; + HWND hWnd = GetHwnd(); + ULONG ulStyle = WS_VISIBLE | WS_SYNCPAINT; + RECTL vRect; + + ::WinQueryWindowRect(hWnd, &vRect); + if (nPageSize > 1 && nRange > 0) + { + nRange1 += (nPageSize - 1); + } + + vInfo.cb = sizeof(SBCDATA); + vInfo.posFirst = 0; + vInfo.posLast = (SHORT)nRange1; + vInfo.posThumb = nPos; + + if (nOrient == wxHORIZONTAL ) { - m_nXThumbSize = nThumbVisible; + ulStyle |= SBS_HORZ; + if (m_hWndScrollBarHorz == 0L) + { + // + // We create the scrollbars with the desktop so that they are not + // registered as child windows of the window in order that child + // windows may be scrolled without scrolling the scrollbars themselves! + // + m_hWndScrollBarHorz = ::WinCreateWindow( hWnd + ,WC_SCROLLBAR + ,(PSZ)NULL + ,ulStyle + ,vRect.xLeft + ,vRect.yBottom + ,vRect.xRight - vRect.xLeft + ,20 + ,hWnd + ,HWND_TOP + ,FID_HORZSCROLL + ,&vInfo + ,NULL + ); + } + else + { + RECTL vRect2; + + // + // Only want to resize the scrollbar if it changes, otherwise + // we'd probably end up in a recursive loop until we crash the call stack + // because this method is called in a ScrolledWindow OnSize event and SWP_MOVE | SWP_SIZE + // generates those events. + // + ::WinQueryWindowRect(m_hWndScrollBarHorz, &vRect2); + if (!(vRect2.xLeft == vRect.xLeft && + vRect2.xRight == vRect.xRight && + vRect2.yBottom == vRect.yBottom && + vRect2.yTop == vRect.yTop + ) ) + { + ::WinSetWindowPos( m_hWndScrollBarHorz + ,HWND_TOP + ,vRect.xLeft + ,vRect.yBottom + ,vRect.xRight - vRect.xLeft + ,20 + ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW + ); + } + ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETSCROLLBAR, (MPARAM)nPos, MPFROM2SHORT(0, (SHORT)nRange1)); + ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0); + } } else { + ulStyle |= SBS_VERT; + if (m_hWndScrollBarVert == 0L) + { + m_hWndScrollBarVert = ::WinCreateWindow( hWnd + ,WC_SCROLLBAR + ,(PSZ)NULL + ,ulStyle + ,vRect.xRight - 20 + ,vRect.yBottom + 20 + ,20 + ,vRect.yTop - (vRect.yBottom + 20) + ,hWnd + ,HWND_TOP + ,FID_VERTSCROLL + ,&vInfo + ,NULL + ); + } + else + { + RECTL vRect2; + + // + // Only want to resize the scrollbar if it changes, otherwise + // we'd probably end up in a recursive loop until we crash the call stack + // because this method is called in a ScrolledWindow OnSize event and SWP_MOVE | SWP_SIZE + // generates those events. + // + ::WinQueryWindowRect(m_hWndScrollBarVert, &vRect2); + if (!(vRect2.xLeft == vRect.xLeft && + vRect2.xRight == vRect.xRight && + vRect2.yBottom == vRect.yBottom && + vRect2.yTop == vRect.yTop + ) ) + { + ::WinSetWindowPos( m_hWndScrollBarVert + ,HWND_TOP + ,vRect.xRight - 20 + ,vRect.yBottom + 20 + ,20 + ,vRect.yTop - (vRect.yBottom + 20) + ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW + ); + } + ::WinSendMsg(m_hWndScrollBarVert, SBM_SETSCROLLBAR, (MPARAM)nPos, MPFROM2SHORT(0, (SHORT)nRange1)); + ::WinSendMsg(m_hWndScrollBarVert, SBM_SETTHUMBSIZE, MPFROM2SHORT((SHORT)nThumbVisible, (SHORT)nRange1), (MPARAM)0); + } m_nYThumbSize = nThumbVisible; } } // end of wxWindow::SetScrollbar @@ -693,20 +857,67 @@ void wxWindow::ScrollWindow( , const wxRect* pRect ) { + RECTL vRect; RECTL vRect2; + nDy *= -1; // flip the sign of Dy as OS/2 is opposite wxWin. if (pRect) { vRect2.xLeft = pRect->x; - vRect2.yTop = pRect->y; + vRect2.yTop = pRect->y + pRect->height; vRect2.xRight = pRect->x + pRect->width; - vRect2.yBottom = pRect->y + pRect->height; + vRect2.yBottom = pRect->y; } + else + { + ::WinQueryWindowRect(GetHwnd(), &vRect2); + ::WinQueryWindowRect(m_hWndScrollBarHorz, &vRect); + vRect2.yBottom += vRect.yTop - vRect.yBottom; + ::WinQueryWindowRect(m_hWndScrollBarVert, &vRect); + vRect2.xRight -= vRect.xRight - vRect.xLeft; + } if (pRect) - ::WinScrollWindow(GetHwnd(), (LONG)nDx, (LONG)nDy, &vRect2, NULL, NULLHANDLE, NULL, 0L); + ::WinScrollWindow( GetHwnd() + ,(LONG)nDx + ,(LONG)nDy + ,&vRect2 + ,NULL + ,NULLHANDLE + ,NULL + ,SW_INVALIDATERGN + ); else - ::WinScrollWindow(GetHwnd(), nDx, nDy, NULL, NULL, NULLHANDLE, NULL, 0L); + ::WinScrollWindow( GetHwnd() + ,nDx + ,nDy + ,NULL + ,NULL + ,NULLHANDLE + ,NULL + ,SW_INVALIDATERGN + ); + + // + // Move the children + wxWindowList::Node* pCurrent = GetChildren().GetFirst(); + SWP vSwp; + + while (pCurrent) + { + wxWindow* pChildWin = pCurrent->GetData(); + + ::WinQueryWindowPos(pChildWin->GetHWND(), &vSwp); + ::WinSetWindowPos( pChildWin->GetHWND() + ,HWND_TOP + ,vSwp.x + nDx + ,vSwp.y + nDy + ,0 + ,0 + , SWP_MOVE | SWP_SHOW + ); + pCurrent = pCurrent->GetNext(); + } } // end of wxWindow::ScrollWindow // --------------------------------------------------------------------------- @@ -1096,7 +1307,10 @@ void wxWindow::DoGetClientSize( HWND hWndClient; RECTL vRect; - hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT); + if (IsKindOf(CLASSINFO(wxFrame))) + hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT); + else + hWndClient = NULLHANDLE; if( hWndClient == NULLHANDLE) ::WinQueryWindowRect(GetHwnd(), &vRect); else @@ -1750,9 +1964,18 @@ void wxWindow::UnpackScroll( , WXHWND* phWnd ) { - *pCode = LOWORD(wParam); - *pPos = HIWORD(wParam); - *phWnd = (WXHWND)lParam; + ULONG ulId; + HWND hWnd; + + ulId = (ULONG)LONGFROMMP(wParam); + hWnd = ::WinWindowFromID(GetHwnd(), ulId); + if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert) + *phWnd = NULLHANDLE; + else + *phWnd = hWnd; + + *pPos = SHORT1FROMMP(lParam); + *pCode = SHORT2FROMMP(lParam); } // end of wxWindow::UnpackScroll void wxWindow::UnpackMenuSelect( @@ -1983,15 +2206,16 @@ MRESULT wxWindow::OS2WindowProc( case WM_DRAWITEM: case WM_MEASUREITEM: { - int idCtrl = (UINT)wParam; + int nIdCtrl = (UINT)wParam; + if ( uMsg == WM_DRAWITEM ) { - bProcessed = OS2OnDrawItem(idCtrl, + bProcessed = OS2OnDrawItem(nIdCtrl, (WXDRAWITEMSTRUCT *)lParam); } else { - bProcessed = OS2OnMeasureItem(idCtrl, + bProcessed = OS2OnMeasureItem(nIdCtrl, (WXMEASUREITEMSTRUCT *)lParam); } @@ -2654,78 +2878,194 @@ bool wxWindow::OS2OnDrawItem( , WXDRAWITEMSTRUCT* pItemStruct ) { - // - // I'll get to owner drawn stuff later - // + wxDC vDc; +#if wxUSE_OWNER_DRAWN // - // is it a menu item or control? + // Is it a menu item? // - wxWindow* pItem = FindItem(vId); - -#if wxUSE_OWNER_DRAWN - if (pItem && pItem->IsKindOf(CLASSINFO(wxControl))) + if (vId == 0) { - return ((wxControl *)pItem)->OS2OnDraw(pItemStruct); - } - else if (pItem && pItem->IsKindOf(CLASSINFO(wxMenu))) - { - /* - // TODO: draw a menu item + ERRORID vError; + wxString sError; + POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct; + wxFrame* pFrame = (wxFrame*)this; + wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem); + HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps); + wxRect vRect( pMeasureStruct->rclItem.xLeft + ,pMeasureStruct->rclItem.yBottom + ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft + ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom + ); + vDc.SetHDC( hDC + ,FALSE + ); + vDc.SetHPS(pMeasureStruct->hps); + // + // Load the wxWindows Pallete and set to RGB mode // - POWNERITEM pDrawStruct = (OWNERITEM *)pItemStruct; - wxMenuItem* pMenuItem = (wxMenuItem *)(pDrawStruct->pItemData); + if (!::GpiCreateLogColorTable( pMeasureStruct->hps + ,0L + ,LCOLF_CONSECRGB + ,0L + ,(LONG)wxTheColourDatabase->m_nSize + ,(PLONG)wxTheColourDatabase->m_palTable + )) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + wxLogError("Unable to set current color table. Error: %s\n", sError); + } + // + // Set the color table to RGB mode + // + if (!::GpiCreateLogColorTable( pMeasureStruct->hps + ,0L + ,LCOLF_RGB + ,0L + ,0L + ,NULL + )) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + wxLogError("Unable to set current color table. Error: %s\n", sError); + } + + wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); + + + int eAction = 0; + int eStatus = 0; - wxCHECK(pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE); + if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld) + { + // + // Entire Item needs to be redrawn (either it has reappeared from + // behind another window or is being displayed for the first time + // + eAction = wxOwnerDrawn::wxODDrawAll; + if (pMeasureStruct->fsAttribute & MIA_HILITED) + { + // + // If it is currently selected we let the system handle it + // + eStatus |= wxOwnerDrawn::wxODSelected; + } + if (pMeasureStruct->fsAttribute & MIA_CHECKED) + { + // + // If it is currently checked we draw our own + // + eStatus |= wxOwnerDrawn::wxODChecked; + pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED; + } + if (pMeasureStruct->fsAttribute & MIA_DISABLED) + { + // + // If it is currently disabled we let the system handle it + // + eStatus |= wxOwnerDrawn::wxODDisabled; + } + // + // Don't really care about framed (indicationg focus) or NoDismiss + // + } + else + { + if (pMeasureStruct->fsAttribute & MIA_HILITED) + { + eAction = wxOwnerDrawn::wxODDrawAll; + eStatus |= wxOwnerDrawn::wxODSelected; + // + // Keep the system from trying to highlight with its bogus colors + // + pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED; + } + else if (!(pMeasureStruct->fsAttribute & MIA_HILITED)) + { + eAction = wxOwnerDrawn::wxODDrawAll; + eStatus = 0; + // + // Keep the system from trying to highlight with its bogus colors + // + pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED; + } + else + { + // + // For now we don't care about anything else + // just ignore the entire message! + // + return TRUE; + } + } // - // Prepare to call OnDrawItem() + // Now redraw the item + // + return(pMenuItem->OnDrawItem( vDc + ,vRect + ,(wxOwnerDrawn::wxODAction)eAction + ,(wxOwnerDrawn::wxODStatus)eStatus + )); + // + // leave the fsAttribute and fsOldAttribute unchanged. If different, + // the system will do the highlight or fraeming or disabling for us, + // otherwise, we'd have to do it ourselves. // - HPSdc; - dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE); - wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top, - pDrawStruct->rcItem.right - pDrawStruct->rcItem.left, - pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top); - - return pMenuItem->OnDrawItem - ( - dc, rect, - (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction, - (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState - ); - */ } - else - return FALSE; + wxWindow* pItem = FindItem(vId); + + if (pItem && pItem->IsKindOf(CLASSINFO(wxControl))) + { + return ((wxControl *)pItem)->OS2OnDraw(pItemStruct); + } #endif - return TRUE; + return FALSE; } // end of wxWindow::OS2OnDrawItem -bool wxWindow::OS2OnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) +bool wxWindow::OS2OnMeasureItem( + int lId +, WXMEASUREITEMSTRUCT* pItemStruct +) { - // TODO: more owner drawn menu related stuff, get to it later -/* -#if wxUSE_OWNER_DRAWN - // is it a menu item? - if ( id == 0 ) + // + // Is it a menu item? + // + if (lId == 65536) // I really don't like this...has to be a better indicator { - MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct; - wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData); - - wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); - - return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth, - &pMeasureStruct->itemHeight); + if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu + { + size_t nWidth; + size_t nHeight; + POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct; + wxFrame* pFrame = (wxFrame*)this; + wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem); + + wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); + nWidth = 0L; + nHeight = 0L; + if (pMenuItem->OnMeasureItem( &nWidth + ,&nHeight + )) + { + pMeasureStruct->rclItem.xRight = nWidth; + pMeasureStruct->rclItem.xLeft = 0L; + pMeasureStruct->rclItem.yTop = nHeight; + pMeasureStruct->rclItem.yBottom = 0L; + return TRUE; + } + return FALSE; + } } + wxWindow* pItem = FindItem(lId); - wxWindow *item = FindItem(id); - if ( item && item->IsKindOf(CLASSINFO(wxControl)) ) + if (pItem && pItem->IsKindOf(CLASSINFO(wxControl))) { - return ((wxControl *)item)->MSWOnMeasure(itemStruct); + return ((wxControl *)pItem)->OS2OnMeasure(pItemStruct); } -#endif // owner-drawn menus -*/ return FALSE; }