X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fa5593acee9def0bb7e3552dc17cdbe9809518d2..f00f657d37e530c55d5e98fac2477b477a6f1d36:/src/os2/frame.cpp diff --git a/src/os2/frame.cpp b/src/os2/frame.cpp index 4c0870f577..ee36faa2b6 100644 --- a/src/os2/frame.cpp +++ b/src/os2/frame.cpp @@ -53,10 +53,13 @@ extern wxWindowList wxModelessWindows; extern wxList WXDLLEXPORT wxPendingDelete; extern wxChar wxFrameClassName[]; + +#if wxUSE_MENUS_NATIVE extern wxMenu *wxCurrentPopupMenu; +#endif -extern void wxAssociateWinWithHandle( HWND hWnd - ,wxWindow* pWin +extern void wxAssociateWinWithHandle( HWND hWnd + ,wxWindowOS2* pWin ); // ---------------------------------------------------------------------------- @@ -233,6 +236,53 @@ wxFrame::~wxFrame() } } // end of wxFrame::~wxFrame +// +// 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 wxFrame::AlterChildPos() +{ + // + // OS/2 is the only OS concerned about this + // + wxWindow* pChild = NULL; + wxControl* pCtrl = NULL; + RECTL vRect; + SWP vSwp; + + ::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; + } +} // end of wxFrame::AlterChildPos + // // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. // @@ -243,6 +293,13 @@ void wxFrame::DoGetClientSize( { RECTL vRect; ::WinQueryWindowRect(GetHwnd(), &vRect); + + // + // No need to use statusbar code as in WIN32 as the FORMATFRAME + // window procedure ensures PM knows about the new frame client + // size internally. A ::WinQueryWindowRect is all that is needed! + // + if (pX) *pX = vRect.xRight - vRect.xLeft; if (pY) @@ -334,15 +391,9 @@ void wxFrame::DoGetPosition( POINTL vPoint; ::WinQueryWindowRect(m_hFrame, &vRect); - vPoint.x = vRect.xLeft; - - // - // OS/2 is backwards [WIN32 it is vRect.yTop] - // - vPoint.y = vRect.yBottom; - *pX = vPoint.x; - *pY = vPoint.y; + *pX = vRect.xRight - vRect.xLeft; + *pY = vRect.yTop - vRect.yBottom; } // end of wxFrame::DoGetPosition // ---------------------------------------------------------------------------- @@ -371,6 +422,7 @@ bool wxFrame::Show( ::WinQueryWindowPos(m_hFrame, &vSwp); m_bIconized = vSwp.fl & SWP_MINIMIZE; + ::WinQueryWindowPos(m_hWnd, &m_vSwpClient); ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0); ::WinEnableWindow(m_hFrame, TRUE); vEvent.SetEventObject(this); @@ -514,6 +566,7 @@ void wxFrame::PositionStatusBar() if (m_frameStatusBar) { int nWidth; + int nY; int nStatbarWidth; int nStatbarHeight; HWND hWndClient; @@ -521,21 +574,24 @@ void wxFrame::PositionStatusBar() RECTL vFRect; ::WinQueryWindowRect(m_hFrame, &vRect); + nY = vRect.yTop; ::WinMapWindowPoints(m_hFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2); vFRect = vRect; ::WinCalcFrameRect(m_hFrame, &vRect, TRUE); nWidth = vRect.xRight - vRect.xLeft; + nY = nY - (vRect.yBottom - vFRect.yBottom); m_frameStatusBar->GetSize( &nStatbarWidth ,&nStatbarHeight ); + nY= nY - nStatbarHeight; // // Since we wish the status bar to be directly under the client area, // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. // m_frameStatusBar->SetSize( vRect.xLeft - vFRect.xLeft - ,vRect.yBottom - vFRect.yBottom + ,nY ,nWidth ,nStatbarHeight ); @@ -550,6 +606,7 @@ void wxFrame::PositionStatusBar() } // end of wxFrame::PositionStatusBar #endif // wxUSE_STATUSBAR +#if wxUSE_MENUS_NATIVE void wxFrame::DetachMenuBar() { if (m_frameMenuBar) @@ -608,10 +665,49 @@ void wxFrame::SetMenuBar( } InternalSetMenuBar(); m_frameMenuBar = pMenuBar; - pMenuBar->Attach(this); + pMenuBar->Attach((wxFrame*)this); } } // end of wxFrame::SetMenuBar +void wxFrame::AttachMenuBar( + wxMenuBar* pMenubar +) +{ + wxFrameBase::AttachMenuBar(pMenubar); + + m_frameMenuBar = pMenubar; + + if (!pMenubar) + { + // + // Actually remove the menu from the frame + // + m_hMenu = (WXHMENU)0; + InternalSetMenuBar(); + } + else // Set new non NULL menu bar + { + // + // Can set a menubar several times. + // + if (pMenubar->GetHMenu()) + { + m_hMenu = pMenubar->GetHMenu(); + } + else + { + if (pMenubar->IsAttached()) + pMenubar->Detach(); + + m_hMenu = pMenubar->Create(); + + if (!m_hMenu) + return; + } + InternalSetMenuBar(); + } +} // end of wxFrame::AttachMenuBar + void wxFrame::InternalSetMenuBar() { ERRORID vError; @@ -634,6 +730,7 @@ void wxFrame::InternalSetMenuBar() } ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0); } // end of wxFrame::InternalSetMenuBar +#endif // wxUSE_MENUS_NATIVE // // Responds to colour changes, and passes event on to children @@ -676,11 +773,11 @@ bool wxFrame::ShowFullScreen( m_lFsStyle = lStyle; #if wxUSE_TOOLBAR - wxToolBar* pTheToolBar = GetToolBar(); + wxToolBar* pTheToolBar = GetToolBar(); #endif //wxUSE_TOOLBAR #if wxUSE_STATUSBAR - wxStatusBar* pTheStatusBar = GetStatusBar(); + wxStatusBar* pTheStatusBar = GetStatusBar(); #endif //wxUSE_STATUSBAR int nDummyWidth; @@ -984,6 +1081,22 @@ bool wxFrame::OS2Create( wxAssociateWinWithHandle(m_hWnd, this); wxAssociateWinWithHandle(m_hFrame, this); + m_backgroundColour.Set(wxString("GREY")); + + LONG lColor = (LONG)m_backgroundColour.GetPixel(); + + if (!::WinSetPresParam( m_hWnd + ,PP_BACKGROUNDCOLOR + ,sizeof(LONG) + ,(PVOID)&lColor + )) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + wxLogError("Error creating frame. Error: %s\n", sError); + return FALSE; + } + // // Now need to subclass window. Instead of calling the SubClassWin in wxWindow // we manually subclass here because we don't want to use the main wxWndProc @@ -995,6 +1108,17 @@ bool wxFrame::OS2Create( // Now size everything. If adding a menu the client will need to be resized. // + if (pParent) + { + nY = pParent->GetSize().y - (nY + nHeight); + } + else + { + RECTL vRect; + + ::WinQueryWindowRect(HWND_DESKTOP, &vRect); + nY = vRect.yTop - (nY + nHeight); + } if (!::WinSetWindowPos( m_hFrame ,HWND_TOP ,nX @@ -1009,37 +1133,6 @@ bool wxFrame::OS2Create( wxLogError("Error sizing frame. Error: %s\n", sError); return FALSE; } - // - // We may have to be smarter here when variable sized toolbars are added! - // - if (!::WinSetWindowPos( m_hWnd - ,HWND_TOP - ,nX + 20 - ,nY + 20 - ,nWidth - 60 - ,nHeight - 60 - ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_ZORDER - )) - { - vError = ::WinGetLastError(vHabmain); - sError = wxPMErrorToStr(vError); - wxLogError("Error sizing client. Error: %s\n", sError); - return FALSE; - } - -/* - uCtlCount = SHORT1FROMMP(::WinSendMsg(GetHWND(), WM_FORMATFRAME, (MPARAM)vSwp, (MPARAM)vRect)); - for (int i = 0; i < uCtlCount; i++) - { - if (vSwp[i].hwnd == GetHWND()) - memcpy(&m_vSwp, &vSwp[i], sizeof(SWP)); - else if (vSwp[i].hwnd == m_hVScroll) - memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP)); - else if (vSwp[i].hwnd == m_hHScroll) - memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP)); - else if (vSwp[i].hwnd == m_hTitleBar) - memcpy(&m_vSwpTitleBar, &vSwp[i], sizeof(SWP)); - }*/ return TRUE; } // end of wxFrame::OS2Create @@ -1051,27 +1144,51 @@ void wxFrame::OnActivate( wxActivateEvent& rEvent ) { - for (wxWindowList::Node* pNode = GetChildren().GetFirst(); - pNode; - pNode = pNode->GetNext()) + if ( rEvent.GetActive() ) { - // FIXME all this is totally bogus - we need to do the same as wxPanel, - // but how to do it without duplicating the code? + // restore focus to the child which was last focused + wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd); - // restore focus - wxWindow* pChild = pNode->GetData(); + wxWindow* pParent = m_pWinLastFocused ? m_pWinLastFocused->GetParent() + : NULL; + if (!pParent) + { + pParent = this; + } - if (!pChild->IsTopLevel() + wxSetFocusToChild( pParent + ,&m_pWinLastFocused + ); + } + else // deactivating + { + // + // Remember the last focused child if it is our child + // + m_pWinLastFocused = FindFocus(); + + for (wxWindowList::Node* pNode = GetChildren().GetFirst(); + pNode; + pNode = pNode->GetNext()) + { + // FIXME all this is totally bogus - we need to do the same as wxPanel, + // but how to do it without duplicating the code? + + // restore focus + wxWindow* pChild = pNode->GetData(); + + if (!pChild->IsTopLevel() #if wxUSE_TOOLBAR - && !wxDynamicCast(pChild, wxToolBar) + && !wxDynamicCast(pChild, wxToolBar) #endif // wxUSE_TOOLBAR #if wxUSE_STATUSBAR - && !wxDynamicCast(pChild, wxStatusBar) + && !wxDynamicCast(pChild, wxStatusBar) #endif // wxUSE_STATUSBAR - ) - { - pChild->SetFocus(); - return; + ) + { + pChild->SetFocus(); + return; + } } } } // end of wxFrame::OnActivate @@ -1154,12 +1271,12 @@ void wxFrame::PositionToolBar() } #endif // wxUSE_STATUSBAR - if ( GetToolBar() ) + if ( m_frameToolBar ) { int nToolbarWidth; int nToolbarHeight; - GetToolBar()->GetSize( &nToolbarWidth + m_frameToolBar->GetSize( &nToolbarWidth ,&nToolbarHeight ); @@ -1227,10 +1344,10 @@ bool wxFrame::OS2TranslateMessage( // wxMenuBar* pMenuBar = GetMenuBar(); - if (!pMenuBar ) + if (!pMenuBar) return FALSE; -#if wxUSE_ACCEL +#if wxUSE_ACCEL && wxUSE_MENUS_NATIVE const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable(); return rAcceleratorTable.Translate(GetHWND(), pMsg); #else @@ -1290,7 +1407,7 @@ bool wxFrame::HandlePaint() } else { - return wxWindow::HandlePaint(); + return(wxWindow::HandlePaint()); } } else @@ -1323,6 +1440,7 @@ bool wxFrame::HandleSize( // restore all child frames too // IconizeChildFrames(FALSE); + (void)SendIconizeEvent(FALSE); // // fall through @@ -1337,6 +1455,7 @@ bool wxFrame::HandleSize( // Iconize all child frames too // IconizeChildFrames(TRUE); + (void)SendIconizeEvent(); m_bIconized = TRUE; break; } @@ -1373,6 +1492,7 @@ bool wxFrame::HandleSize( vEvent.SetEventObject(this); bProcessed = GetEventHandler()->ProcessEvent(vEvent); + AlterChildPos(); } return bProcessed; } // end of wxFrame::HandleSize @@ -1401,6 +1521,7 @@ bool wxFrame::HandleCommand( // if (nCmd == CMDSRC_MENU || nCmd == CMDSRC_ACCELERATOR) { +#if wxUSE_MENUS_NATIVE if (wxCurrentPopupMenu) { wxMenu* pPopupMenu = wxCurrentPopupMenu; @@ -1410,7 +1531,9 @@ bool wxFrame::HandleCommand( return pPopupMenu->OS2Command( nCmd ,nId ); + return TRUE; } +#endif if (ProcessCommand(nId)) { @@ -1598,23 +1721,22 @@ MRESULT wxFrame::OS2WindowProc( break; case WM_PAINT: - { - HPS hPS; - RECTL vRect; - wxPaintEvent vEvent; - - hPS = WinBeginPaint(m_hWnd, 0L, &vRect); - ::WinFillRect(hPS, &vRect, CLR_BLUE /* SYSCLR_WINDOW */); - ::WinEndPaint(hPS); + bProcessed = HandlePaint(); + mRc = (MRESULT)FALSE; + break; - mRc = (MRESULT)FALSE; - vEvent.SetEventObject(this); - GetEventHandler()->ProcessEvent(vEvent); - bProcessed = TRUE; - } + case WM_ERASEBACKGROUND: + // + // Returning TRUE to requests PM to paint the window background + // in SYSCLR_WINDOW. We capture this here because the PS returned + // in Frames is the PS for the whole frame, which we can't really + // use at all. If you want to paint a different background, do it + // in an OnPaint using a wxPaintDC. + // + mRc = (MRESULT)(TRUE); break; - case WM_COMMAND: + case WM_COMMAND: { WORD wId; WORD wCmd; @@ -1669,15 +1791,6 @@ MRESULT wxFrame::OS2WindowProc( mRc = (MRESULT)FALSE; break; - case WM_ERASEBACKGROUND: - // - // Return TRUE to request PM to paint the window background - // in SYSCLR_WINDOW. - // - bProcessed = TRUE; - mRc = (MRESULT)(TRUE); - break; - case CM_QUERYDRAGIMAGE: { HPOINTER hIcon;