X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1e6feb95a79834836e88143b15d9f424ebe79621..67e49a98bbba6793cf1e344477bee9e46d4d5c71:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 31ef0ea340..59e4c2a5f1 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -39,7 +39,6 @@ #include "wx/dcclient.h" #include "wx/utils.h" #include "wx/app.h" - #include "wx/panel.h" #include "wx/layout.h" #include "wx/dialog.h" #include "wx/frame.h" @@ -47,8 +46,7 @@ #include "wx/button.h" #include "wx/msgdlg.h" #include "wx/settings.h" - - #include + #include "wx/statbox.h" #endif #if wxUSE_OWNER_DRAWN @@ -84,7 +82,7 @@ #include -#if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__) +#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__)) || defined(__CYGWIN10__) #include #include #endif @@ -93,11 +91,11 @@ #include #endif -#if (!defined(__GNUWIN32_OLD__) && !defined(__TWIN32__)) || defined(__CYGWIN10__) +#if (!defined(__GNUWIN32_OLD__) && !defined(__TWIN32__) && !defined(__WXMICROWIN__)) || defined(__CYGWIN10__) #ifdef __WIN95__ #include #endif -#else // broken compiler +#elif !defined(__WXMICROWIN__) // broken compiler #ifndef __TWIN32__ #include "wx/msw/gnuwin32/extra.h" #endif @@ -132,7 +130,6 @@ extern MSG s_currentMsg; wxMenu *wxCurrentPopupMenu = NULL; #endif // wxUSE_MENUS_NATIVE -extern wxList WXDLLEXPORT wxPendingDelete; extern const wxChar *wxCanvasClassName; // --------------------------------------------------------------------------- @@ -159,15 +156,30 @@ static void TranslateKbdEventToMouse(wxWindowMSW *win, // get the text metrics for the current font static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win); -// check if the mouse is in the window or its child -static bool IsMouseInWindow(HWND hwnd); +// wrapper around BringWindowToTop() API +static inline void wxBringWindowToTop(HWND hwnd) +{ +#ifdef __WXMICROWIN__ + // It seems that MicroWindows brings the _parent_ of the window to the top, + // which can be the wrong one. + + // activate (set focus to) specified window + ::SetFocus(hwnd); + + // raise top level parent to top of z order + ::SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); +#else // !__WXMICROWIN__ + if ( !::BringWindowToTop(hwnd) ) + { + wxLogLastError(_T("BringWindowToTop")); + } +#endif // __WXMICROWIN__/!__WXMICROWIN__ +} // --------------------------------------------------------------------------- // event tables // --------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) - // in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu() // method #ifdef __WXUNIVERSAL__ @@ -181,7 +193,6 @@ BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase) EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged) EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog) EVT_IDLE(wxWindowMSW::OnIdle) - EVT_SET_FOCUS(wxWindowMSW::OnSetFocus) END_EVENT_TABLE() // =========================================================================== @@ -196,7 +207,7 @@ END_EVENT_TABLE() wxWindow *wxWindowMSW::FindItem(long id) const { #if wxUSE_CONTROLS - wxControl *item = wxDynamicThisCast(this, wxControl); + wxControl *item = wxDynamicCastThis(wxControl); if ( item ) { // is it we or one of our "internal" children? @@ -356,6 +367,17 @@ bool wxWindowMSW::Create(wxWindow *parent, { wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); +#if wxUSE_STATBOX + // wxGTK doesn't allow to create controls with static box as the parent so + // this will result in a crash when the program is ported to wxGTK - warn + // about it + // + // the correct solution is to create the controls as siblings of the + // static box + wxASSERT_MSG( !wxDynamicCastThis(wxStaticBox), + _T("wxStaticBox can't be used as a window parent!") ); +#endif // wxUSE_STATBOX + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) return FALSE; @@ -423,12 +445,19 @@ void wxWindowMSW::SetFocus() HWND hWnd = GetHwnd(); wxCHECK_RET( hWnd, _T("can't set focus to invalid window") ); +#ifndef __WXMICROWIN__ ::SetLastError(0); +#endif if ( !::SetFocus(hWnd) ) { // was there really an error? +#ifndef __WXMICROWIN__ DWORD dwRes = ::GetLastError(); +#else + + DWORD dwRes = 0; +#endif if ( dwRes ) { wxLogApiError(_T("SetFocus"), dwRes); @@ -491,7 +520,7 @@ bool wxWindowMSW::Show(bool show) if ( show ) { - BringWindowToTop(hWnd); + wxBringWindowToTop(hWnd); } return TRUE; @@ -500,11 +529,7 @@ bool wxWindowMSW::Show(bool show) // Raise the window to the top of the Z order void wxWindowMSW::Raise() { -#ifdef __WIN16__ - ::BringWindowToTop(GetHwnd()); -#else // Win32 - ::SetForegroundWindow(GetHwnd()); -#endif + wxBringWindowToTop(GetHwnd()); } // Lower the window to the bottom of the Z order @@ -732,6 +757,15 @@ int wxWindowMSW::GetScrollPage(int orient) const #endif // WXWIN_COMPATIBILITY +inline int GetScrollPosition(HWND hWnd, int wOrient) +{ +#ifdef __WXMICROWIN__ + return ::GetScrollPosWX(hWnd, wOrient); +#else + return ::GetScrollPos(hWnd, wOrient); +#endif +} + int wxWindowMSW::GetScrollPos(int orient) const { int wOrient; @@ -739,13 +773,11 @@ int wxWindowMSW::GetScrollPos(int orient) const wOrient = SB_HORZ; else wOrient = SB_VERT; + HWND hWnd = GetHwnd(); - if ( hWnd ) - { - return ::GetScrollPos(hWnd, wOrient); - } - else - return 0; + wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") ); + + return GetScrollPosition(hWnd, wOrient); } // This now returns the whole range, not just the number @@ -898,6 +930,46 @@ void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect) ::ScrollWindow(GetHwnd(), dx, dy, prect ? &rect : NULL, NULL); } +static bool ScrollVertically(HWND hwnd, int kind, int count) +{ + int posStart = GetScrollPosition(hwnd, SB_VERT); + + int pos = posStart; + for ( int n = 0; n < count; n++ ) + { + ::SendMessage(hwnd, WM_VSCROLL, kind, 0); + + int posNew = GetScrollPosition(hwnd, SB_VERT); + if ( posNew == pos ) + { + // don't bother to continue, we're already at top/bottom + break; + } + + pos = posNew; + } + + return pos != posStart; +} + +bool wxWindowMSW::ScrollLines(int lines) +{ + bool down = lines > 0; + + return ScrollVertically(GetHwnd(), + down ? SB_LINEDOWN : SB_LINEUP, + down ? lines : -lines); +} + +bool wxWindowMSW::ScrollPages(int pages) +{ + bool down = pages > 0; + + return ScrollVertically(GetHwnd(), + down ? SB_PAGEDOWN : SB_PAGEUP, + down ? pages : -pages); +} + // --------------------------------------------------------------------------- // subclassing // --------------------------------------------------------------------------- @@ -912,6 +984,9 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) wxAssociateWinWithHandle(hwnd, this); m_oldWndProc = (WXFARPROC) GetWindowLong(hwnd, GWL_WNDPROC); + + wxASSERT( (WXFARPROC) m_oldWndProc != (WXFARPROC) wxWndProc ); + SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc); } @@ -1149,6 +1224,25 @@ void wxWindowMSW::Clear() dc.Clear(); } +static inline void SendSetRedraw(HWND hwnd, bool on) +{ + ::SendMessage(hwnd, WM_SETREDRAW, (WPARAM)on, 0); +} + +void wxWindowMSW::Freeze() +{ + SendSetRedraw(GetHwnd(), FALSE); +} + +void wxWindowMSW::Thaw() +{ + SendSetRedraw(GetHwnd(), TRUE); + + // we need to refresh everything or otherwise he invalidated area is not + // repainted + Refresh(); +} + void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect) { HWND hWnd = GetHwnd(); @@ -1176,7 +1270,7 @@ void wxWindowMSW::Update() wxLogLastError(_T("UpdateWindow")); } -#ifdef __WIN32__ +#if defined(__WIN32__) && !defined(__WXMICROWIN__) // just calling UpdateWindow() is not enough, what we did in our WM_PAINT // handler needs to be really drawn right now (void)::GdiFlush(); @@ -1460,24 +1554,6 @@ wxPoint wxWindowMSW::GetClientAreaOrigin() const return wxPoint(0, 0); } -// Makes an adjustment to the window position (for example, a frame that has -// a toolbar that it manages itself). -void wxWindowMSW::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) -{ - // don't do it for the dialogs/frames - they float independently of their - // parent - if ( !IsTopLevel() ) - { - wxWindow *parent = GetParent(); - if ( !(sizeFlags & wxSIZE_NO_ADJUSTMENTS) && parent ) - { - wxPoint pt(parent->GetClientAreaOrigin()); - x += pt.x; - y += pt.y; - } - } -} - // --------------------------------------------------------------------------- // text metrics // --------------------------------------------------------------------------- @@ -1739,18 +1815,13 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) bProcess = FALSE; } -#if wxUSE_BUTTON + // FIXME: this should be handled by + // wxNavigationKeyEvent handler and not here!! else { - wxPanel *panel = wxDynamicThisCast(this, wxPanel); - wxButton *btn = NULL; - if ( panel ) - { - // panel may have a default button which should - // be activated by Enter - btn = panel->GetDefaultItem(); - } - +#if wxUSE_BUTTON + wxButton *btn = wxDynamicCast(GetDefaultItem(), + wxButton); if ( btn && btn->IsEnabled() ) { // if we do have a default button, do press it @@ -1758,11 +1829,15 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) 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. - } + else // no default button #endif // wxUSE_BUTTON + { + // no special function for enter and don't even + // let IsDialogMessage() have it: it seems to + // do something really strange with it + return FALSE; + } + } } break; @@ -1779,20 +1854,11 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) if ( GetEventHandler()->ProcessEvent(event) ) { -#if wxUSE_BUTTON - wxButton *btn = wxDynamicCast(FindFocus(), wxButton); - if ( btn ) - { - // the button which has focus should be default - btn->SetDefault(); - } -#endif // wxUSE_BUTTON - return TRUE; } } } -#else +#else // 0 // let ::IsDialogMessage() do almost everything and handle just the // things it doesn't here: Ctrl-TAB for switching notebook pages if ( msg->message == WM_KEYDOWN ) @@ -1820,7 +1886,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) } } } -#endif // 0 +#endif // 1/0 if ( ::IsDialogMessage(GetHwnd(), msg) ) { @@ -1852,6 +1918,12 @@ bool wxWindowMSW::MSWTranslateMessage(WXMSG* pMsg) #endif // wxUSE_ACCEL } +bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* pMsg) +{ + // preprocess all messages by default + return TRUE; +} + // --------------------------------------------------------------------------- // message params unpackers (different for Win16 and Win32) // --------------------------------------------------------------------------- @@ -1885,9 +1957,11 @@ void wxWindowMSW::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam, void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam, WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd) { +#ifndef __WXMICROWIN__ *nCtlColor = CTLCOLOR_BTN; *hwnd = (WXHWND)lParam; *hdc = (WXHDC)wParam; +#endif } void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, @@ -2030,7 +2104,11 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam break; case WM_DESTROY: - processed = HandleDestroy(); + // never set processed to TRUE and *always* pass WM_DESTROY to + // DefWindowProc() as Windows may do some internal cleanup when + // processing it and failing to pass the message along may cause + // memory and resource leaks! + (void)HandleDestroy(); break; case WM_MOVE: @@ -2065,21 +2143,11 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam } break; -#ifdef __WXUNIVERSAL__ +#ifndef __WXMICROWIN__ case WM_ACTIVATEAPP: wxTheApp->SetActive(wParam != 0, FindFocus()); break; - - case WM_NCHITTEST: - // we shouldn't allow the windows which don't want to get focus to - // get it - if ( !AcceptsFocus() ) - { - rc.result = HTTRANSPARENT; - processed = TRUE; - } - break; -#endif // __WXUNIVERSAL__ +#endif case WM_ACTIVATE: { @@ -2127,12 +2195,6 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam #endif case WM_LBUTTONDOWN: - // set focus to this window - if (AcceptsFocus()) - SetFocus(); - - // fall through - case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: @@ -2141,12 +2203,70 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDBLCLK: - processed = HandleMouseEvent(message, + { + processed = FALSE; +#ifdef __WXMICROWIN__ + // MicroWindows seems to ignore the fact that a window is + // disabled. So catch mouse events and throw them away if + // necessary. + wxWindowMSW* win = this; + while (win) + { + if (!win->IsEnabled()) + { + processed = TRUE; + break; + } + win = win->GetParent(); + if (win && win->IsTopLevel()) + break; + } +#endif // __WXMICROWIN__ + if (!processed) + { + if (message == WM_LBUTTONDOWN && AcceptsFocus()) + SetFocus(); + processed = HandleMouseEvent(message, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), - wParam); - break; + wParam); + } + break; + } + +#ifdef __WXMICROWIN__ + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONUP: + case WM_NCLBUTTONDBLCLK: + case WM_NCRBUTTONDOWN: + case WM_NCRBUTTONUP: + case WM_NCRBUTTONDBLCLK: +#if 0 + case WM_NCMBUTTONDOWN: + case WM_NCMBUTTONUP: + case WM_NCMBUTTONDBLCLK: +#endif + { + // MicroWindows seems to ignore the fact that a window + // is disabled. So catch mouse events and throw them away if necessary. + processed = FALSE; + wxWindowMSW* win = this; + while (win) + { + if (!win->IsEnabled()) + { + processed = TRUE; + break; + } + win = win->GetParent(); + if (win && win->IsTopLevel()) + break; + } + break; + } +#endif // __WXMICROWIN__ +#ifdef MM_JOY1MOVE case MM_JOY1MOVE: case MM_JOY2MOVE: case MM_JOY1ZMOVE: @@ -2160,6 +2280,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam GET_Y_LPARAM(lParam), wParam); break; +#endif // __WXMICROWIN__ case WM_SYSCOMMAND: processed = HandleSysCommand(wParam, lParam); @@ -2182,6 +2303,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam #endif // Win95 // for these messages we must return TRUE if process the message +#ifdef WM_DRAWITEM case WM_DRAWITEM: case WM_MEASUREITEM: { @@ -2201,6 +2323,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam rc.result = TRUE; } break; +#endif // defined(WM_DRAWITEM) case WM_GETDLGCODE: if ( m_lDlgCode ) @@ -2309,7 +2432,8 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam break; // CTLCOLOR messages are sent by children to query the parent for their - // colors + // colors#ifndef __WXMICROWIN__ +#ifndef __WXMICROWIN__ #ifdef __WIN32__ case WM_CTLCOLORMSGBOX: case WM_CTLCOLOREDIT: @@ -2336,6 +2460,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam lParam); } break; +#endif // !__WXMICROWIN__ // the return value for this message is ignored case WM_SYSCOLORCHANGE: @@ -2399,14 +2524,14 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam } break; -#ifdef __WIN32__ +#if defined(__WIN32__) && defined(WM_HELP) case WM_HELP: { HELPINFO* info = (HELPINFO*) lParam; // Don't yet process menu help events, just windows if (info->iContextType == HELPINFO_WINDOW) { - wxWindow* subjectOfHelp = this; + wxWindowMSW* subjectOfHelp = this; bool eventProcessed = FALSE; while (subjectOfHelp && !eventProcessed) { @@ -2447,6 +2572,18 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam } break; #endif // __WIN32__ + +#ifdef __WXUNIVERSAL__ + case WM_NCHITTEST: + // we shouldn't allow the windows which don't want to get focus to + // get it + if ( !AcceptsFocus() ) + { + rc.result = HTTRANSPARENT; + processed = TRUE; + } + break; +#endif // __WXUNIVERSAL__ } if ( !processed ) @@ -2537,6 +2674,7 @@ void wxWindowMSW::MSWDestroyWindow() void wxWindowMSW::MSWDetachWindowMenu() { +#ifndef __WXUNIVERSAL__ if ( m_hMenu ) { wxChar buf[1024]; @@ -2563,6 +2701,7 @@ void wxWindowMSW::MSWDetachWindowMenu() } } } +#endif } bool wxWindowMSW::MSWCreate(int id, @@ -2636,6 +2775,7 @@ bool wxWindowMSW::MSWCreate(int id, wxWndHook = this; +#ifndef __WXMICROWIN__ if ( dialog_template ) { // for the dialogs without wxDIALOG_NO_PARENT style, use the top level @@ -2709,8 +2849,10 @@ bool wxWindowMSW::MSWCreate(int id, { wxLogLastError(wxT("MoveWindow")); } + } else // creating a normal window, not a dialog +#endif // !__WXMICROWIN__ { int controlId = 0; if ( style & WS_CHILD ) @@ -2781,6 +2923,7 @@ bool wxWindowMSW::MSWCreate(int id, // 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__ LPNMHDR hdr = (LPNMHDR)lParam; HWND hWnd = hdr->hwndFrom; wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd); @@ -2806,6 +2949,9 @@ bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // finally try this window too (catches toolbar case) return MSWOnNotify(idCtrl, lParam, result); +#else // __WXMICROWIN__ + return FALSE; +#endif } bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl), @@ -2857,15 +3003,16 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff) if ( !endSession ) return FALSE; + // only send once + if ( (this != wxTheApp->GetTopWindow()) ) + return FALSE; + wxCloseEvent event(wxEVT_END_SESSION, -1); event.SetEventObject(wxTheApp); event.SetCanVeto(FALSE); event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) ); - if ( (this == wxTheApp->GetTopWindow()) && // Only send once - wxTheApp->ProcessEvent(event)) - { - } - return TRUE; + + return wxTheApp->ProcessEvent(event); } // --------------------------------------------------------------------------- @@ -2907,33 +3054,6 @@ bool wxWindowMSW::HandleDestroy() // activation/focus // --------------------------------------------------------------------------- -void wxWindowMSW::OnSetFocus(wxFocusEvent& event) -{ - // panel wants to track the window which was the last to have focus in it, - // so we want to set ourselves as the window which last had focus - // - // notice that it's also important to do it upwards the tree becaus - // otherwise when the top level panel gets focus, it won't set it back to - // us, but to some other sibling - wxWindow *win = (wxWindow *)this; - while ( win ) - { - wxWindow *parent = win->GetParent(); - wxPanel *panel = wxDynamicCast(parent, wxPanel); - if ( panel ) - { - panel->SetLastFocus(win); - } - - win = parent; - } - - wxLogTrace(_T("focus"), _T("%s (0x%08x) gets focus"), - GetClassInfo()->GetClassName(), GetHandle()); - - event.Skip(); -} - bool wxWindowMSW::HandleActivate(int state, bool WXUNUSED(minimized), WXHWND WXUNUSED(activate)) @@ -2948,6 +3068,11 @@ bool wxWindowMSW::HandleActivate(int state, bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) { + // notify the parent keeping track of focus for the kbd navigation + // purposes that we got it + wxChildFocusEvent eventFocus((wxWindow *)this); + (void)GetEventHandler()->ProcessEvent(eventFocus); + #if wxUSE_CARET // Deal with caret if ( m_caret ) @@ -2956,6 +3081,15 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) } #endif // wxUSE_CARET +#if wxUSE_TEXTCTRL + // If it's a wxTextCtrl don't send the event as it will be done + // after the control gets to process it from EN_FOCUS handler + if ( wxDynamicCastThis(wxTextCtrl) ) + { + return FALSE; + } +#endif // wxUSE_TEXTCTRL + wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); event.SetEventObject(this); @@ -2975,6 +3109,16 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd) } #endif // wxUSE_CARET +#if wxUSE_TEXTCTRL + // If it's a wxTextCtrl don't send the event as it will be done + // after the control gets to process it. + wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl); + if ( ctrl ) + { + return FALSE; + } +#endif + wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId); event.SetEventObject(this); @@ -3006,6 +3150,7 @@ bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus)) bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) { +#ifndef __WXMICROWIN__ HDROP hFilesInfo = (HDROP) wParam; POINT dropPoint; DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint); @@ -3030,19 +3175,24 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files); event.m_eventObject = this; - event.m_pos.x = dropPoint.x; event.m_pos.x = dropPoint.y; + event.m_pos.x = dropPoint.x; + event.m_pos.y = dropPoint.y; bool rc = GetEventHandler()->ProcessEvent(event); delete[] files; return rc; +#else // __WXMICROWIN__ + return FALSE; +#endif } bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd), short nHitTest, int WXUNUSED(mouseMsg)) { +#ifndef __WXMICROWIN__ // the logic is as follows: // -1. don't set cursor for non client area, including but not limited to // the title bar, scrollbars, &c @@ -3119,6 +3269,7 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd), // cursor set, stop here return TRUE; } +#endif // __WXMICROWIN__ // pass up the window chain return FALSE; @@ -3134,9 +3285,9 @@ bool wxWindowMSW::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct) #if wxUSE_MENUS_NATIVE // is it a menu item? - if ( id == 0 ) + DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct; + if ( id == 0 && pDrawStruct->CtlType == ODT_MENU ) { - DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct; wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData); wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); @@ -3175,9 +3326,9 @@ bool wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) { #if wxUSE_OWNER_DRAWN // is it a menu item? - if ( id == 0 ) + MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct; + if ( id == 0 && pMeasureStruct->CtlType == ODT_MENU ) { - MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct; wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData); wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE ); @@ -3215,6 +3366,7 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXWPARAM wParam, WXLPARAM lParam) { +#ifndef __WXMICROWIN__ WXHBRUSH hBrush = 0; if ( nCtlColor == CTLCOLOR_DLG ) @@ -3234,6 +3386,9 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, *brush = hBrush; return hBrush != 0; +#else // __WXMICROWIN__ + return FALSE; +#endif } // Define for each class of dialog and control @@ -3500,7 +3655,7 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) return GetEventHandler()->ProcessEvent(event); } -#if wxUSE_SPINCTRL +#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) else { // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND @@ -3625,7 +3780,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) } -bool wxWindow::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam) +bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam) { #if wxUSE_MOUSEWHEEL wxMouseEvent event(wxEVT_MOUSEWHEEL); @@ -3804,6 +3959,7 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam) bool wxWindowMSW::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags) { +#ifdef JOY_BUTTON1 int change = 0; if ( flags & JOY_BUTTON1CHG ) change = wxJOY_BUTTON1; @@ -3880,6 +4036,9 @@ bool wxWindowMSW::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags) event.SetEventObject(this); return GetEventHandler()->ProcessEvent(event); +#else + return FALSE; +#endif } // --------------------------------------------------------------------------- @@ -4041,14 +4200,11 @@ int wxCharCodeMSWToWX(int keySym) case VK_NUMPAD7: id = WXK_NUMPAD7; break; case VK_NUMPAD8: id = WXK_NUMPAD8; break; case VK_NUMPAD9: id = WXK_NUMPAD9; break; - case VK_MULTIPLY: id = WXK_MULTIPLY; break; - case 0xBB: // VK_OEM_PLUS - case VK_ADD: id = WXK_ADD; break; - case 0xBD: // VK_OEM_MINUS - case VK_SUBTRACT: id = WXK_SUBTRACT; break; - case 0xBE: // VK_OEM_PERIOD - case VK_DECIMAL: id = WXK_DECIMAL; break; - case VK_DIVIDE: id = WXK_DIVIDE; break; + case VK_MULTIPLY: id = WXK_NUMPAD_MULTIPLY; break; + case VK_ADD: id = WXK_NUMPAD_ADD; break; + case VK_SUBTRACT: id = WXK_NUMPAD_SUBTRACT; break; + case VK_DECIMAL: id = WXK_NUMPAD_DECIMAL; break; + case VK_DIVIDE: id = WXK_NUMPAD_DIVIDE; break; case VK_F1: id = WXK_F1; break; case VK_F2: id = WXK_F2; break; case VK_F3: id = WXK_F3; break; @@ -4118,11 +4274,11 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual) case WXK_NUMPAD7: keySym = VK_NUMPAD7; break; case WXK_NUMPAD8: keySym = VK_NUMPAD8; break; case WXK_NUMPAD9: keySym = VK_NUMPAD9; break; - case WXK_MULTIPLY: keySym = VK_MULTIPLY; break; - case WXK_ADD: keySym = VK_ADD; break; - case WXK_SUBTRACT: keySym = VK_SUBTRACT; break; - case WXK_DECIMAL: keySym = VK_DECIMAL; break; - case WXK_DIVIDE: keySym = VK_DIVIDE; break; + case WXK_NUMPAD_MULTIPLY: keySym = VK_MULTIPLY; break; + case WXK_NUMPAD_ADD: keySym = VK_ADD; break; + case WXK_NUMPAD_SUBTRACT: keySym = VK_SUBTRACT; break; + case WXK_NUMPAD_DECIMAL: keySym = VK_DECIMAL; break; + case WXK_NUMPAD_DIVIDE: keySym = VK_DIVIDE; break; case WXK_F1: keySym = VK_F1; break; case WXK_F2: keySym = VK_F2; break; case WXK_F3: keySym = VK_F3; break; @@ -4198,7 +4354,7 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd) // spin control text buddy window should be mapped to spin ctrl // itself so try it too -#if wxUSE_SPINCTRL +#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) if ( !win ) { win = wxSpinCtrl::GetSpinForTextCtrl((WXHWND)hwnd); @@ -4206,24 +4362,34 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd) #endif // wxUSE_SPINCTRL #endif // Win32 - - if ( !win ) - { - // hwnd is not a wxWindow, try its parent next below - hwnd = ::GetParent(hwnd); - } } } while ( hwnd && !win ) { - win = wxFindWinFromHandle((WXHWND)hwnd); + // this is a really ugly hack needed to avoid mistakenly returning the + // parent frame wxWindow for the find/replace modeless dialog HWND - + // this, in turn, is needed to call IsDialogMessage() from + // wxApp::ProcessMessage() as for this we must return NULL from here + // + // FIXME: this is clearly not the best way to do it but I think we'll + // need to change HWND <-> wxWindow code more heavily than I can + // do it now to fix it + if ( ::GetWindow(hwnd, GW_OWNER) ) + { + // it's a dialog box, don't go upwards + break; + } + hwnd = ::GetParent(hwnd); + win = wxFindWinFromHandle((WXHWND)hwnd); } return win; } +#ifndef __WXMICROWIN__ + // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE // in active frames and dialogs, regardless of where the focus is. static HHOOK wxTheKeyboardHook = 0; @@ -4301,6 +4467,8 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam); } +#endif // !__WXMICROWIN__ + #ifdef __WXDEBUG__ const char *wxGetMessageName(int message) {