X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f44fdfb032152a62cc0e3a4c0f09330cfab76710..4f55a07f9f4c6ba6905aaa8e584e6fb14771d278:/src/os2/window.cpp diff --git a/src/os2/window.cpp b/src/os2/window.cpp index 7a31cfbbda..26e94bc0cc 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -37,11 +37,6 @@ #include #endif -#define DEBUG_PRINTF(NAME) { static int raz=0; \ - printf( #NAME " %i\n",raz); fflush(stdout); \ - raz++; \ - } - #if wxUSE_OWNER_DRAWN #include "wx/ownerdrw.h" #endif @@ -158,6 +153,7 @@ BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged) EVT_INIT_DIALOG(wxWindow::OnInitDialog) EVT_IDLE(wxWindow::OnIdle) + EVT_SET_FOCUS(wxWindow::OnSetFocus) END_EVENT_TABLE() // =========================================================================== @@ -249,9 +245,6 @@ bool wxWindow::OS2Command( , WXWORD WXUNUSED(uId) ) { - -DEBUG_PRINTF(wxWindow::OS2Command); - return(FALSE); } @@ -280,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() @@ -301,9 +296,6 @@ void wxWindow::Init() m_lLastMouseY = -1; m_nLastMouseEvent = -1; #endif // wxUSE_MOUSEEVENT_HACK - -DEBUG_PRINTF(wxWindow::Init-End); - } // wxWindow::Init // @@ -311,18 +303,25 @@ DEBUG_PRINTF(wxWindow::Init-End); // wxWindow::~wxWindow() { -DEBUG_PRINTF(wxWindow::~wxWindow-Start); m_isBeingDeleted = TRUE; OS2DetachWindowMenu(); + for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent()) + { + wxFrame* pFrame = wxDynamicCast(pWin, wxFrame); + + if (pFrame) + { + if (pFrame->GetLastFocus() == this) + pFrame->SetLastFocus((wxWindow*)NULL); + } + } if (m_parent) m_parent->RemoveChild(this); DestroyChildren(); if (m_hWnd) { -// UnsubclassWin(); - if(!::WinDestroyWindow(GetHWND())) wxLogLastError(wxT("DestroyWindow")); // @@ -330,7 +329,6 @@ DEBUG_PRINTF(wxWindow::~wxWindow-Start); // wxRemoveHandleAssociation(this); } -DEBUG_PRINTF(wxWindow::~wxWindow-End); } // end of wxWindow::~wxWindow bool wxWindow::Create( @@ -343,6 +341,8 @@ bool wxWindow::Create( ) { HWND hParent = NULLHANDLE; + wxPoint vPos = rPos; // The OS/2 position + ULONG ulCreateFlags = 0L; wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent")); @@ -358,29 +358,69 @@ bool wxWindow::Create( if (pParent) { + int nTempy; + pParent->AddChild(this); hParent = GetWinHwnd(pParent); + // + // OS2 uses normal coordinates, no bassackwards Windows ones + // + if (pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) || + pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) + ) + { + wxWindow* pGrandParent = NULL; + + pGrandParent = pParent->GetParent(); + if (pGrandParent) + nTempy = pGrandParent->GetSize().y - (vPos.y + rSize.y); + else + nTempy = pParent->GetSize().y - (vPos.y + rSize.y); + } + else + nTempy = pParent->GetSize().y - (vPos.y + rSize.y); + vPos.y = nTempy; + if ( pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) || + pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) + ) + ulCreateFlags |= WS_CLIPSIBLINGS; } else - hParent = HWND_DESKTOP; - - ULONG ulCreateFlags = 0L; + { + RECTL vRect; + ::WinQueryWindowRect(HWND_DESKTOP, &vRect); + hParent = HWND_DESKTOP; + vPos.y = vRect.yTop - (vPos.y + rSize.y); + } // // Most wxSTYLES are really PM Class specific styles and will be // set in those class create procs. PM's basic windows styles are // very limited. // + ulCreateFlags |= WS_VISIBLE; + + + if (lStyle & wxCLIP_SIBLINGS) + ulCreateFlags |= WS_CLIPSIBLINGS; + if (lStyle & wxCLIP_CHILDREN ) ulCreateFlags |= WS_CLIPCHILDREN; // - // Empty stuff for now since PM has no custome 3D effects - // Doesn't mean someone cannot make some up though + // // bool bWant3D; - WXDWORD dwExStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &bWant3D); + WXDWORD dwExStyle = Determine3DEffects( WS_EX_CLIENTEDGE + ,&bWant3D + ); + + // + // Add the simple border style as we'll use this to draw borders + // + if (lStyle & wxSIMPLE_BORDER) + dwExStyle |= wxSIMPLE_BORDER; // // Generic OS/2 Windows are created with no owner, no Z Order, no Control data, @@ -390,13 +430,16 @@ bool wxWindow::Create( ,(PSZ)wxCanvasClassName ,rName.c_str() ,ulCreateFlags - ,rPos.x - ,rPos.y + ,vPos.x + ,vPos.y ,WidthDefault(rSize.x) ,HeightDefault(rSize.y) ,NULLHANDLE ,NULLHANDLE ,m_windowId + ,NULL + ,NULL + ,dwExStyle ); return(TRUE); @@ -513,7 +556,6 @@ bool wxWindow::SetFont( const wxFont& rFont ) { -DEBUG_PRINTF(wxWindow::SetFont); if (!wxWindowBase::SetFont(rFont)) { // nothing to do @@ -598,7 +640,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( @@ -607,11 +666,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 @@ -643,7 +702,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( @@ -652,7 +714,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 @@ -660,12 +725,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( @@ -674,7 +737,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( @@ -685,13 +751,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 @@ -702,20 +884,87 @@ 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(); + + if (pChildWin->GetHWND() != NULLHANDLE) + { + ::WinQueryWindowPos(pChildWin->GetHWND(), &vSwp); + ::WinQueryWindowRect(pChildWin->GetHWND(), &vRect); + if (pChildWin->GetHWND() == m_hWndScrollBarVert || + pChildWin->GetHWND() == m_hWndScrollBarHorz) + { + ::WinSetWindowPos( pChildWin->GetHWND() + ,HWND_TOP + ,vSwp.x + nDx + ,vSwp.y + nDy + ,0 + ,0 + ,SWP_MOVE | SWP_SHOW | SWP_ZORDER + ); + } + else + { + ::WinSetWindowPos( pChildWin->GetHWND() + ,HWND_BOTTOM + ,vSwp.x + nDx + ,vSwp.y + nDy + ,0 + ,0 + ,SWP_MOVE | SWP_ZORDER + ); + ::WinInvalidateRect(pChildWin->GetHWND(), &vRect, FALSE); + } + } + pCurrent = pCurrent->GetNext(); + } } // end of wxWindow::ScrollWindow // --------------------------------------------------------------------------- @@ -729,19 +978,12 @@ void wxWindow::SubclassWin( HWND hwnd = (HWND)hWnd; wxASSERT_MSG( !m_fnOldWndProc, wxT("subclassing window twice?") ); - wxCHECK_RET(::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in SubclassWin") ); - -// wxAssociateWinWithHandle(hwnd, this); - m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc); -// ::WinSetWindowULong(hwnd, QWL_USER, (ULONG)wxWndProc); } // end of wxWindow::SubclassWin void wxWindow::UnsubclassWin() { -// wxRemoveHandleAssociation(this); - // // Restore old Window proc // @@ -749,11 +991,10 @@ void wxWindow::UnsubclassWin() if (m_hWnd) { -// m_hWnd = 0; - wxCHECK_RET( ::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in UnsubclassWin") ); PFNWP fnProc = (PFNWP)::WinQueryWindowPtr(hwnd, QWP_PFNWP); + if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc)) { WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc); @@ -771,16 +1012,32 @@ WXDWORD wxWindow::MakeExtendedStyle( ) { // - // PM does not support extended style + // Simply fill out with wxWindow extended styles. We'll conjure + // something up in OS2Create and all window redrawing pieces later // - WXDWORD exStyle = 0; - return exStyle; + WXDWORD dwStyle = 0; + + if (lStyle & wxTRANSPARENT_WINDOW ) + dwStyle |= wxTRANSPARENT_WINDOW; + + if (!bEliminateBorders) + { + if (lStyle & wxSUNKEN_BORDER) + dwStyle |= wxSUNKEN_BORDER; + if (lStyle & wxDOUBLE_BORDER) + dwStyle |= wxDOUBLE_BORDER; + if (lStyle & wxRAISED_BORDER ) + dwStyle |= wxRAISED_BORDER; + if (lStyle & wxSTATIC_BORDER) + dwStyle |= wxSTATIC_BORDER; + } + return dwStyle; } // end of wxWindow::MakeExtendedStyle // -// Determines whether native 3D effects or CTL3D should be used, +// Determines whether simulated 3D effects or CTL3D should be used, // applying a default border style if required, and returning an extended -// style to pass to CreateWindowEx. +// style to pass to OS2Create. // WXDWORD wxWindow::Determine3DEffects( WXDWORD dwDefaultBorderStyle @@ -790,9 +1047,65 @@ WXDWORD wxWindow::Determine3DEffects( WXDWORD dwStyle = 0L; // - // Native PM does not have any specialize 3D effects like WIN32 does + // Native PM does not have any specialize 3D effects like WIN32 does, + // so we have to try and invent them. + // + + // + // If matches certain criteria, then assume no 3D effects + // unless specifically requested (dealt with in MakeExtendedStyle) // - *pbWant3D = FALSE; + if (!GetParent() || + !IsKindOf(CLASSINFO(wxControl)) || + (m_windowStyle & wxNO_BORDER) + ) + { + *pbWant3D = FALSE; + return MakeExtendedStyle(m_windowStyle, FALSE); + } + + // + // 1) App can specify global 3D effects + // + *pbWant3D = wxTheApp->GetAuto3D(); + + // + // 2) If the parent is being drawn with user colours, or simple border + // specified, switch effects off. + // + if (GetParent() && + (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || + (m_windowStyle & wxSIMPLE_BORDER) + ) + *pbWant3D = FALSE; + + // + // 3) Control can override this global setting by defining + // a border style, e.g. wxSUNKEN_BORDER + // + if ((m_windowStyle & wxDOUBLE_BORDER) || + (m_windowStyle & wxRAISED_BORDER) || + (m_windowStyle & wxSTATIC_BORDER) || + (m_windowStyle & wxSUNKEN_BORDER) + ) + *pbWant3D = TRUE; + + dwStyle = MakeExtendedStyle( m_windowStyle + ,FALSE + ); + + // + // If we want 3D, but haven't specified a border here, + // apply the default border style specified. + // + if (dwDefaultBorderStyle && (*pbWant3D) && + !((m_windowStyle & wxDOUBLE_BORDER) || + (m_windowStyle & wxRAISED_BORDER) || + (m_windowStyle & wxSTATIC_BORDER) || + (m_windowStyle & wxSIMPLE_BORDER) + ) + ) + dwStyle |= dwDefaultBorderStyle; return dwStyle; } // end of wxWindow::Determine3DEffects @@ -1113,8 +1426,14 @@ void wxWindow::DoGetClientSize( HWND hWndClient; RECTL vRect; - hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT); - ::WinQueryWindowRect(hWndClient, &vRect); + if (IsKindOf(CLASSINFO(wxFrame))) + hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT); + else + hWndClient = NULLHANDLE; + if( hWndClient == NULLHANDLE) + ::WinQueryWindowRect(GetHwnd(), &vRect); + else + ::WinQueryWindowRect(hWndClient, &vRect); if (pWidth) *pWidth = vRect.xRight; @@ -1129,6 +1448,17 @@ void wxWindow::DoMoveWindow( , int nHeight ) { + RECTL vRect; + HWND hParent; + wxWindow* pParent = GetParent(); + + if (pParent) + hParent = GetWinHwnd(pParent); + else + hParent = HWND_DESKTOP; + ::WinQueryWindowRect(hParent, &vRect); + nY = vRect.yTop - (nY + nHeight); + if ( !::WinSetWindowPos( GetHwnd() ,HWND_TOP ,(LONG)nX @@ -1338,10 +1668,12 @@ int wxWindow::GetCharHeight() const hPs = ::WinGetPS(GetHwnd()); if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics)) + { + ::WinReleasePS(hPs); return (0); - else - return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender); + } ::WinReleasePS(hPs); + return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender); } // end of wxWindow::GetCharHeight int wxWindow::GetCharWidth() const @@ -1352,10 +1684,12 @@ int wxWindow::GetCharWidth() const hPs = ::WinGetPS(GetHwnd()); if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics)) + { + ::WinReleasePS(hPs); return (0); - else - return(vFontMetrics.lAveCharWidth); + } ::WinReleasePS(hPs); + return(vFontMetrics.lAveCharWidth); } // end of wxWindow::GetCharWidth void wxWindow::GetTextExtent( @@ -1476,6 +1810,26 @@ void wxWindow::GetCaretPos( // popup menu // --------------------------------------------------------------------------- +static void wxYieldForCommandsOnly() +{ + // + // Peek all WM_COMMANDs (it will always return WM_QUIT too but we don't + // want to process it here) + // + QMSG vMsg; + + while (::WinPeekMsg( vHabmain + ,&vMsg + ,(HWND)0 + ,WM_COMMAND + ,WM_COMMAND + ,PM_REMOVE + ) && vMsg.msg != WM_QUIT) + { + wxTheApp->DoMessage((WXMSG*)&vMsg); + } +} + bool wxWindow::DoPopupMenu( wxMenu* pMenu , int nX @@ -1502,7 +1856,14 @@ bool wxWindow::DoPopupMenu( ,0L ,PU_MOUSEBUTTON2DOWN | PU_MOUSEBUTTON2 | PU_KEYBOARD ); - wxYield(); + // we need to do it righ now as otherwise the events are never going to be + // sent to wxCurrentPopupMenu from HandleCommand() + // + // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't + // help and we'd still need wxYieldForCommandsOnly() as the menu may be + // destroyed as soon as we return (it can be a local variable in the caller + // for example) and so we do need to process the event immediately + wxYieldForCommandsOnly(); wxCurrentPopupMenu = NULL; pMenu->SetInvokingWindow(NULL); @@ -1519,8 +1880,6 @@ MRESULT wxWindow::OS2DefWindowProc( , WXLPARAM lParam ) { -DEBUG_PRINTF(wxWindow::OS2DefWindowProc); - if (m_fnOldWndProc) return (MRESULT)m_fnOldWndProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam); else @@ -1533,8 +1892,6 @@ bool wxWindow::OS2ProcessMessage( { QMSG* pQMsg = (QMSG*)pMsg; -DEBUG_PRINTF(OS2ProcessMessage); - if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL)) { // @@ -1740,11 +2097,6 @@ void wxWindow::UnpackCommand( , WORD* pCmd ) { -/* - *pId = LOWORD(wParam); - *phWnd = (WXHWND)lParam; - *pCmd = HIWORD(wParam); -*/ *pId = LOWORD(wParam); *phWnd = NULL; // or may be GetHWND() ? *pCmd = LOWORD(lParam); @@ -1769,9 +2121,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( @@ -1811,7 +2172,6 @@ MRESULT EXPENTRY wxWndProc( // Trace all ulMsgs - useful for the debugging // #ifdef __WXDEBUG__ -DEBUG_PRINTF(__WXDEBUG__wxWndProc); wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"), wxGetMessageName(ulMsg), wParam, lParam); #endif // __WXDEBUG__ @@ -1872,17 +2232,6 @@ MRESULT wxWindow::OS2WindowProc( WXHICON hIcon; WXHBRUSH hBrush; - // - // The return value - // -// union -// { -// bool bAllow; -// MRESULT mResult; -// WXHICON hIcon; -// WXHBRUSH hBrush; -// } vRc; - // // For most messages we should return 0 when we do process the message // @@ -1951,7 +2300,6 @@ MRESULT wxWindow::OS2WindowProc( break; case WM_PAINT: -DEBUG_PRINTF(WM_PAINT) bProcessed = HandlePaint(); break; @@ -1962,11 +2310,9 @@ DEBUG_PRINTF(WM_PAINT) // bProcessed = TRUE; mResult = (MRESULT)TRUE; -DEBUG_PRINTF(WM_CLOSE) break; case WM_SHOW: -DEBUG_PRINTF(WM_SHOW) bProcessed = HandleShow(wParam != 0, (int)lParam); break; @@ -2005,11 +2351,9 @@ DEBUG_PRINTF(WM_SHOW) { WORD id, cmd; WXHWND hwnd; -DEBUG_PRINTF(WM_COMMAND-in) UnpackCommand(wParam, lParam, &id, &hwnd, &cmd); bProcessed = HandleCommand(id, cmd, hwnd); -DEBUG_PRINTF(WM_COMMAND-out) } break; @@ -2019,15 +2363,16 @@ DEBUG_PRINTF(WM_COMMAND-out) 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); } @@ -2142,6 +2487,15 @@ DEBUG_PRINTF(WM_COMMAND-out) } break; #endif + case WM_ERASEBACKGROUND: + // + // Returning TRUE to requestw PM to paint the window background + // in SYSCLR_WINDOW. We don't really want that + // + bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam); + mResult = (MRESULT)(FALSE); + break; + // // Instead of CTLCOLOR messages PM sends QUERYWINDOWPARAMS to // things such as colors and fonts and such @@ -2169,17 +2523,6 @@ DEBUG_PRINTF(WM_COMMAND-out) bProcessed = HandlePresParamChanged(wParam); break; - // move this to wxFrame - case WM_ERASEBACKGROUND: - bProcessed = HandleEraseBkgnd((WXHDC)(HDC)wParam); - if (bProcessed) - { - // - // We processed the message, i.e. erased the background - // - mResult = (MRESULT)TRUE; - } - break; // move all drag and drops to wxDrg case WM_ENDDRAG: @@ -2224,14 +2567,16 @@ DEBUG_PRINTF(WM_COMMAND-out) } break; } - if (!bProcessed) { #ifdef __WXDEBUG__ wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."), wxGetMessageName(uMsg)); #endif // __WXDEBUG__ - mResult = OS2DefWindowProc(uMsg, wParam, lParam); + if (IsKindOf(CLASSINFO(wxFrame))) + mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam); + else + mResult = OS2DefWindowProc(uMsg, wParam, lParam); } return mResult; } // end of wxWindow::OS2WindowProc @@ -2366,6 +2711,7 @@ bool wxWindow::OS2Create( , unsigned long ulId , void* pCtlData , void* pPresParams +, WXDWORD dwExStyle ) { ERRORID vError; @@ -2375,6 +2721,8 @@ bool wxWindow::OS2Create( long lWidth1 = 20L; long lHeight1 = 20L; int nControlId = 0; + int nNeedsubclass = 0; + PCSZ pszClass = zClass; // // Find parent's size, if it exists, to set up a possible default @@ -2383,10 +2731,8 @@ bool wxWindow::OS2Create( RECTL vParentRect; HWND hWndClient; - if (lX > -1L) - lX1 = lX; - if (lY > -1L) - lY1 = lY; + lX1 = lX; + lY1 = lY; if (lWidth > -1L) lWidth1 = lWidth; if (lHeight > -1L) @@ -2414,6 +2760,21 @@ bool wxWindow::OS2Create( { nControlId = ulId; } + else + { + // no standard controls + if(wxString (wxT("wxFrameClass")) == wxString(zClass) ) + { + pszClass = WC_FRAME; + nNeedsubclass = 1; + } + else + { + nControlId = ulId; + if(nControlId < 0) + nControlId = FID_CLIENT; + } + } // // We will either have a registered class via string name or a standard PM Class via a long @@ -2426,9 +2787,9 @@ bool wxWindow::OS2Create( ,(LONG)lY1 ,(LONG)lWidth ,(LONG)lHeight - ,NULLHANDLE + ,hOwner ,HWND_TOP - ,(ULONG)ulId + ,(ULONG)nControlId ,pCtlData ,pPresParams ); @@ -2439,6 +2800,7 @@ bool wxWindow::OS2Create( wxLogError("Can't create window of class %s!. Error: %s\n", zClass, sError); return FALSE; } + m_dwExStyle = dwExStyle; ::WinSetWindowULong(m_hWnd, QWL_USER, (ULONG) this); wxWndHook = NULL; @@ -2462,9 +2824,14 @@ bool wxWindow::OS2Create( // // Now need to subclass window. // - - SubclassWin(GetHWND()); - + if(!nNeedsubclass) + { + wxAssociateWinWithHandle((HWND)m_hWnd,this); + } + else + { + SubclassWin(GetHWND()); + } return TRUE; } // end of wxWindow::OS2Create @@ -2668,78 +3035,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))) - { - return ((wxControl *)pItem)->OS2OnDraw(pItemStruct); - } - else if (pItem && pItem->IsKindOf(CLASSINFO(wxMenu))) + if (vId == 0) { - /* - // 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 ); + - wxCHECK(pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE); + int eAction = 0; + int eStatus = 0; + 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; } @@ -2856,47 +3339,89 @@ bool wxWindow::HandlePaint() wxLogLastError("CreateRectRgn"); return FALSE; } - // - // Debug code - // -#ifdef __WXDEBUG__ - { - HWND hWnd; - HWND hWnd0 = NULLHANDLE; - - hWnd = GetHwnd(); - if(hWnd != hWnd0) - printf("HandlePaint hWnd=%x ",hWnd); - } -#endif m_updateRegion = wxRegion(hRgn); vEvent.SetEventObject(this); + if (!GetEventHandler()->ProcessEvent(vEvent)) + { + HPS hPS; + + hPS = ::WinBeginPaint( GetHwnd() + ,NULLHANDLE + ,&vRect + ); + if(hPS) + { + ::GpiCreateLogColorTable( hPS + ,0L + ,LCOLF_CONSECRGB + ,0L + ,(LONG)wxTheColourDatabase->m_nSize + ,(PLONG)wxTheColourDatabase->m_palTable + ); + ::GpiCreateLogColorTable( hPS + ,0L + ,LCOLF_RGB + ,0L + ,0L + ,NULL + ); + + ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel()); + + if (m_dwExStyle) + { + LINEBUNDLE vLineBundle; + + vLineBundle.lColor = 0x00000000; // Black + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 1; + vLineBundle.lGeomWidth = 1; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + ::WinQueryWindowRect(GetHwnd(), &vRect); + wxDrawBorder( hPS + ,vRect + ,m_dwExStyle + ); + } + ::WinEndPaint(hPS); + } + } return (GetEventHandler()->ProcessEvent(vEvent)); } // end of wxWindow::HandlePaint -bool wxWindow::HandleEraseBkgnd(WXHDC hdc) +bool wxWindow::HandleEraseBkgnd( + WXHDC hDC +) { - // TODO: will have to worry about this later as part of - // the handling of changed presentation parameters - /* - if ( ::IsIconic(GetHwnd()) ) + SWP vSwp; + + ::WinQueryWindowPos(GetHwnd(), &vSwp); + if (vSwp.fl & SWP_MINIMIZE) return TRUE; - wxDC dc; + wxDC vDC; - dc.SetHDC(hdc); - dc.SetWindow(this); - dc.BeginDrawing(); + vDC.m_hPS = (HPS)hDC; // this is really a PS + vDC.SetWindow(this); + vDC.BeginDrawing(); - wxEraseEvent event(m_windowId, &dc); - event.SetEventObject(this); - bool rc = GetEventHandler()->ProcessEvent(event); + wxEraseEvent vEvent(m_windowId, &vDC); + + vEvent.SetEventObject(this); - dc.EndDrawing(); - dc.SelectOldObjects(hdc); - dc.SetHDC((WXHDC) NULL); - */ + bool rc = GetEventHandler()->ProcessEvent(vEvent); + + vDC.EndDrawing(); + vDC.m_hPS = NULLHANDLE; return TRUE; } // end of wxWindow::HandleEraseBkgnd @@ -2904,7 +3429,11 @@ void wxWindow::OnEraseBackground( wxEraseEvent& rEvent ) { - // TODO: + RECTL vRect; + HPS hPS = rEvent.m_dc->m_hPS; + + ::WinQueryWindowRect(GetHwnd(), &vRect); + ::WinFillRect(hPS, &vRect, m_backgroundColour.GetPixel()); } // end of wxWindow::OnEraseBackground // ---------------------------------------------------------------------------