X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/11e59d47c05f2303ccfc07625b726ac7cb821881..dd16fdaeaaa5882bdf1ee7af8b2a64821c0680af:/src/os2/window.cpp?ds=inline diff --git a/src/os2/window.cpp b/src/os2/window.cpp index ff7acf974f..dd6e9411d5 100644 --- a/src/os2/window.cpp +++ b/src/os2/window.cpp @@ -9,7 +9,9 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// // For compilers that support precompilation, includes "wx.h". +// #include "wx/wxprec.h" #ifndef WX_PRECOMP @@ -64,14 +66,21 @@ #include -// place compiler, OS specific includes here - +// +// Place compiler, OS specific includes here +// -// standard macros -- these are for OS/2 PM, but most GUI's have something similar +// +// Standard macros -- these are for OS/2 PM, but most GUI's have something similar +// #ifndef GET_X_LPARAM +// // SHORT1FROMMP -- LOWORD +// #define GET_X_LPARAM(mp) ((unsigned short)(unsigned long)(mp)) +// // SHORT2FROMMP -- HIWORD +// #define GET_Y_LPARAM(mp) ((unsigned short)(unsigned long)(mp >> 16)) #endif // GET_X_LPARAM @@ -79,18 +88,23 @@ // global variables // --------------------------------------------------------------------------- -// the last Windows message we got (MT-UNSAFE) -extern WXMSGID s_currentMsg; -extern wxList WXDLLEXPORT wxPendingDelete; -extern wxChar wxCanvasClassName[]; +// +// The last Windows message we got (MT-UNSAFE) +// +extern WXMSGID s_currentMsg; -wxMenu *wxCurrentPopupMenu = NULL; -wxList *wxWinHandleList = NULL; +wxMenu* wxCurrentPopupMenu = NULL; +extern wxList WXDLLEXPORT wxPendingDelete; +extern wxChar* wxCanvasClassName; +wxList* wxWinHandleList = NULL; // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- + +// // the window proc for all our windows; most gui's have something similar +// MRESULT wxWndProc( HWND hWnd ,ULONG message ,MPARAM mp1 @@ -101,17 +115,32 @@ MRESULT wxWndProc( HWND hWnd const char *wxGetMessageName(int message); #endif //__WXDEBUG__ -void wxRemoveHandleAssociation(wxWindow *win); -void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win); -wxWindow *wxFindWinFromHandle(WXHWND hWnd); +void wxRemoveHandleAssociation(wxWindow* pWin); +void wxAssociateWinWithHandle( HWND hWnd + ,wxWindow* pWin + ); +wxWindow* wxFindWinFromHandle(WXHWND hWnd); +// +// This magical function is used to translate VK_APPS key presses to right +// mouse clicks +// +static void TranslateKbdEventToMouse( wxWindow* pWin + ,int* pX + ,int* pY + ,MPARAM* pFlags + ); + +// +// get the current state of SHIFT/CTRL keys +// +static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; } +static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; } // --------------------------------------------------------------------------- // event tables // --------------------------------------------------------------------------- -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) -#endif BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground) @@ -124,71 +153,92 @@ END_EVENT_TABLE() // implementation // =========================================================================== -// Find an item given the MS Windows id -wxWindow *wxWindow::FindItem(long id) const +// +// Find an item given the PM Window id +// +wxWindow* wxWindow::FindItem( + long lId +) const { - wxWindowList::Node *current = GetChildren().GetFirst(); - while (current) - { - wxWindow *childWin = current->GetData(); + wxControl* pItem = wxDynamicCast( this + ,wxControl + ); - wxWindow *wnd = childWin->FindItem(id); - if ( wnd ) - return wnd; - - if ( childWin->IsKindOf(CLASSINFO(wxControl)) ) + if (pItem) + { + // + // I it we or one of our "internal" children? + // + if (pItem->GetId() == lId || + (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND)) { - wxControl *item = (wxControl *)childWin; - if ( item->GetId() == id ) - return item; - else - { - // In case it's a 'virtual' control (e.g. radiobox) - if ( item->GetSubcontrols().Member((wxObject *)id) ) - return item; - } + return pItem; } - - current = current->GetNext(); } - return NULL; -} + wxWindowList::Node* pCurrent = GetChildren().GetFirst(); + + while (pCurrent) + { + wxWindow* pChildWin = pCurrent->GetData(); + wxWindow* pWnd = pChildWin->FindItem(lId); + + if (pWnd) + return pWnd; -// Find an item given the MS Windows handle -wxWindow *wxWindow::FindItemByHWND(WXHWND hWnd, bool controlOnly) const + pCurrent = pCurrent->GetNext(); + } + return(NULL); +} // end of wxWindow::FindItem + +// +// Find an item given the PM Window handle +// +wxWindow* wxWindow::FindItemByHWND( + WXHWND hWnd +, bool bControlOnly +) const { - wxWindowList::Node *current = GetChildren().GetFirst(); - while (current) + wxWindowList::Node* pCurrent = GetChildren().GetFirst(); + + while (pCurrent) { - wxWindow *parent = current->GetData(); + wxWindow* pParent = pCurrent->GetData(); + // // Do a recursive search. - wxWindow *wnd = parent->FindItemByHWND(hWnd); - if ( wnd ) - return wnd; + // + wxWindow* pWnd = pParent->FindItemByHWND(hWnd); + + if (pWnd) + return(pWnd); - if ( !controlOnly || parent->IsKindOf(CLASSINFO(wxControl)) ) + if (!bControlOnly || pParent->IsKindOf(CLASSINFO(wxControl))) { - wxWindow *item = current->GetData(); - if ( item->GetHWND() == hWnd ) - return item; + wxWindow* pItem = pCurrent->GetData(); + + if (pItem->GetHWND() == hWnd) + return(pItem); else { - if ( item->ContainsHWND(hWnd) ) - return item; + if (pItem->ContainsHWND(hWnd)) + return(pItem); } } - - current = current->GetNext(); + pCurrent = pCurrent->GetNext(); } - return NULL; -} + return(NULL); +} // end of wxWindow::FindItemByHWND +// // Default command handler -bool wxWindow::OS2Command(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id)) +// +bool wxWindow::OS2Command( + WXUINT WXUNUSED(uParam) +, WXWORD WXUNUSED(uId) +) { - return FALSE; + return(FALSE); } // ---------------------------------------------------------------------------- @@ -197,84 +247,141 @@ bool wxWindow::OS2Command(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id)) void wxWindow::Init() { - // generic + // + // Generic + // InitBase(); + // // PM specific - m_doubleClickAllowed = 0; - m_winCaptured = FALSE; + // + m_bDoubleClickAllowed = 0; + m_bWinCaptured = FALSE; m_isBeingDeleted = FALSE; - m_oldWndProc = 0; - m_useCtl3D = FALSE; - m_mouseInWindow = FALSE; + m_fnOldWndProc = 0; + m_bUseCtl3D = FALSE; + m_bMouseInWindow = FALSE; + // // wxWnd + // m_hMenu = 0; - m_hWnd = 0; - // pass WM_GETDLGCODE to DefWindowProc() + // + // Pass WM_GETDLGCODE to DefWindowProc() m_lDlgCode = 0; - m_xThumbSize = 0; - m_yThumbSize = 0; - m_backgroundTransparent = FALSE; + m_nXThumbSize = 0; + m_nYThumbSize = 0; + m_bBackgroundTransparent = FALSE; - // as all windows are created with WS_VISIBLE style... + // + // As all windows are created with WS_VISIBLE style... + // m_isShown = TRUE; #if wxUSE_MOUSEEVENT_HACK - m_lastMouseX = - m_lastMouseY = -1; - m_lastMouseEvent = -1; + m_lLastMouseX = + m_lLastMouseY = -1; + m_nLastMouseEvent = -1; #endif // wxUSE_MOUSEEVENT_HACK -} +} // wxWindow::Init +// // Destructor +// wxWindow::~wxWindow() { m_isBeingDeleted = TRUE; OS2DetachWindowMenu(); - // delete handlers? if (m_parent) m_parent->RemoveChild(this); DestroyChildren(); if (m_hWnd) { - if(!WinDestroyWindow(GetHWND())) + if(!::WinDestroyWindow(GetHWND())) wxLogLastError(wxT("DestroyWindow")); + // // remove hWnd <-> wxWindow association + // wxRemoveHandleAssociation(this); } -} - -bool wxWindow::Create(wxWindow *parent, wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) -{ - wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); - - if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) - return FALSE; - - parent->AddChild(this); - - bool want3D; - WXDWORD exStyle = 0; // TODO: Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); - DWORD msflags = 0; - - - // TODO: PM Specific initialization - OS2Create(m_windowId, parent, wxCanvasClassName, this, NULL, - pos.x, pos.y, - WidthDefault(size.x), HeightDefault(size.y), - msflags, NULL, exStyle); - return TRUE; -} +} // end of wxWindow::~wxWindow + +bool wxWindow::Create( + wxWindow* pParent +, wxWindowID vId +, const wxPoint& rPos +, const wxSize& rSize +, long lStyle +, const wxString& rName +) +{ + wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent")); + + if ( !CreateBase( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,wxDefaultValidator + ,rName + )) + return(FALSE); + + pParent->AddChild(this); + + ULONG ulFlags = 0L; + + // + // Frame windows and their derivatives only + // + if (lStyle & wxBORDER) + ulFlags |= FCF_BORDER; + if (lStyle & wxTHICK_FRAME ) + ulFlags |= FCF_SIZEBORDER; + + // + // Some generic window styles + // + ulFlags |= WS_VISIBLE; + if (lStyle & wxCLIP_CHILDREN ) + ulFlags |= WS_CLIPCHILDREN; + + bool bWant3D; + WXDWORD dwExStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &bWant3D); + + // + // OS/2 PM doesn't have "extended" styles but if the library specifies + // them and we are creating a frame window then at least give it a border + // + if ( bWant3D || + (m_windowStyle & wxSIMPLE_BORDER) || + (m_windowStyle & wxRAISED_BORDER ) || + (m_windowStyle & wxSUNKEN_BORDER) || + (m_windowStyle & wxDOUBLE_BORDER) + ) + { + ulFlags |= FCF_BORDER; + } + OS2Create( m_windowId + ,pParent + ,wxCanvasClassName + ,this + ,NULL + ,rPos.x + ,rPos.y + ,WidthDefault(rSize.x) + ,HeightDefault(rSize.y) + ,ulFlags + ,NULL + ,dwExStyle + ); + return(TRUE); +} // end of wxWindow::Create // --------------------------------------------------------------------------- // basic operations @@ -282,74 +389,177 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, void wxWindow::SetFocus() { - // TODO: -} + HWND hWnd = GetHwnd(); + + if (hWnd) + ::WinSetFocus(HWND_DESKTOP, hWnd); +} // end of wxWindow::SetFocus wxWindow* wxWindowBase::FindFocus() { - wxWindow* window = NULL; - // TODO: - return(window); -} + HWND hWnd = ::WinQueryFocus(HWND_DESKTOP); + + if (hWnd) + { + return wxFindWinFromHandle((WXHWND)hWnd); + } + return NULL; +} // wxWindowBase::FindFocus -bool wxWindow::Enable(bool enable) // check if base implementation is OK +bool wxWindow::Enable( + bool bEnable +) { - // TODO: + if (!wxWindowBase::Enable(bEnable)) + return(FALSE); + + HWND hWnd = GetHwnd(); + + if ( hWnd ) + ::WinEnableWindow(hWnd, (BOOL)bEnable); + + wxWindowList::Node* pNode = GetChildren().GetFirst(); + + while (pNode) + { + wxWindow* pChild = pNode->GetData(); + + pChild->Enable(bEnable); + pNode = pNode->GetNext(); + } return(TRUE); -} +} // end of wxWindow::Enable -bool wxWindow::Show(bool show) // check if base implementation is OK +bool wxWindow::Show( + bool bShow +) { - // TODO: + if (!wxWindowBase::Show(bShow)) + return(FALSE); + + HWND hWnd = GetHwnd(); + + ::WinShowWindow(hWnd, bShow); + + if (bShow) + { + ::WinSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER); + } return(TRUE); -} +} // end of wxWindow::Show void wxWindow::Raise() { - // TODO: -} + ::WinSetWindowPos(GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_ACTIVATE); +} // end of wxWindow::Raise void wxWindow::Lower() { - // TODO: -} + ::WinSetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER | SWP_DEACTIVATE); +} // end of wxWindow::Lower -void wxWindow::SetTitle( const wxString& title) +void wxWindow::SetTitle( + const wxString& rTitle +) { -// TODO: SetWindowText(GetHwnd(), title.c_str()); -} + ::WinSetWindowText(GetHwnd(), rTitle.c_str()); +} // end of wxWindow::SetTitle wxString wxWindow::GetTitle() const { return wxGetWindowText(GetHWND()); -} +} // end of wxWindow::GetTitle void wxWindow::CaptureMouse() { - // TODO: -} + HWND hWnd = GetHwnd(); + + if (hWnd && !m_bWinCaptured) + { + ::WinSetCapture(HWND_DESKTOP, hWnd); + m_bWinCaptured = TRUE; + } +} // end of wxWindow::GetTitle void wxWindow::ReleaseMouse() { - // TODO: -} + if (m_bWinCaptured) + { + ::WinSetCapture(HWND_DESKTOP, NULLHANDLE); + m_bWinCaptured = FALSE; + } +} // end of wxWindow::ReleaseMouse -bool wxWindow::SetFont(const wxFont& f) +bool wxWindow::SetFont( + const wxFont& rFont +) { - // TODO: + if (!wxWindowBase::SetFont(rFont)) + { + // nothing to do + return(FALSE); + } + + HWND hWnd = GetHwnd(); + + if (hWnd != 0) + { + wxChar zFont[128]; + + sprintf(zFont, "%d.%s", rFont.GetPointSize(), rFont.GetFaceName().c_str()); + return(::WinSetPresParam(hWnd, PP_FONTNAMESIZE, strlen(zFont), (PVOID)zFont)); + } return(TRUE); } -bool wxWindow::SetCursor(const wxCursor& cursor) // check if base implementation is OK +bool wxWindow::SetCursor( + const wxCursor& rCursor +) // check if base implementation is OK { - // TODO: - return(TRUE); -} + if ( !wxWindowBase::SetCursor(rCursor)) + { + // no change + return FALSE; + } + + wxASSERT_MSG( m_cursor.Ok(), + wxT("cursor must be valid after call to the base version")); + + HWND hWnd = GetHwnd(); + POINTL vPoint; + RECTL vRect; + HPS hPS; + HRGN hRGN; -void wxWindow::WarpPointer(int x_pos, int y_pos) + hPS = ::WinGetPS(hWnd); + + ::WinQueryPointerPos(HWND_DESKTOP, &vPoint); + ::WinQueryWindowRect(hWnd, &vRect); + + hRGN = ::GpiCreateRegion(hPS, 1L, &vRect); + + if ((::GpiPtInRegion(hPS, hRGN, &vPoint) == PRGN_INSIDE) && !wxIsBusy()) + { + ::WinSetPointer(HWND_DESKTOP, (HPOINTER)m_cursor.GetHCURSOR()); + } + return TRUE; +} // end of wxWindow::SetCursor + +void wxWindow::WarpPointer( + int nXPos +, int nYPos +) { - // TODO: -} + int nX = nXPos; + int nY = nYPos; + RECTL vRect; + + ::WinQueryWindowRect(GetHwnd(), &vRect); + nX += vRect.xLeft; + nY += vRect.yBottom; + + ::WinSetPointerPos(HWND_DESKTOP, (LONG)nX, (LONG)(nY)); +} // end of wxWindow::WarpPointer #if WXWIN_COMPATIBILITY void wxWindow::OS2DeviceToLogical (float *x, float *y) const @@ -362,27 +572,51 @@ void wxWindow::OS2DeviceToLogical (float *x, float *y) const // --------------------------------------------------------------------------- #if WXWIN_COMPATIBILITY -void wxWindow::SetScrollRange(int orient, int range, bool refresh) -{ - // TODO: -} - -void wxWindow::SetScrollPage(int orient, int page, bool refresh) -{ - // TODO: +void wxWindow::SetScrollRange( + int nOrient +, int nRange +, bool bRefresh +) +{ + ::WinSendMsg(GetHwnd(), SBM_SETSCROLLBAR, (MPARAM)0, MPFROM2SHORT(0, nRange)); +} // end of wxWindow::SetScrollRange + +void wxWindow::SetScrollPage( + int nOrient +, int nPage +, bool bRefresh +) +{ + if ( orient == wxHORIZONTAL ) + m_xThumbSize = page; + else + m_yThumbSize = page; } -int wxWindow::OldGetScrollRange(int orient) const +int wxWindow::OldGetScrollRange( + int nOrient +) const { - // TODO: - return 0; -} + MRESULT mRc; + HWND hWnd = GetHwnd(); -int wxWindow::GetScrollPage(int orient) const -{ - // TODO: - return(1); -} + if (hWnd) + { + mRc = WinSendMsg(hWnd, SBM_QUERYRANGE, (MPARAM)0L, (MPARAM)0L); + return(SHORT2FROMMR(mRc)); + } + return 0; +} // end of wxWindow::OldGetScrollRange + +int wxWindow::GetScrollPage( + int nOrient +) const +{ + if (nOrient == wxHORIZONTAL) + return m_xThumbSize; + else + return m_yThumbSize; +} // end of wxWindow::GetScrollPage #endif // WXWIN_COMPATIBILITY int wxWindow::GetScrollPos(int orient) const @@ -435,7 +669,7 @@ void wxWindow::ScrollWindow( int dx void wxWindow::SubclassWin(WXHWND hWnd) { - wxASSERT_MSG( !m_oldWndProc, wxT("subclassing window twice?") ); + wxASSERT_MSG( !m_fnOldWndProc, wxT("subclassing window twice?") ); HWND hwnd = (HWND)hWnd; /* @@ -504,7 +738,7 @@ WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders) WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) const { - DWORD exStyle; // remove after implementation doe + DWORD exStyle = 0L; // remove after implementation doe /* TODO: this ought to be fun * // If matches certain criteria, then assume no 3D effects @@ -695,12 +929,6 @@ void wxWindow::DoSetSize(int x, int y, // TODO: } -// for a generic window there is no natural best size - just use the current one -wxSize wxWindow::DoGetBestSize() -{ - return GetSize(); -} - void wxWindow::DoSetClientSize(int width, int height) { // TODO: @@ -794,7 +1022,7 @@ bool wxWindow::DoPopupMenu( wxMenu *menu, int x, int y ) // pre/post message processing // =========================================================================== -MRESULT wxWindow::OS2DefWindowProc(HWND hwnd, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +MRESULT wxWindow::OS2DefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { // TODO: return (MRESULT)0; @@ -864,7 +1092,7 @@ void wxWindow::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, wxWindow *wxWndHook = NULL; // Main window proc -MRESULT wxWndProc(HWND hWnd, UINT message, MPARAM wParam, MPARAM lParam) +MRESULT wxWndProc(HWND hWnd, ULONG message, MPARAM wParam, MPARAM lParam) { // trace all messages - useful for the debugging #ifdef __WXDEBUG__ @@ -897,13 +1125,13 @@ MRESULT wxWndProc(HWND hWnd, UINT message, MPARAM wParam, MPARAM lParam) { // FIXME: why do we do this? wnd->SetHWND((WXHWND) hWnd); - rc = wnd->OS2DefWindowProc(hWnd, message, wParam, lParam ); + rc = wnd->OS2DefWindowProc(message, wParam, lParam ); wnd->SetHWND(0); } else { if ( wnd ) - rc = wnd->OS2WindowProc(hWnd, message, wParam, lParam); + rc = wnd->OS2WindowProc(message, wParam, lParam); else rc = 0; //TODO: DefWindowProc( hWnd, message, wParam, lParam ); } @@ -911,7 +1139,7 @@ MRESULT wxWndProc(HWND hWnd, UINT message, MPARAM wParam, MPARAM lParam) return rc; } -MRESULT wxWindow::OS2WindowProc(HWND hWnd, WXUINT message, WXWPARAM wParam, WXLPARAM lParam) +MRESULT wxWindow::OS2WindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) { // did we process the message? bool processed = FALSE; @@ -2071,10 +2299,10 @@ bool wxWindow::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags) bool wxWindow::HandleMouseMove(int x, int y, WXUINT flags) { - if ( !m_mouseInWindow ) + if ( !m_bMouseInWindow ) { // Generate an ENTER event - m_mouseInWindow = TRUE; + m_bMouseInWindow = TRUE; wxMouseEvent event(wxEVT_ENTER_WINDOW); InitMouseEvent(event, x, y, flags);