X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/92049cd473c81fbce934e71796b2d841d5e605fa..6a570331df89d26dfb682bedab0faf13e2c285d8:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index ac5c4cac6d..8d185d6420 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -31,6 +31,7 @@ #ifndef WX_PRECOMP #include #include "wx/msw/winundef.h" + #include "wx/window.h" #include "wx/accel.h" #include "wx/setup.h" #include "wx/menu.h" @@ -281,11 +282,10 @@ wxWindow::~wxWindow() { if ( !::DestroyWindow(GetHwnd()) ) wxLogLastError("DestroyWindow"); - } - // Restore old Window proc, if required and remove hWnd <-> wxWindow - // association - UnsubclassWin(); + // remove hWnd <-> wxWindow association + wxRemoveHandleAssociation(this); + } } // real construction (Init() must have been called before!) @@ -328,7 +328,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, // want everything: i.e. all keys and WM_CHAR message m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS | DLGC_WANTTAB | DLGC_WANTMESSAGE; - } MSWCreate(m_windowId, parent, wxCanvasClassName, this, NULL, @@ -448,7 +447,7 @@ bool wxWindow::SetFont(const wxFont& font) wxASSERT_MSG( hFont, _T("should have valid font") ); - ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, TRUE); + ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); } return TRUE; @@ -801,10 +800,13 @@ void wxWindow::SubclassWin(WXHWND hWnd) { wxASSERT_MSG( !m_oldWndProc, _T("subclassing window twice?") ); - wxAssociateWinWithHandle((HWND)hWnd, this); + HWND hwnd = (HWND)hWnd; + wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in SubclassWin") ); - m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC); - SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc); + wxAssociateWinWithHandle(hwnd, this); + + m_oldWndProc = (WXFARPROC) GetWindowLong(hwnd, GWL_WNDPROC); + SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc); } void wxWindow::UnsubclassWin() @@ -812,16 +814,19 @@ void wxWindow::UnsubclassWin() wxRemoveHandleAssociation(this); // Restore old Window proc - if ( GetHwnd() ) + HWND hwnd = GetHwnd(); + if ( hwnd ) { - FARPROC farProc = (FARPROC) GetWindowLong(GetHwnd(), GWL_WNDPROC); + m_hWnd = 0; + + wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in SubclassWin") ); + + FARPROC farProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC); if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) ) { - SetWindowLong(GetHwnd(), GWL_WNDPROC, (LONG) m_oldWndProc); + SetWindowLong(hwnd, GWL_WNDPROC, (LONG) m_oldWndProc); m_oldWndProc = 0; } - - m_hWnd = 0; } } @@ -1168,35 +1173,80 @@ void wxWindow::DoGetClientSize(int *x, int *y) const *y = rect.bottom; } +// set the size of the window: if the dimensions are positive, just use them, +// but if any of them is equal to -1, it means that we must find the value for +// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in +// which case -1 is a valid value for x and y) +// +// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate +// the width/height to best suit our contents, otherwise we reuse the current +// width/height void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) { + // get the current size and position... int currentX, currentY; GetPosition(¤tX, ¤tY); int currentW,currentH; GetSize(¤tW, ¤tH); - if ( x == currentX && y == currentY && width == currentW && height == currentH ) + // ... and don't do anything (avoiding flicker) if it's already ok + if ( x == currentX && y == currentY && + width == currentW && height == currentH ) + { return; + } - int actualWidth = width; - int actualHeight = height; - int actualX = x; - int actualY = y; if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - actualX = currentX; + x = currentX; if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - actualY = currentY; + y = currentY; - AdjustForParentClientOrigin(actualX, actualY, sizeFlags); + AdjustForParentClientOrigin(x, y, sizeFlags); + wxSize size(-1, -1); if ( width == -1 ) - actualWidth = currentW; + { + if ( sizeFlags && wxSIZE_AUTO_WIDTH ) + { + size = DoGetBestSize(); + width = size.x; + } + else + { + // just take the current one + width = currentW; + } + } + if ( height == -1 ) - actualHeight = currentH; + { + if ( sizeFlags && wxSIZE_AUTO_HEIGHT ) + { + if ( size.x == -1 ) + { + size= DoGetBestSize(); + } + //else: already called DoGetBestSize() above - HWND hWnd = GetHwnd(); - if ( hWnd ) - MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE); + height = size.y; + } + else + { + // just take the current one + height = currentH; + } + } + + if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) + { + wxLogLastError("MoveWindow"); + } +} + +// 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) @@ -1312,7 +1362,7 @@ void wxWindow::GetTextExtent(const wxString& string, SIZE sizeRect; TEXTMETRIC tm; - GetTextExtentPoint(dc, (const wxChar *)string, (int)string.Length(), &sizeRect); + GetTextExtentPoint(dc, string, (int)string.Length(), &sizeRect); GetTextMetrics(dc, &tm); if ( fontToUse && fnt && hfontOld ) @@ -1368,6 +1418,31 @@ void wxWindow::GetCaretPos(int *x, int *y) const } #endif // wxUSE_CARET +// --------------------------------------------------------------------------- +// popup menu +// --------------------------------------------------------------------------- + +bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) +{ + menu->SetInvokingWindow(this); + menu->UpdateUI(); + + HWND hWnd = GetHwnd(); + HMENU hMenu = GetHmenuOf(menu); + POINT point; + point.x = x; + point.y = y; + ::ClientToScreen(hWnd, &point); + wxCurrentPopupMenu = menu; + ::TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL); + wxYield(); + wxCurrentPopupMenu = NULL; + + menu->SetInvokingWindow(NULL); + + return TRUE; +} + // =========================================================================== // pre/post message processing // =========================================================================== @@ -1454,9 +1529,28 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) // buttons want process Enter themselevs bProcess = FALSE; } - // else: but if it does not it makes sense to make it - // work like a TAB - and that's what we do. - // Note that Ctrl-Enter always works this way. + else + { + wxPanel *panel = wxDynamicCast(this, wxPanel); + wxButton *btn = NULL; + if ( panel ) + { + // panel may have a default button which should + // be activated by Enter + btn = panel->GetDefaultItem(); + } + + if ( btn && btn->IsEnabled() ) + { + // if we do have a default button, do press it + btn->MSWCommand(BN_CLICKED, 0 /* unused */); + + return TRUE; + } + // else: but if it does not it makes sense to make + // it work like a TAB - and that's what we do. + // Note that Ctrl-Enter always works this way. + } } break; @@ -1504,10 +1598,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) bool wxWindow::MSWTranslateMessage(WXMSG* pMsg) { - return m_acceleratorTable.Ok() && - ::TranslateAccelerator(GetHwnd(), - GetTableHaccel(m_acceleratorTable), - (MSG *)pMsg); + return m_acceleratorTable.Translate(this, pMsg); } // --------------------------------------------------------------------------- @@ -1737,8 +1828,8 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case WM_MBUTTONUP: case WM_MBUTTONDBLCLK: { - int x = LOWORD(lParam); - int y = HIWORD(lParam); + short x = LOWORD(lParam); + short y = HIWORD(lParam); processed = HandleMouseEvent(message, x, y, wParam); }