void wxWindowMSW::OnInternalIdle()
{
+#ifdef __WXWINCE__
// Check if we need to send a LEAVE event
if ( m_mouseInWindow )
{
// or doesn't have mouse capture
if ( !IsMouseInWindow() )
{
- // Generate a LEAVE event
- m_mouseInWindow = false;
-
- // Unfortunately the mouse button and keyboard state may have
- // changed by the time the OnInternalIdle function is called, so 'state'
- // may be meaningless.
- int state = 0;
- if ( wxIsShiftDown() )
- state |= MK_SHIFT;
- if ( wxIsCtrlDown() )
- state |= MK_CONTROL;
-
- // Only the high-order bit should be tested
- if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
- state |= MK_LBUTTON;
- if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
- state |= MK_MBUTTON;
- if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
- state |= MK_RBUTTON;
-
- POINT pt;
- if ( !::GetCursorPos(&pt) )
- {
- wxLogLastError(_T("GetCursorPos"));
- }
-
- // we need to have client coordinates here for symmetry with
- // wxEVT_ENTER_WINDOW
- RECT rect = wxGetWindowRect(GetHwnd());
- pt.x -= rect.left;
- pt.y -= rect.top;
-
- wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
- InitMouseEvent(event2, pt.x, pt.y, state);
-
- (void)GetEventHandler()->ProcessEvent(event2);
+ GenerateMouseLeave();
}
}
+#endif // !__WXWINCE__
if (wxUpdateUIEvent::CanUpdate(this))
UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
height = 0;
// if our parent had prepared a defer window handle for us, use it
- HDWP hdwp = m_parent ? (HDWP)m_parent->m_hDWP : NULL;
+ wxWindowMSW *parent = GetParent();
+ HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
if ( hdwp )
{
hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL,
}
// hdwp must be updated as it may have been changed
- m_parent->m_hDWP = (WXHANDLE)hdwp;
+ parent->m_hDWP = (WXHANDLE)hdwp;
}
// otherwise (or if deferring failed) move the window in place immediately
(void)HandleDestroy();
break;
+#ifndef __SMARTPHONE__ // or wxWinCE in general ?
case WM_WINDOWPOSCHANGING:
{
WINDOWPOS *wp = wx_reinterpret_cast(WINDOWPOS *, lParam);
// then change the positions of all child windows at once
if ( m_hDWP )
{
+ HDWP hDWP = (HDWP)m_hDWP;
+ m_hDWP = NULL;
+
// put all child controls in place at once now
- if ( !::EndDeferWindowPos((HDWP)m_hDWP) )
+ if ( !::EndDeferWindowPos(hDWP) )
{
wxLogLastError(_T("EndDeferWindowPos"));
}
-
- m_hDWP = NULL;
}
break;
+#endif // __SMARTPHONE__
case WM_SIZE:
processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
wParam);
break;
- // Seems to be broken currently
-#if 0 // ndef __WXWINCE__
+#ifdef WM_MOUSELEAVE
case WM_MOUSELEAVE:
- {
- wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
-
- // only process this message if the mouse is not in the window,
- // This can also check for children in composite windows.
- // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
- // if the mouse does not enter the window from it's child before
- // leaving the scope of the window. ( perhaps this can be picked
- // up in the OnIdle code as before, for this special case )
- if ( /*IsComposite() && */ !IsMouseInWindow() )
{
- m_mouseInWindow = false;
-
- // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
- int state = 0;
- if ( wxIsShiftDown() )
- state |= MK_SHIFT;
- if ( wxIsCtrlDown() )
- state |= MK_CONTROL;
- if ( GetKeyState( VK_LBUTTON ) )
- state |= MK_LBUTTON;
- if ( GetKeyState( VK_MBUTTON ) )
- state |= MK_MBUTTON;
- if ( GetKeyState( VK_RBUTTON ) )
- state |= MK_RBUTTON;
-
- POINT pt;
- if ( !::GetCursorPos(&pt) )
+ // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
+ if ( m_mouseInWindow )
{
- wxLogLastError(_T("GetCursorPos"));
+ GenerateMouseLeave();
}
- // we need to have client coordinates here for symmetry with
- // wxEVT_ENTER_WINDOW
- RECT rect = wxGetWindowRect(GetHwnd());
- pt.x -= rect.left;
- pt.y -= rect.top;
-
- wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
- InitMouseEvent(event2, pt.x, pt.y, state);
-
- (void)GetEventHandler()->ProcessEvent(event2);
+ // always pass processed back as false, this allows the window
+ // manager to process the message too. This is needed to
+ // ensure windows XP themes work properly as the mouse moves
+ // over widgets like buttons.
+ processed = false;
}
- // always pass processed back as false, this allows the window
- // manager to process the message too. This is needed to ensure
- // windows XP themes work properly as the mouse moves over widgets
- // like buttons.
- processed = false;
- }
- break;
-#endif
- // __WXWINCE__
+ break;
+#endif // WM_MOUSELEAVE
#if wxUSE_MOUSEWHEEL
case WM_MOUSEWHEEL:
bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
{
wxShowEvent event(GetId(), show);
- event.m_eventObject = this;
+ event.SetEventObject(this);
return GetEventHandler()->ProcessEvent(event);
}
bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
{
wxInitDialogEvent event(GetId());
- event.m_eventObject = this;
+ event.SetEventObject(this);
return GetEventHandler()->ProcessEvent(event);
}
DragFinish (hFilesInfo);
wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
- event.m_eventObject = this;
+ event.SetEventObject(this);
POINT dropPoint;
DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
{
- // standard controls always erase their background themselves (although the
- // user may try to override it in a derived class)
- if ( IsOfStandardClass() )
+ // standard non top level controls (i.e. except the dialogs) always erase
+ // their background themselves in HandleCtlColor() or have some control-
+ // specific ways to set the colours (common controls)
+ if ( IsOfStandardClass() && !IsTopLevel() )
{
event.Skip();
return;
// do default background painting
- wxDC& dc = *event.GetDC();
- HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
- if ( hBrush )
- {
- RECT rc;
- ::GetClientRect(GetHwnd(), &rc);
- ::FillRect(GetHdcOf(dc), &rc, hBrush);
- }
- else
+ if ( !DoEraseBackground(*event.GetDC()) )
{
// let the system paint the background
event.Skip();
}
}
+bool wxWindowMSW::DoEraseBackground(wxDC& dc)
+{
+ HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
+ if ( !hBrush )
+ return false;
+
+ RECT rc;
+ ::GetClientRect(GetHwnd(), &rc);
+ ::FillRect(GetHdcOf(dc), &rc, hBrush);
+
+ return true;
+}
+
WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
{
wxColour col = MSWGetBgColourForChild(child);
wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child)
{
- return m_inheritBgCol || (m_hasBgCol && child == this)
- ? GetBackgroundColour()
- : wxNullColour;
+ if ( m_hasBgCol )
+ {
+ // our background colour applies to:
+ // 1. this window itself, always
+ // 2. all children unless the colour is "not inheritable"
+ // 3. immediate transparent children which should show the same
+ // background as we do, but not for transparent grandchildren
+ // which use the background of their immediate parent instead
+ if ( m_inheritBgCol ||
+ child == this ||
+ (child->HasTransparentBackground() &&
+ child->GetParent() == this) )
+ {
+ return GetBackgroundColour();
+ }
+ }
+
+ return wxNullColour;
}
WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)
event.m_leftDown = (flags & MK_LBUTTON) != 0;
event.m_middleDown = (flags & MK_MBUTTON) != 0;
event.m_rightDown = (flags & MK_RBUTTON) != 0;
- // event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
- // Returns different negative values on WinME and WinNT,
- // so simply test for negative value.
event.m_altDown = ::GetKeyState(VK_MENU) < 0;
#ifndef __WXWINCE__
event.SetTimestamp(::GetMessageTime());
#endif
- event.m_eventObject = this;
+ event.SetEventObject(this);
event.SetId(GetId());
#if wxUSE_MOUSEEVENT_HACK
{
// Generate an ENTER event
m_mouseInWindow = true;
-#if _WIN32_WINNT >= 0x0400
#ifndef __WXWINCE__
TRACKMOUSEEVENT trackinfo;
// appropriate TrackMouseEvent or emulate it ( win95 )
// else we need _WIN32_WINNT >= 0x0400
_TrackMouseEvent(&trackinfo);
-#endif
-#endif
+#endif // __WXWINCE__
wxMouseEvent event(wxEVT_ENTER_WINDOW);
InitMouseEvent(event, x, y, flags);
event.m_linesPerAction = s_linesPerRotation;
return GetEventHandler()->ProcessEvent(event);
-#else
- (void) wParam;
- (void) lParam;
+#else // !wxUSE_MOUSEWHEEL
+ wxUnusedVar(wParam);
+ wxUnusedVar(lParam);
return false;
-#endif
+#endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL
}
+void wxWindowMSW::GenerateMouseLeave()
+{
+ m_mouseInWindow = false;
+
+ int state = 0;
+ if ( wxIsShiftDown() )
+ state |= MK_SHIFT;
+ if ( wxIsCtrlDown() )
+ state |= MK_CONTROL;
+
+ // Only the high-order bit should be tested
+ if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
+ state |= MK_LBUTTON;
+ if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
+ state |= MK_MBUTTON;
+ if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
+ state |= MK_RBUTTON;
+
+ POINT pt;
+ if ( !::GetCursorPos(&pt) )
+ {
+ wxLogLastError(_T("GetCursorPos"));
+ }
+
+ // we need to have client coordinates here for symmetry with
+ // wxEVT_ENTER_WINDOW
+ RECT rect = wxGetWindowRect(GetHwnd());
+ pt.x -= rect.left;
+ pt.y -= rect.top;
+
+ wxMouseEvent event(wxEVT_LEAVE_WINDOW);
+ InitMouseEvent(event, pt.x, pt.y, state);
+
+ (void)GetEventHandler()->ProcessEvent(event);
+}
// ---------------------------------------------------------------------------
// keyboard handling
event.m_controlDown = wxIsCtrlDown();
event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;
- event.m_eventObject = (wxWindow *)this; // const_cast
+ event.SetEventObject((wxWindow *)this); // const_cast
event.m_keyCode = id;
#if wxUSE_UNICODE
event.m_uniChar = (wxChar) wParam;
wxScrollWinEvent event;
event.SetPosition(pos);
event.SetOrientation(orientation);
- event.m_eventObject = this;
+ event.SetEventObject(this);
switch ( wParam )
{
case SB_TOP:
- event.m_eventType = wxEVT_SCROLLWIN_TOP;
+ event.SetEventType(wxEVT_SCROLLWIN_TOP);
break;
case SB_BOTTOM:
- event.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
+ event.SetEventType(wxEVT_SCROLLWIN_BOTTOM);
break;
case SB_LINEUP:
- event.m_eventType = wxEVT_SCROLLWIN_LINEUP;
+ event.SetEventType(wxEVT_SCROLLWIN_LINEUP);
break;
case SB_LINEDOWN:
- event.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
+ event.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
break;
case SB_PAGEUP:
- event.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
+ event.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
break;
case SB_PAGEDOWN:
- event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
+ event.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
break;
case SB_THUMBPOSITION:
event.SetPosition(scrollInfo.nTrackPos);
}
- event.m_eventType = wParam == SB_THUMBPOSITION
+ event.SetEventType( wParam == SB_THUMBPOSITION
? wxEVT_SCROLLWIN_THUMBRELEASE
- : wxEVT_SCROLLWIN_THUMBTRACK;
+ : wxEVT_SCROLLWIN_THUMBTRACK );
break;
default:
if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
event.m_altDown = true;
- event.m_eventObject = NULL;
+ event.SetEventObject(NULL);
event.m_keyCode = id;
event.m_shiftDown = wxIsShiftDown();
event.m_controlDown = wxIsCtrlDown();