X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/61179e28bd7f9e29af93582326919b91549db357..3cd94a0d119ade811cd876a309cfe6d28b5c36dd:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 5dc59b9efb..aba22e63b4 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -312,10 +312,8 @@ void wxWindowMSW::Init() InitBase(); // MSW specific - m_doubleClickAllowed = 0; - m_isBeingDeleted = FALSE; - m_oldWndProc = 0; + m_oldWndProc = NULL; m_useCtl3D = FALSE; m_mouseInWindow = FALSE; m_lastKeydownProcessed = FALSE; @@ -993,7 +991,10 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) } else { - // don't bother restoring it neither + // don't bother restoring it neither: this also makes it easy to + // implement IsOfStandardClass() method which returns TRUE for the + // standard controls and FALSE for the wxWindows own windows as it can + // simply check m_oldWndProc m_oldWndProc = NULL; } } @@ -1164,12 +1165,15 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const break; } + // wxUniv doesn't use Windows dialog navigation functions at all +#ifndef __WXUNIVERSAL__ // to make the dialog navigation work with the nested panels we must - // use this style - if ( flags & wxTAB_TRAVERSAL ) + // use this style (top level windows such as dialogs don't need it) + if ( (flags & wxTAB_TRAVERSAL) && !IsTopLevel() ) { *exstyle |= WS_EX_CONTROLPARENT; } +#endif // __WXUNIVERSAL__ } return style; @@ -1912,14 +1916,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) // here we try to do all the job which ::IsDialogMessage() usually does // internally #if 1 - bool bProcess = TRUE; - if ( msg->message != WM_KEYDOWN ) - bProcess = FALSE; - - if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - bProcess = FALSE; - - if ( bProcess ) + if ( msg->message == WM_KEYDOWN ) { bool bCtrlDown = wxIsCtrlDown(); bool bShiftDown = wxIsShiftDown(); @@ -1936,6 +1933,8 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) bool bForward = TRUE, bWindowChange = FALSE; + // should we process this message specially? + bool bProcess = TRUE; switch ( msg->wParam ) { case VK_TAB: @@ -2080,9 +2079,9 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) // place edit control from being closed with Escape in a dialog if ( msg->message != WM_KEYDOWN || msg->wParam != VK_ESCAPE ) { - // ::IsDialogMessage() can enter in an infinite loop when - // WS_EX_CONTROLPARENT is specified and the currently focused - // window is disabled or hidden, so don't call it in this case + // ::IsDialogMessage() can enter in an infinite loop when the + // currently focused window is disabled or hidden and its parent + // has WS_EX_CONTROLPARENT style, so don't call it in this case bool canSafelyCallIsDlgMsg = TRUE; HWND hwndFocus = ::GetFocus(); @@ -2097,6 +2096,14 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) break; } + if ( !(::GetWindowLong(hwndFocus, GWL_STYLE) & WS_CHILD) ) + { + // it's a top level window, don't go further -- e.g. even + // if the parent of a dialog is disabled, this doesn't + // break navigation inside the dialog + break; + } + hwndFocus = ::GetParent(hwndFocus); } @@ -2439,28 +2446,36 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam break; } - if (!processed) + if ( processed ) + break; + #endif // __WXMICROWIN__ - { - // VZ: why do we need it here? DefWindowProc() is supposed - // to do this for us anyhow - if ( message == WM_LBUTTONDOWN && AcceptsFocus() ) - SetFocus(); + // VZ: if you find a situation when this is needed, tell + // me about it, do *not* uncomment this code as it + // causes other strange problems +#if 0 + if ( message == WM_LBUTTONDOWN && AcceptsFocus() ) + SetFocus(); +#endif // 0 - int x = GET_X_LPARAM(lParam), - y = GET_Y_LPARAM(lParam); + int x = GET_X_LPARAM(lParam), + y = GET_Y_LPARAM(lParam); - // redirect the event to a static control if necessary - if (this == GetCapture()) - { - processed = HandleMouseEvent(message, x, y, wParam); - } - else - { - wxWindowMSW *win = FindWindowForMouseEvent(this, &x, &y); //TW:REQ:Univ - processed = win->HandleMouseEvent(message, x, y, wParam); - } + // redirect the event to a static control if necessary by + // finding one under mouse + wxWindowMSW *win; + if ( GetCapture() == this ) + { + // but don't do it if the mouse is captured by this window + // because then it should really get this event itself + win = this; } + else + { + win = FindWindowForMouseEvent(this, &x, &y); + } + + processed = win->HandleMouseEvent(message, x, y, wParam); } break; @@ -2524,11 +2539,19 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam #endif // defined(WM_DRAWITEM) case WM_GETDLGCODE: - if ( GetWindowStyleFlag() & wxWANTS_CHARS ) + if ( !IsOfStandardClass() ) { - // want everything: i.e. all keys and WM_CHAR message - rc.result = DLGC_WANTARROWS | DLGC_WANTCHARS | - DLGC_WANTTAB | DLGC_WANTMESSAGE; + // we always want to get the char events + rc.result = DLGC_WANTCHARS; + + if ( GetWindowStyleFlag() & wxWANTS_CHARS ) + { + // in fact, we want everything + rc.result |= DLGC_WANTARROWS | + DLGC_WANTTAB | + DLGC_WANTALLKEYS; + } + processed = TRUE; } //else: get the dlg code from the DefWindowProc() @@ -2932,7 +2955,7 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, WXHWND wxWindowMSW::MSWGetParent() const { - return m_parent ? m_parent->GetHWND() : NULL; + return m_parent ? m_parent->GetHWND() : WXHWND(NULL); } bool wxWindowMSW::MSWCreate(const wxChar *wclass, @@ -2948,20 +2971,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, // controlId is menu handle for the top level windows, so set it to 0 // unless we're creating a child window - int controlId; - if ( style & WS_CHILD ) - { - controlId = GetId(); - - if ( GetWindowStyleFlag() & wxCLIP_SIBLINGS ) - { - style |= WS_CLIPSIBLINGS; - } - } - else // !child - { - controlId = 0; - } + int controlId = style & WS_CHILD ? GetId() : 0; // for each class "Foo" we have we also have "FooNR" ("no repaint") class // which is the same but without CS_[HV]REDRAW class styles so using it @@ -3011,7 +3021,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, // --------------------------------------------------------------------------- #ifdef __WIN95__ -// FIXME: VZ: I'm not sure at all that the order of processing is correct + bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { #ifndef __WXMICROWIN__ @@ -3019,12 +3029,19 @@ bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) HWND hWnd = hdr->hwndFrom; wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd); - // is this one of our windows? + // if the control is one of our windows, let it handle the message itself if ( win ) { return win->MSWOnNotify(idCtrl, lParam, result); } + // VZ: why did we do it? normally this is unnecessary and, besides, it + // breaks the message processing for the toolbars because the tooltip + // notifications were being forwarded to the toolbar child controls + // (if it had any) before being passed to the toolbar itself, so in my + // example the tooltip for the combobox was always shown instead of the + // correct button tooltips +#if 0 // try all our children wxWindowList::Node *node = GetChildren().GetFirst(); while ( node ) @@ -3037,32 +3054,92 @@ bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) node = node->GetNext(); } +#endif // 0 - // finally try this window too (catches toolbar case) + // by default, handle it ourselves return MSWOnNotify(idCtrl, lParam, result); #else // __WXMICROWIN__ return FALSE; #endif } +#if wxUSE_TOOLTIPS + +bool wxWindowMSW::HandleTooltipNotify(WXUINT code, + WXLPARAM lParam, + const wxString& ttip) +{ + // I don't know why it happens, but the versions of comctl32.dll starting + // from 4.70 sometimes send TTN_NEEDTEXTW even to ANSI programs (normally, + // this message is supposed to be sent to Unicode programs only) -- hence + // we need to handle it as well, otherwise no tooltips will be shown in + // this case + + if ( !(code == TTN_NEEDTEXTA || code == TTN_NEEDTEXTW) || ttip.empty() ) + { + // not a tooltip message or no tooltip to show anyhow + return FALSE; + } + + LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam; + + if ( code == TTN_NEEDTEXTA ) + { + ttText->lpszText = (wxChar *)ttip.c_str(); + } + else + { +#if wxUSE_UNICODE + ttText->lpszText = (wxChar *)ttip.c_str(); +#else // !Unicode + size_t lenAnsi = ttip.length(); + + // some compilers (MetroWerks and Cygwin) don't like calling mbstowcs + // with NULL argument + #if defined( __MWERKS__ ) || defined( __CYGWIN__ ) + size_t lenUnicode = 2*lenAnsi; + #else + size_t lenUnicode = mbstowcs(NULL, ttip, lenAnsi); + #endif + + // using the pointer of right type avoids us doing all sorts of + // pointer arithmetics ourselves + wchar_t *dst = (wchar_t *)ttText->szText, + *pwz = new wchar_t[lenUnicode + 1]; + mbstowcs(pwz, ttip, lenAnsi + 1); + memcpy(dst, pwz, lenUnicode*sizeof(wchar_t)); + + // put the terminating wide NUL + dst[lenUnicode] = L'\0'; + + delete [] pwz; +#endif // Unicode/!Unicode + } + + return TRUE; +} + +#endif // wxUSE_TOOLTIPS + bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl), - WXLPARAM lParam, - WXLPARAM* WXUNUSED(result)) + WXLPARAM lParam, + WXLPARAM* WXUNUSED(result)) { #if wxUSE_TOOLTIPS - NMHDR* hdr = (NMHDR *)lParam; - if ( (int)hdr->code == TTN_NEEDTEXT && m_tooltip ) + if ( m_tooltip ) { - TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam; - ttt->lpszText = (wxChar *)m_tooltip->GetTip().c_str(); - - // processed - return TRUE; + NMHDR* hdr = (NMHDR *)lParam; + if ( HandleTooltipNotify(hdr->code, lParam, m_tooltip->GetTip())) + { + // processed + return TRUE; + } } #endif // wxUSE_TOOLTIPS return FALSE; } + #endif // __WIN95__ // --------------------------------------------------------------------------- @@ -3123,7 +3200,7 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate) { // there is no need to do anything for the top level windows const wxWindow *parent = GetParent(); - if ( parent && !parent->IsTopLevel() ) + while ( parent && !parent->IsTopLevel() ) { LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE); if ( !(exStyle & WS_EX_CONTROLPARENT) ) @@ -3132,6 +3209,8 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate) ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE, exStyle | WS_EX_CONTROLPARENT); } + + parent = parent->GetParent(); } } @@ -3537,7 +3616,7 @@ bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange) if ( hWndPalChange != GetHWND() ) { // check to see if we our our parents have a custom palette - wxWindow *win = this; + wxWindowMSW *win = this; while ( win && !win->HasCustomPalette() ) { win = win->GetParent(); @@ -3586,7 +3665,7 @@ bool wxWindowMSW::HandleQueryNewPalette() #if wxUSE_PALETTE // check to see if we our our parents have a custom palette - wxWindow *win = this; + wxWindowMSW *win = this; while (!win->HasCustomPalette() && win->GetParent()) win = win->GetParent(); if (win->HasCustomPalette()) { /* realize the palette to see whether redrawing is needed */