X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3a19e16d18542ec645271612d3e0170831cbf0eb..e27ce4e910f99ab572a609b7d560abf56440f81d:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 78eb269cf5..1aff70f753 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -21,7 +21,6 @@ #endif #ifndef WX_PRECOMP - #include #include "wx/setup.h" #include "wx/menu.h" #include "wx/dc.h" @@ -36,6 +35,8 @@ #include "wx/button.h" #include "wx/settings.h" #include "wx/msgdlg.h" + + #include #endif #if wxUSE_OWNER_DRAWN @@ -48,7 +49,13 @@ #include "wx/menuitem.h" #include "wx/log.h" + +#if wxUSE_TOOLTIPS #include "wx/tooltip.h" +#endif + +#include "wx/intl.h" +#include "wx/log.h" #include "wx/msw/private.h" @@ -63,7 +70,9 @@ #include #endif +#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) #include +#endif #ifndef __TWIN32__ #ifdef __GNUWIN32__ @@ -185,6 +194,8 @@ bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam, WXLPARAM* WXUNUSED(result)) { +#ifdef __WIN95__ +#if wxUSE_TOOLTIPS NMHDR* hdr = (NMHDR *)lParam; if ( hdr->code == TTN_NEEDTEXT && m_tooltip ) { @@ -194,6 +205,8 @@ bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam), // processed return TRUE; } +#endif +#endif return FALSE; } @@ -282,7 +295,9 @@ void wxWindow::Init() m_pDropTarget = NULL; #endif +#if wxUSE_TOOLTIPS m_tooltip = NULL; +#endif } wxWindow::wxWindow() @@ -293,11 +308,21 @@ wxWindow::wxWindow() // Destructor wxWindow::~wxWindow() { + // Remove potential dangling pointer + if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel))) + { + wxPanel* panel = (wxPanel*) GetParent(); + if (panel->GetLastFocus() == this) + panel->SetLastFocus((wxWindow*) NULL); + } + m_isBeingDeleted = TRUE; // first of all, delete the things on which nothing else depends +#if wxUSE_TOOLTIPS wxDELETE(m_tooltip); +#endif // JACS - if behaviour is odd, restore this // to the start of ~wxWindow. Vadim has changed @@ -537,6 +562,8 @@ void wxWindow::DragAcceptFiles(bool accept) // tooltips // ---------------------------------------------------------------------------- +#if wxUSE_TOOLTIPS + void wxWindow::SetToolTip(const wxString &tip) { SetToolTip(new wxToolTip(tip)); @@ -551,6 +578,8 @@ void wxWindow::SetToolTip(wxToolTip *tooltip) m_tooltip->SetWindow(this); } +#endif // wxUSE_TOOLTIPS + // Get total size void wxWindow::GetSize(int *x, int *y) const { @@ -741,13 +770,14 @@ void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) bool wxWindow::Show(bool show) { + m_isShown = show; HWND hWnd = (HWND) GetHWND(); int cshow; if (show) cshow = SW_SHOW; else cshow = SW_HIDE; - ShowWindow(hWnd, (BOOL)cshow); + ShowWindow(hWnd, cshow); if (show) { BringWindowToTop(hWnd); @@ -759,7 +789,11 @@ bool wxWindow::Show(bool show) bool wxWindow::IsShown(void) const { - return (::IsWindowVisible((HWND) GetHWND()) != 0); + // Can't rely on IsWindowVisible, since it will return FALSE + // if the parent is not visible. + return m_isShown; +// int ret = ::IsWindowVisible((HWND) GetHWND()) ; +// return (ret != 0); } int wxWindow::GetCharHeight(void) const @@ -883,10 +917,8 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA wnd->m_hWnd = (WXHWND) hWnd; } - // Stop right here if we don't have a valid handle - // in our wxWnd object. + // Stop right here if we don't have a valid handle in our wxWindow object. if (wnd && !wnd->m_hWnd) { - // wxDebugMsg("Warning: could not find a valid handle, wx_win.cc/wxWndProc.\n"); wnd->m_hWnd = (WXHWND) hWnd; long res = wnd->MSWDefWindowProc(message, wParam, lParam ); wnd->m_hWnd = 0; @@ -1201,39 +1233,63 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) break; } -#if 0 case WM_KEYDOWN: { - MSWOnKeyDown((WORD) wParam, lParam); - // we consider these message "not interesting" + // If this has been processed by an event handler, + // return 0 now (we've handled it). + if (MSWOnKeyDown((WORD) wParam, lParam)) + { + return 0; + } + + // we consider these message "not interesting" to OnChar if ( wParam == VK_SHIFT || wParam == VK_CONTROL ) + { return Default(); + } - // Avoid duplicate messages to OnChar - if ( (wParam != VK_ESCAPE) && (wParam != VK_SPACE) && - (wParam != VK_RETURN) && (wParam != VK_BACK) && - (wParam != VK_TAB) ) + // Avoid duplicate messages to OnChar for these special keys + switch ( wParam ) { - MSWOnChar((WORD)wParam, lParam); - if ( ::GetKeyState(VK_CONTROL) & 0x100 ) - return Default(); + case VK_ESCAPE: + case VK_SPACE: + case VK_RETURN: + case VK_BACK: + case VK_TAB: + case VK_LEFT: + case VK_RIGHT: + case VK_DOWN: + case VK_UP: +/* +// if ( ::GetKeyState(VK_CONTROL) & 0x100 ) // Don't understand purpose of this test + if (!MSWOnChar((WORD)wParam, lParam)) + return Default(); + break; +*/ + default: + if (!MSWOnChar((WORD)wParam, lParam)) + { + return Default(); + } +/* + if ( ::GetKeyState(VK_CONTROL) & 0x100 ) + return Default(); +*/ + break; } - else if ( ::GetKeyState(VK_CONTROL) & 0x100 ) - MSWOnChar((WORD)wParam, lParam); - else - return Default(); + break; } -#endif - case WM_KEYUP: { - MSWOnKeyUp((WORD) wParam, lParam); + if (!MSWOnKeyUp((WORD) wParam, lParam)) + return Default(); break; } case WM_CHAR: // Always an ASCII character { - MSWOnChar((WORD)wParam, lParam, TRUE); + if (!MSWOnChar((WORD)wParam, lParam, TRUE)) + return Default(); break; } @@ -1436,6 +1492,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) default: return MSWDefWindowProc(message, wParam, lParam ); } + return 0; // Success: we processed this command. } @@ -1702,6 +1759,13 @@ bool wxWindow::MSWOnSetFocus(WXHWND WXUNUSED(hwnd)) ::ShowCaret((HWND) GetHWND()); } + // panel wants to track the window which was the last to have focus in it + wxWindow *parent = GetParent(); + if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) ) + { + ((wxPanel *)parent)->SetLastFocus(this); + } + wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); event.SetEventObject(this); if (!GetEventHandler()->ProcessEvent(event)) @@ -1927,22 +1991,27 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) if ( msg->message != WM_KEYDOWN ) bProcess = FALSE; - if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN ) + if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN ) bProcess = FALSE; - bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0; + if ( bProcess ) + { + bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0; - // WM_GETDLGCODE: if the control wants it for itself, don't process it - // (except for Ctrl-Tab combination which is always processed) - LONG lDlgCode = 0; - if ( bProcess && !bCtrlDown ) { - lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0); - } + // WM_GETDLGCODE: ask the control if it wants the key for itself, + // don't process it if it's the case (except for Ctrl-Tab/Enter + // combinations which are always processed) + LONG lDlgCode = 0; + if ( !bCtrlDown ) + { + lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0); + } + + bool bForward = TRUE, + bWindowChange = FALSE; - bool bForward = TRUE, - bWindowChange = FALSE; - if ( bProcess ) { - switch ( msg->wParam ) { + switch ( msg->wParam ) + { case VK_TAB: if ( lDlgCode & DLGC_WANTTAB ) { bProcess = FALSE; @@ -1969,36 +2038,53 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) break; case VK_RETURN: - // if there is a default button, Enter should press it - if ( !GetDefaultItem() ) { - // but if there is not it makes sense to make it work - // like a TAB - - // nothing to do - all variables are already set - - break; + { + if ( lDlgCode & DLGC_WANTMESSAGE ) + { + // control wants to process Enter itself, don't + // call IsDialogMessage() which would interpret + // it + return FALSE; + } +#ifndef __WIN16__ + wxButton *btnDefault = GetDefaultItem(); + if ( btnDefault && !bCtrlDown ) + { + // if there is a default button, Enter should + // press it + (void)::SendMessage((HWND)btnDefault->GetHWND(), + BM_CLICK, 0, 0); + return TRUE; + } + // else: but if there is 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. +#endif } - //else: fall through and don't process the message + break; default: bProcess = FALSE; } - } - if ( bProcess ) { - wxNavigationKeyEvent event; - event.SetDirection(bForward); - event.SetWindowChange(bWindowChange); - event.SetEventObject(this); + if ( bProcess ) + { + wxNavigationKeyEvent event; + event.SetDirection(bForward); + event.SetWindowChange(bWindowChange); + event.SetEventObject(this); - if ( GetEventHandler()->ProcessEvent(event) ) - return TRUE; + if ( GetEventHandler()->ProcessEvent(event) ) + return TRUE; + } } - return ::IsDialogMessage((HWND)GetHWND(), msg) != 0; + if ( ::IsDialogMessage((HWND)GetHWND(), msg) ) + return TRUE; } #if wxUSE_TOOLTIPS - else if ( m_tooltip ) { + if ( m_tooltip ) + { // relay mouse move events to the tooltip control MSG *msg = (MSG *)pMsg; if ( msg->message == WM_MOUSEMOVE ) @@ -2221,7 +2307,6 @@ void wxWindow::MSWOnMButtonDown(int x, int y, WXUINT flags) void wxWindow::MSWOnMButtonUp(int x, int y, WXUINT flags) { - //wxDebugMsg("MButtonUp\n") ; wxMouseEvent event(wxEVT_MIDDLE_UP); event.m_x = x; event.m_y = y; @@ -2401,7 +2486,7 @@ void wxWindow::MSWOnMouseLeave(int x, int y, WXUINT flags) GetEventHandler()->ProcessEvent(event); } -void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) +bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) { int id; bool tempControlDown = FALSE; @@ -2463,12 +2548,16 @@ void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) event.m_x = pt.x; event.m_y = pt.y; - if (!GetEventHandler()->ProcessEvent(event)) - Default(); + if (GetEventHandler()->ProcessEvent(event)) + return TRUE; + else + return FALSE; } + else + return FALSE; } -void wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII) +bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII) { int id; @@ -2497,12 +2586,19 @@ void wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII) event.m_x = pt.x; event.m_y = pt.y; - if (!GetEventHandler()->ProcessEvent(event)) - Default(); + if (GetEventHandler()->ProcessEvent(event)) + { + return TRUE; + } + else return FALSE; + } + else + { + return FALSE; } } -void wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII) +bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII) { int id; @@ -2531,9 +2627,13 @@ void wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII) event.m_x = pt.x; event.m_y = pt.y; - if (!GetEventHandler()->ProcessEvent(event)) - Default(); + if (GetEventHandler()->ProcessEvent(event)) + return TRUE; + else + return FALSE; } + else + return FALSE; } void wxWindow::MSWOnJoyDown(int joystick, int x, int y, WXUINT flags) @@ -3584,7 +3684,7 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) // 5) If this isn't a Win95 app, and we are using CTL3D, remove border // effects from extended style -#if CTL3D +#if wxUSE_CTL3D if ( *want3D ) nativeBorder = FALSE; #endif @@ -3594,7 +3694,7 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) // If we want 3D, but haven't specified a border here, // apply the default border style specified. // TODO what about non-Win95 WIN32? Does it have borders? -#if defined(__WIN95__) && !CTL3D +#if defined(__WIN95__) && !wxUSE_CTL3D if (defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) || (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) )) exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ; @@ -3605,25 +3705,13 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) void wxWindow::OnChar(wxKeyEvent& event) { -#if 0 - if ( event.KeyCode() == WXK_TAB ) { - // propagate the TABs to the parent - it's up to it to decide what - // to do with it - wxWindow *parent = GetParent(); - if ( parent ) { - if ( parent->GetEventHandler()->ProcessEvent(event) ) - return; - } - } -#endif // 0 - bool isVirtual; int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual); if ( id == -1 ) id= m_lastWParam; - if ( !event.ControlDown() ) + if ( !event.ControlDown() ) // Why this test? (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam); } @@ -3650,7 +3738,7 @@ bool wxWindow::TransferDataToWindow() if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferToWindow() ) { - wxMessageBox("Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION); + wxLogError(_("Could not transfer data to window")); return FALSE; } @@ -4032,16 +4120,17 @@ void wxWindow::SetConstraintSizes(bool recurse) winName = "unnamed"; else winName = GetName(); - wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName); + wxLogDebug("Constraint(s) not satisfied for window of type %s, name %s:", + (const char *)windowClass, (const char *)winName); if (!constr->left.GetDone()) - wxDebugMsg(" unsatisfied 'left' constraint.\n"); + wxLogDebug(" unsatisfied 'left' constraint."); if (!constr->right.GetDone()) - wxDebugMsg(" unsatisfied 'right' constraint.\n"); + wxLogDebug(" unsatisfied 'right' constraint."); if (!constr->width.GetDone()) - wxDebugMsg(" unsatisfied 'width' constraint.\n"); + wxLogDebug(" unsatisfied 'width' constraint."); if (!constr->height.GetDone()) - wxDebugMsg(" unsatisfied 'height' constraint.\n"); - wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n"); + wxLogDebug(" unsatisfied 'height' constraint."); + wxLogDebug("Please check constraints: try adding AsIs() constraints.\n"); } if (recurse) @@ -4175,7 +4264,9 @@ bool wxWindow::Close(bool force) { wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId); event.SetEventObject(this); +#if WXWIN_COMPATIBILITY event.SetForce(force); +#endif event.SetCanVeto(!force); return (GetEventHandler()->ProcessEvent(event) && !event.GetVeto());