// headers
// ---------------------------------------------------------------------------
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
- #pragma implementation "window.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
// by setting this to 0 (in the future this should be removed completely)
#define USE_DEFERRED_SIZING 1
+// set this to 1 to filter out duplicate mouse events, e.g. mouse move events
+// when mouse position didnd't change
+#ifdef __WXWINCE__
+ #define wxUSE_MOUSEEVENT_HACK 0
+#else
+ #define wxUSE_MOUSEEVENT_HACK 1
+#endif
+
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
// wxGetStdColourMap() and wxWindow::OnSysColourChanged() (FIXME-MT)
static bool gs_hasStdCmap = false;
+// last mouse event information we need to filter out the duplicates
+#if wxUSE_MOUSEEVENT_HACK
+static struct MouseEventInfoDummy
+{
+ // mouse position (in screen coordinates)
+ wxPoint pos;
+
+ // last mouse event type
+ wxEventType type;
+} gs_lastMouseEvent;
+#endif // wxUSE_MOUSEEVENT_HACK
+
// ---------------------------------------------------------------------------
// private functions
// ---------------------------------------------------------------------------
// get the text metrics for the current font
static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
+#ifdef __WXWINCE__
// find the window for the mouse event at the specified position
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y); //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y);
+#endif // __WXWINCE__
// wrapper around BringWindowToTop() API
static inline void wxBringWindowToTop(HWND hwnd)
m_xThumbSize = 0;
m_yThumbSize = 0;
-#if wxUSE_MOUSEEVENT_HACK
- m_lastMouseX =
- m_lastMouseY = -1;
- m_lastMouseEvent = -1;
-#endif // wxUSE_MOUSEEVENT_HACK
-
m_pendingPosition = wxDefaultPosition;
m_pendingSize = wxDefaultSize;
}
return false;
HWND hWnd = GetHwnd();
- int cshow = show ? SW_SHOW : SW_HIDE;
- ::ShowWindow(hWnd, cshow);
- if ( show && IsTopLevel() )
+ // we could be called before the underlying window is created (this is
+ // actually useful to prevent it from being initially shown), e.g.
+ //
+ // wxFoo *foo = new wxFoo;
+ // foo->Hide();
+ // foo->Create(parent, ...);
+ //
+ // should work without errors
+ if ( hWnd )
{
- wxBringWindowToTop(hWnd);
+ ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
+
+ if ( show && IsTopLevel() )
+ {
+ wxBringWindowToTop(hWnd);
+ }
}
return true;
return true;
}
-void wxWindowMSW::WarpPointer (int x, int y)
+void wxWindowMSW::WarpPointer(int x, int y)
{
ClientToScreen(&x, &y);
}
}
+void wxWindowMSW::MSWUpdateUIState(int action)
+{
+ // WM_UPDATEUISTATE only appeared in Windows 2000 so it can do us no good
+ // to use it on older systems -- and could possibly do some harm
+ static int s_needToUpdate = -1;
+ if ( s_needToUpdate == -1 )
+ {
+ int verMaj, verMin;
+ s_needToUpdate = wxGetOsVersion(&verMaj, &verMin) == wxWINDOWS_NT &&
+ verMaj >= 5;
+ }
+
+ if ( s_needToUpdate )
+ {
+ // NB: it doesn't seem to matter what we put in wParam, whether we
+ // include just one UISF_XXX or both, both are affected, no idea
+ // why
+ ::SendMessage(GetHwnd(), WM_UPDATEUISTATE,
+ MAKEWPARAM(action, UISF_HIDEFOCUS | UISF_HIDEACCEL), 0);
+ }
+}
+
// ---------------------------------------------------------------------------
// scrolling stuff
// ---------------------------------------------------------------------------
if ( GetEventHandler()->ProcessEvent(event) )
{
+ // as we don't call IsDialogMessage(), which would take of
+ // this by default, we need to manually send this message
+ // so that controls could change their appearance
+ // appropriately
+ MSWUpdateUIState(UIS_CLEAR);
+
return true;
}
}
int x = GET_X_LPARAM(lParam),
y = GET_Y_LPARAM(lParam);
+#ifdef __WXWINCE__
// redirect the event to a static control if necessary by
- // finding one under mouse
+ // finding one under mouse because under CE the static controls
+ // don't generate mouse events (even with SS_NOTIFY)
wxWindowMSW *win;
if ( GetCapture() == this )
{
wxCHECK_MSG( win, 0,
_T("FindWindowForMouseEvent() returned NULL") );
}
+#else // !__WXWINCE__
+ wxWindowMSW *win = this;
+#endif // __WXWINCE__/!__WXWINCE__
processed = win->HandleMouseEvent(message, x, y, wParam);
event.SetId(GetId());
#if wxUSE_MOUSEEVENT_HACK
- m_lastMouseX = x;
- m_lastMouseY = y;
- m_lastMouseEvent = event.GetEventType();
+ gs_lastMouseEvent.pos = ClientToScreen(wxPoint(x, y));
+ gs_lastMouseEvent.type = event.GetEventType();
#endif // wxUSE_MOUSEEVENT_HACK
}
+#ifdef __WXWINCE__
// Windows doesn't send the mouse events to the static controls (which are
// transparent in the sense that their WM_NCHITTEST handler returns
// HTTRANSPARENT) at all but we want all controls to receive the mouse events
// Notice that this is not done for the mouse move events because this could
// (would?) be too slow, but only for clicks which means that the static texts
// still don't get move, enter nor leave events.
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y)
{
wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") );
return win;
}
+#endif // __WXWINCE__
bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
{
(void)GetEventHandler()->ProcessEvent(event);
}
}
+#ifdef HAVE_TRACKMOUSEEVENT
+ else
+ {
+ // Check if we need to send a LEAVE event
+ // Windows doesn't send WM_MOUSELEAVE if the mouse has been captured so
+ // send it here if we are using native mouse leave tracking
+ if ( HasCapture() && !IsMouseInWindow() )
+ {
+ GenerateMouseLeave();
+ }
+ }
+#endif // HAVE_TRACKMOUSEEVENT
#if wxUSE_MOUSEEVENT_HACK
- // Window gets a click down message followed by a mouse move message even
- // if position isn't changed! We want to discard the trailing move event
- // if x and y are the same.
- if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN ||
- m_lastMouseEvent == wxEVT_LEFT_DOWN ||
- m_lastMouseEvent == wxEVT_MIDDLE_DOWN) &&
- (m_lastMouseX == x && m_lastMouseY == y) )
- {
- m_lastMouseEvent = wxEVT_MOTION;
+ // Windows often generates mouse events even if mouse position hasn't
+ // changed (http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/66576)
+ //
+ // Filter this out as it can result in unexpected behaviour compared to
+ // other platforms
+ if ( gs_lastMouseEvent.type == wxEVT_RIGHT_DOWN ||
+ gs_lastMouseEvent.type == wxEVT_LEFT_DOWN ||
+ gs_lastMouseEvent.type == wxEVT_MIDDLE_DOWN ||
+ gs_lastMouseEvent.type == wxEVT_MOTION )
+ {
+ if ( ClientToScreen(wxPoint(x, y)) == gs_lastMouseEvent.pos )
+ {
+ gs_lastMouseEvent.type = wxEVT_MOTION;
- return false;
+ return false;
+ }
}
#endif // wxUSE_MOUSEEVENT_HACK