X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6463b9f5399b8670a0c74f2f8666bc2c9f37a406..f3f0d961af5454a3544a4f4f9aced750d4641d69:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 081a98761b..94f3430ce1 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -114,52 +114,12 @@ #include "wx/msw/gnuwin32/extra.h" #endif -#if defined(__GNUG__) #include "wx/msw/missing.h" -#endif #if defined(__WXWINCE__) #include "wx/msw/wince/missing.h" #endif -// ---------------------------------------------------------------------------- -// standard constants not available with all compilers/headers -// ---------------------------------------------------------------------------- - -// This didn't appear in mingw until 2.95.2 -#ifndef SIF_TRACKPOS -#define SIF_TRACKPOS 16 -#endif - -#if wxUSE_MOUSEWHEEL - #ifndef WM_MOUSEWHEEL - #define WM_MOUSEWHEEL 0x020A - #endif - #ifndef WHEEL_DELTA - #define WHEEL_DELTA 120 - #endif - #ifndef SPI_GETWHEELSCROLLLINES - #define SPI_GETWHEELSCROLLLINES 104 - #endif -#endif // wxUSE_MOUSEWHEEL - -#ifndef VK_OEM_1 - #define VK_OEM_1 0xBA - #define VK_OEM_2 0xBF - #define VK_OEM_3 0xC0 - #define VK_OEM_4 0xDB - #define VK_OEM_5 0xDC - #define VK_OEM_6 0xDD - #define VK_OEM_7 0xDE -#endif - -#ifndef VK_OEM_COMMA - #define VK_OEM_PLUS 0xBB - #define VK_OEM_COMMA 0xBC - #define VK_OEM_MINUS 0xBD - #define VK_OEM_PERIOD 0xBE -#endif - // --------------------------------------------------------------------------- // global variables // --------------------------------------------------------------------------- @@ -1853,10 +1813,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) switch ( msg->wParam ) { case VK_TAB: - // assume that nobody wants Shift-TAB for himself - if we - // don't do it there is no easy way for a control to grab - // TABs but still let Shift-TAB work as navugation key - if ( (lDlgCode & DLGC_WANTTAB) && !bShiftDown ) { + if ( lDlgCode & DLGC_WANTTAB ) { bProcess = FALSE; } else { @@ -1880,6 +1837,25 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) bProcess = FALSE; break; + case VK_ESCAPE: + { +#if wxUSE_BUTTON + wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL), + wxButton); + if ( btn && btn->IsEnabled() ) + { + // if we do have a cancel button, do press it + btn->MSWCommand(BN_CLICKED, 0 /* unused */); + + // we consumed the message + return TRUE; + } +#endif // wxUSE_BUTTON + + bProcess = FALSE; + } + break; + case VK_RETURN: { if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown ) @@ -1993,8 +1969,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) } #endif // 1/0 - // we handle VK_ESCAPE ourselves in wxDialog::OnCharHook() and we - // shouldn't let IsDialogMessage() get it as it _always_ eats the + // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the // message even when there is no cancel button and when the message is // needed by the control itself: in particular, it prevents the tree in // place edit control from being closed with Escape in a dialog @@ -2909,8 +2884,20 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam wxPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt); - evtCtx.SetEventObject(this); - processed = GetEventHandler()->ProcessEvent(evtCtx); + + // we could have got an event from our child, reflect it back + // to it if this is the case + wxWindowMSW *win = NULL; + if ( wParam != m_hWnd ) + { + win = FindItemByHWND((WXHWND)wParam); + } + + if ( !win ) + win = this; + + evtCtx.SetEventObject(win); + processed = win->GetEventHandler()->ProcessEvent(evtCtx); } break; #endif @@ -2995,15 +2982,17 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, int& x, int& y, int& w, int& h) const { + // yes, those are just some arbitrary hardcoded numbers static const int DEFAULT_Y = 200; + static const int DEFAULT_W = 400; static const int DEFAULT_H = 250; bool nonDefault = FALSE; if ( pos.x == -1 ) { - // if set x to CW_USEDEFAULT, y parameter is ignored anyhow so we can - // just as well set it to CW_USEDEFAULT as well + // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we + // can just as well set it to CW_USEDEFAULT as well x = y = CW_USEDEFAULT; } @@ -3036,9 +3025,25 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, */ if ( size.x == -1 ) { - // as above, h is not used at all in this case anyhow - w = - h = CW_USEDEFAULT; + // we don't use CW_USEDEFAULT here for several reasons: + // + // 1. it results in huge frames on modern screens (1000*800 is not + // uncommon on my 1280*1024 screen) which is way too big for a half + // empty frame of most of wxWindows samples for example) + // + // 2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which + // the default is for whatever reason 8*8 which breaks client <-> + // window size calculations (it would be nice if it didn't, but it + // does and the simplest way to fix it seemed to change the broken + // default size anyhow) + // + // 3. there is just no advantage in doing it: with x and y it is + // possible that [future versions of] Windows position the new top + // level window in some smart way which we can't do, but we can + // guess a reasonably good size for a new window just as well + // ourselves + w = DEFAULT_W; + h = DEFAULT_H; } else { @@ -4397,7 +4402,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) { // Generate an ENTER event m_mouseInWindow = TRUE; - +#if _WIN32_WINNT >= 0x0400 #ifndef __WXWINCE__ TRACKMOUSEEVENT trackinfo; @@ -4409,7 +4414,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) // else we need _WIN32_WINNT >= 0x0400 _TrackMouseEvent(&trackinfo); #endif - +#endif wxMouseEvent event(wxEVT_ENTER_WINDOW); InitMouseEvent(event, x, y, flags); @@ -5765,54 +5770,62 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam) #endif // wxUSE_HOTKEY -// Not verified for WinCE +// Not tested under WinCE #ifndef __WXWINCE__ -/* - * wxEventFixModule (needs a better name) allows message handling to continute while a menu - * is being shown - ie, to continue processing messages from a worker thread. - * - * Code originally by Jason W. from wx-dev, reworked into a wxModule by Chris Mellon - */ -class wxEventFixModule : public wxModule { +// this class installs a message hook which really wakes up our idle processing +// each time a WM_NULL is received (wxWakeUpIdle does this), even if we're +// sitting inside a local modal loop (e.g. a menu is opened or scrollbar is +// being dragged or even inside ::MessageBox()) and so don't control message +// dispatching otherwise +class wxIdleWakeUpModule : public wxModule +{ public: - //base class virtuals - virtual bool OnInit() { - wxEventFixModule::s_hMsgHookProc = SetWindowsHookEx( - WH_GETMESSAGE, - &wxEventFixModule::MsgHookProc, - NULL, - GetCurrentThreadId()); - wxLogDebug(_T("Loaded event fix module")); - return true; - }; - virtual void OnExit() { - UnhookWindowsHookEx(wxEventFixModule::s_hMsgHookProc); + virtual bool OnInit() + { + ms_hMsgHookProc = ::SetWindowsHookEx + ( + WH_GETMESSAGE, + &wxIdleWakeUpModule::MsgHookProc, + NULL, + GetCurrentThreadId() + ); - }; - static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) { + if ( !ms_hMsgHookProc ) + { + wxLogLastError(_T("SetWindowsHookEx(WH_GETMESSAGE)")); + + return false; + } + + return true; + } + + virtual void OnExit() + { + ::UnhookWindowsHookEx(wxIdleWakeUpModule::ms_hMsgHookProc); + } + + static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) + { MSG *msg = (MSG*)lParam; - switch (msg->message) + if ( msg->message == WM_NULL ) { - case WM_NULL: - static bool bInHookProc = false; - if (!bInHookProc) - { - bInHookProc = true; - wxTheApp->ProcessPendingEvents(); - bInHookProc = false; - } - break; + wxTheApp->ProcessPendingEvents(); } - return CallNextHookEx(wxEventFixModule::s_hMsgHookProc, nCode, wParam, lParam); + + return CallNextHookEx(ms_hMsgHookProc, nCode, wParam, lParam); }; + private: - static HHOOK s_hMsgHookProc; -DECLARE_DYNAMIC_CLASS(wxEventFixModule) + static HHOOK ms_hMsgHookProc; + + DECLARE_DYNAMIC_CLASS(wxIdleWakeUpModule) }; -HHOOK wxEventFixModule::s_hMsgHookProc = 0; -IMPLEMENT_DYNAMIC_CLASS(wxEventFixModule, wxModule) -#endif - // __WXWINCE__ +HHOOK wxIdleWakeUpModule::ms_hMsgHookProc = 0; + +IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule, wxModule) + +#endif // __WXWINCE__