X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f23208caccf81b0b34c5c11b466c6bd64fdf0f9d..72c71d39724af116d419295b684dd2946efb3da3:/src/os2/window.cpp diff --git a/src/os2/window.cpp b/src/os2/window.cpp index 01de71dd15..d032c864b7 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -99,8 +99,8 @@ QMSG s_currentMsg; wxMenu* wxCurrentPopupMenu = NULL; extern wxList WXDLLEXPORT wxPendingDelete; -#if defined(__VISAGECPP__) && (__IBMCPP__ < 400) -extern wxChar* wxCanvasClassName; +#if !defined(__VISAGECPP__) || (__IBMCPP__ < 400) +extern wxChar wxCanvasClassName[]; #endif wxList* wxWinHandleList = NULL; @@ -153,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() // =========================================================================== @@ -272,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() @@ -306,6 +309,7 @@ wxWindow::~wxWindow() if (m_parent) m_parent->RemoveChild(this); DestroyChildren(); + if (m_hWnd) { if(!::WinDestroyWindow(GetHWND())) @@ -327,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")); @@ -342,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; @@ -356,6 +382,12 @@ bool wxWindow::Create( // 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; @@ -374,14 +406,15 @@ 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 ); + return(TRUE); } // end of wxWindow::Create @@ -580,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( @@ -589,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 @@ -625,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( @@ -634,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 @@ -642,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( @@ -656,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( @@ -667,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 @@ -684,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 // --------------------------------------------------------------------------- @@ -711,31 +931,23 @@ 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, QWS_USER, (ULONG)wxWndProc); } // end of wxWindow::SubclassWin void wxWindow::UnsubclassWin() { - wxRemoveHandleAssociation(this); - // // Restore old Window proc // - HWND hwnd = GetHwnd(); + HWND hwnd = GetHWND(); - if (hwnd) + if (m_hWnd) { - m_hWnd = 0; - wxCHECK_RET( ::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in UnsubclassWin") ); - PFNWP fnProc = (PFNWP)::WinQueryWindowULong(hwnd, QWS_USER); + PFNWP fnProc = (PFNWP)::WinQueryWindowPtr(hwnd, QWP_PFNWP); + if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc)) { WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc); @@ -1095,8 +1307,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; @@ -1320,10 +1538,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 @@ -1334,10 +1554,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( @@ -1502,9 +1724,9 @@ MRESULT wxWindow::OS2DefWindowProc( ) { if (m_fnOldWndProc) - return ((MRESULT)m_fnOldWndProc()); + return (MRESULT)m_fnOldWndProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam); else - return (::WinDefWindowProc(GetHwnd(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam)); + return ::WinDefWindowProc(GetHWND(), (ULONG)uMsg, (MPARAM)wParam, (MPARAM)lParam); } // end of wxWindow::OS2DefWindowProc bool wxWindow::OS2ProcessMessage( @@ -1674,12 +1896,12 @@ bool wxWindow::OS2ProcessMessage( } } } + // + // Let Dialogs process + // + if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0)); + return TRUE; } - // - // Let Dialogs process - // - if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0)); - return TRUE; #if wxUSE_TOOLTIPS if ( m_tooltip ) @@ -1699,7 +1921,11 @@ bool wxWindow::OS2TranslateMessage( WXMSG* pMsg ) { - return m_acceleratorTable.Translate(this, pMsg); +#if wxUSE_ACCEL + return m_acceleratorTable.Translate(m_hWnd, pMsg); +#else + return FALSE; +#endif //wxUSE_ACCEL } // end of wxWindow::OS2TranslateMessage // --------------------------------------------------------------------------- @@ -1715,8 +1941,8 @@ void wxWindow::UnpackCommand( ) { *pId = LOWORD(wParam); - *phWnd = (WXHWND)lParam; - *pCmd = HIWORD(wParam); + *phWnd = NULL; // or may be GetHWND() ? + *pCmd = LOWORD(lParam); } // end of wxWindow::UnpackCommand void wxWindow::UnpackActivate( @@ -1738,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( @@ -1798,7 +2033,8 @@ MRESULT EXPENTRY wxWndProc( pWnd->SetHWND((WXHWND)hWnd); } - MRESULT rc; + MRESULT rc = (MRESULT)0; + // // Stop right here if we don't have a valid handle in our wxWindow object. @@ -1816,6 +2052,7 @@ MRESULT EXPENTRY wxWndProc( else rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam); } + return rc; } // end of wxWndProc @@ -1833,22 +2070,15 @@ MRESULT wxWindow::OS2WindowProc( // Did we process the uMsg? // bool bProcessed = FALSE; - - // - // The return value - // - union - { - bool bAllow; - MRESULT mResult; - WXHICON hIcon; - WXHBRUSH hBrush; - } vRc; + bool bAllow; + MRESULT mResult; + WXHICON hIcon; + WXHBRUSH hBrush; // // For most messages we should return 0 when we do process the message // - vRc.mResult = (MRESULT)0; + mResult = (MRESULT)0; switch (uMsg) { @@ -1864,14 +2094,15 @@ MRESULT wxWindow::OS2WindowProc( // // Return 0 to bAllow window creation // - vRc.mResult = (MRESULT)(bMayCreate ? 0 : -1); + mResult = (MRESULT)(bMayCreate ? 0 : -1); } } break; case WM_DESTROY: - bProcessed = HandleDestroy(); - break; + HandleDestroy(); + bProcessed = TRUE; + break; case WM_MOVE: bProcessed = HandleMove( LOWORD(lParam) @@ -1900,6 +2131,7 @@ MRESULT wxWindow::OS2WindowProc( bProcessed = HandleActivate( wState ,(WXHWND)hWnd ); + bProcessed = FALSE; } break; @@ -1920,7 +2152,7 @@ MRESULT wxWindow::OS2WindowProc( // ourselves in ~wxWindow // bProcessed = TRUE; - vRc.mResult = (MRESULT)TRUE; + mResult = (MRESULT)TRUE; break; case WM_SHOW: @@ -1954,7 +2186,6 @@ MRESULT wxWindow::OS2WindowProc( bProcessed = HandleMouseEvent(uMsg, x, y, (WXUINT)wParam); } break; - case WM_SYSCOMMAND: bProcessed = HandleSysCommand(wParam, lParam); break; @@ -1975,27 +2206,28 @@ 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); } if ( bProcessed ) - vRc.mResult = (MRESULT)TRUE; + mResult = (MRESULT)TRUE; } break; case WM_QUERYDLGCODE: if ( m_lDlgCode ) { - vRc.mResult = (MRESULT)m_lDlgCode; + mResult = (MRESULT)m_lDlgCode; bProcessed = TRUE; } // @@ -2094,10 +2326,19 @@ MRESULT wxWindow::OS2WindowProc( #if defined(__VISAGECPP__) && (__IBMCPP__ >= 400) case WM_CTLCOLORCHANGE: { - bProcessed = HandleCtlColor(&vRc.hBrush); + bProcessed = HandleCtlColor(&hBrush); } 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 @@ -2125,17 +2366,6 @@ MRESULT wxWindow::OS2WindowProc( 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 - // - vRc.mResult = (MRESULT)TRUE; - } - break; // move all drag and drops to wxDrg case WM_ENDDRAG: @@ -2148,18 +2378,18 @@ MRESULT wxWindow::OS2WindowProc( if ( bProcessed ) { // we never set focus from here - vRc.mResult = FALSE; + mResult = FALSE; } break; // wxFrame specific message case WM_MINMAXFRAME: - bProcessed = HandleGetMinMaxInfo((PSWP)lParam); + bProcessed = HandleGetMinMaxInfo((PSWP)wParam); break; case WM_SYSVALUECHANGED: // TODO: do something - vRc.mResult = (MRESULT)TRUE; + mResult = (MRESULT)TRUE; break; // @@ -2176,20 +2406,22 @@ MRESULT wxWindow::OS2WindowProc( // processing this message - exactly what we need because we've // just set the cursor. // - vRc.mResult = (MRESULT)TRUE; + mResult = (MRESULT)TRUE; } break; } - if (!bProcessed) { #ifdef __WXDEBUG__ wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."), wxGetMessageName(uMsg)); #endif // __WXDEBUG__ - vRc.mResult = OS2DefWindowProc(uMsg, wParam, lParam); + if (IsKindOf(CLASSINFO(wxFrame))) + mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam); + else + mResult = OS2DefWindowProc(uMsg, wParam, lParam); } - return vRc.mResult; + return mResult; } // end of wxWindow::OS2WindowProc // @@ -2326,11 +2558,13 @@ bool wxWindow::OS2Create( { ERRORID vError; wxString sError; - long lX1 = (long)CW_USEDEFAULT; + long lX1 = 0L; long lY1 = 0L; - long lWidth1 = (long)CW_USEDEFAULT; - long lHeight1 = 100L; + 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 @@ -2357,6 +2591,7 @@ bool wxWindow::OS2Create( (ULONG)zClass == (ULONG)WC_COMBOBOX || (ULONG)zClass == (ULONG)WC_CONTAINER || (ULONG)zClass == (ULONG)WC_ENTRYFIELD || + (ULONG)zClass == (ULONG)WC_FRAME || (ULONG)zClass == (ULONG)WC_LISTBOX || (ULONG)zClass == (ULONG)WC_MENU || (ULONG)zClass == (ULONG)WC_NOTEBOOK || @@ -2369,6 +2604,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 @@ -2381,9 +2631,9 @@ bool wxWindow::OS2Create( ,(LONG)lY1 ,(LONG)lWidth ,(LONG)lHeight - ,NULLHANDLE + ,hOwner ,HWND_TOP - ,(ULONG)ulId + ,(ULONG)nControlId ,pCtlData ,pPresParams ); @@ -2394,6 +2644,7 @@ bool wxWindow::OS2Create( wxLogError("Can't create window of class %s!. Error: %s\n", zClass, sError); return FALSE; } + ::WinSetWindowULong(m_hWnd, QWL_USER, (ULONG) this); wxWndHook = NULL; #ifdef __WXDEBUG__ @@ -2413,6 +2664,17 @@ bool wxWindow::OS2Create( wxAssociateWinWithHandle((HWND)m_hWnd ,this ); + // + // Now need to subclass window. + // + if(!nNeedsubclass) + { + wxAssociateWinWithHandle((HWND)m_hWnd,this); + } + else + { + SubclassWin(GetHWND()); + } return TRUE; } // end of wxWindow::OS2Create @@ -2616,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))) - { - 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 + // + 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 // - POWNERITEM pDrawStruct = (OWNERITEM *)pItemStruct; - wxMenuItem* pMenuItem = (wxMenuItem *)(pDrawStruct->pItemData); + 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; } @@ -2795,42 +3173,74 @@ void wxWindow::OnSysColourChanged( bool wxWindow::HandlePaint() { HRGN hRgn = NULLHANDLE; + wxPaintEvent vEvent; + HPS hPS; + RECTL vRect; if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_NULL) { wxLogLastError("CreateRectRgn"); return FALSE; } + m_updateRegion = wxRegion(hRgn); + vEvent.SetEventObject(this); + if (!GetEventHandler()->ProcessEvent(vEvent)) + { + HPS hPS; - wxPaintEvent vEvent; + 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 + ); - vEvent.SetEventObject(this); + ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel()); + ::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); - dc.EndDrawing(); - dc.SelectOldObjects(hdc); - dc.SetHDC((WXHDC) NULL); - */ + vEvent.SetEventObject(this); + + bool rc = GetEventHandler()->ProcessEvent(vEvent); + + vDC.EndDrawing(); + vDC.m_hPS = NULLHANDLE; return TRUE; } // end of wxWindow::HandleEraseBkgnd @@ -2838,7 +3248,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 // --------------------------------------------------------------------------- @@ -3944,3 +4358,45 @@ static void TranslateKbdEventToMouse( pWin->ScreenToClient(pX, pY); } // end of TranslateKbdEventToMouse +// Find the wxWindow at the current mouse position, returning the mouse +// position. +wxWindow* wxFindWindowAtPointer( + wxPoint& rPt +) +{ + return wxFindWindowAtPoint(wxGetMousePosition()); +} + +wxWindow* wxFindWindowAtPoint( + const wxPoint& rPt +) +{ + POINTL vPt2; + + vPt2.x = rPt.x; + vPt2.y = rPt.y; + + HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE); + wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ; + HWND hWnd = hWndHit; + + // + // Try to find a window with a wxWindow associated with it + // + while (!pWin && (hWnd != 0)) + { + hWnd = ::WinQueryWindow(hWnd, QW_PARENT); + pWin = wxFindWinFromHandle((WXHWND)hWnd) ; + } + return pWin; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + POINTL vPt; + + ::WinQueryPointerPos(HWND_DESKTOP, &vPt); + return wxPoint(vPt.x, vPt.y); +} +