extern wxMenu *wxCurrentPopupMenu;
#endif
+#if wxUSE_UXTHEME
+// This is a hack used by the owner-drawn wxButton implementation to ensure
+// that the brush used for erasing its background is correctly aligned with the
+// control.
+wxWindowMSW *wxWindowBeingErased = NULL;
+#endif // wxUSE_UXTHEME
+
namespace
{
return true;
}
+
bool wxWindowMSW::SetCursor(const wxCursor& cursor)
{
if ( !wxWindowBase::SetCursor(cursor) )
}
// don't "overwrite" busy cursor
- if ( m_cursor.Ok() && !wxIsBusy() )
+ if ( wxIsBusy() )
+ return true;
+
+ if ( m_cursor.IsOk() )
{
// normally we should change the cursor only if it's over this window
// but we should do it always if we capture the mouse currently
}
//else: will be set later when the mouse enters this window
}
+ else // Invalid cursor: this means reset to the default one.
+ {
+ // To revert to the correct cursor we need to find the window currently
+ // under the cursor and ask it to set its cursor itself as only it
+ // knows what it is.
+ POINT pt;
+ if ( !::GetCursorPos(&pt) )
+ {
+ wxLogLastError(wxT("GetCursorPos"));
+ return false;
+ }
+
+ const wxWindowMSW* win = wxFindWindowAtPoint(wxPoint(pt.x, pt.y));
+ if ( !win )
+ win = this;
+
+ ::SendMessage(GetHwndOf(win), WM_SETCURSOR,
+ (WPARAM)GetHwndOf(win),
+ MAKELPARAM(HTCLIENT, WM_MOUSEMOVE));
+ }
return true;
}
if ( y )
*y = rect.bottom;
}
+
+ // The size of the client window can't be negative but ::GetClientRect()
+ // can return negative size for an extremely small (1x1) window with
+ // borders so ensure that we correct it here as having negative sizes is
+ // completely unexpected.
+ if ( x && *x < 0 )
+ *x = 0;
+ if ( y && *y < 0 )
+ *y = 0;
}
void wxWindowMSW::DoGetPosition(int *x, int *y) const
int *externalLeading,
const wxFont *fontToUse) const
{
- wxASSERT_MSG( !fontToUse || fontToUse->Ok(),
+ wxASSERT_MSG( !fontToUse || fontToUse->IsOk(),
wxT("invalid font in GetTextExtent()") );
HFONT hfontToUse;
{
menu->UpdateUI();
+ wxPoint pt;
if ( x == wxDefaultCoord && y == wxDefaultCoord )
{
- wxPoint mouse = ScreenToClient(wxGetMousePosition());
- x = mouse.x; y = mouse.y;
+ pt = wxGetMousePosition();
+ }
+ else
+ {
+ pt = ClientToScreen(wxPoint(x, y));
}
- HWND hWnd = GetHwnd();
- HMENU hMenu = GetHmenuOf(menu);
- POINT point;
- point.x = x;
- point.y = y;
- ::ClientToScreen(hWnd, &point);
#if defined(__WXWINCE__)
static const UINT flags = 0;
#else // !__WXWINCE__
}
#endif // __WXWINCE__/!__WXWINCE__
- ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
+ ::TrackPopupMenu(GetHmenuOf(menu), flags, pt.x, pt.y, 0, GetHwnd(), NULL);
// we need to do it right now as otherwise the events are never going to be
// sent to wxCurrentPopupMenu from HandleCommand()
WXLRESULT wxWindowMSW::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
+ WXLRESULT rc;
if ( m_oldWndProc )
- return ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
+ rc = ::CallWindowProc(CASTWNDPROC m_oldWndProc, GetHwnd(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
else
- return ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam);
+ rc = ::DefWindowProc(GetHwnd(), nMsg, wParam, lParam);
+
+ // Special hack used by wxTextEntry auto-completion only: this event is
+ // sent after the normal keyboard processing so that its handler could use
+ // the updated contents of the text control, after taking the key that was
+ // pressed into account.
+ if ( nMsg == WM_CHAR )
+ {
+ wxKeyEvent event(CreateCharEvent(wxEVT_AFTER_CHAR, wParam, lParam));
+ HandleWindowEvent(event);
+ }
+
+ return rc;
}
bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
// emulate the button click
btn = wxFindWinFromHandle(msg->hwnd);
}
-
- bProcess = false;
}
else // not a button itself, do we have default button?
{
return true;
}
+ // This "Return" key press won't be actually used for
+ // navigation so don't generate wxNavigationKeyEvent
+ // for it but still pass it to IsDialogMessage() as it
+ // may handle it in some other way (e.g. by playing the
+ // default error sound).
+ bProcess = false;
+
#endif // wxUSE_BUTTON
#ifdef __WXWINCE__
return rc;
}
-WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+bool
+wxWindowMSW::MSWHandleMessage(WXLRESULT *result,
+ WXUINT message,
+ WXWPARAM wParam,
+ WXLPARAM lParam)
{
// did we process the message?
bool processed = false;
}
if ( !processed )
+ return false;
+
+ *result = rc.result;
+
+ return true;
+}
+
+WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+{
+ WXLRESULT result;
+ if ( !MSWHandleMessage(&result, message, wParam, lParam) )
{
#if wxDEBUG_LEVEL >= 2
wxLogTrace("winmsg", wxT("Forwarding %s to DefWindowProc."),
wxGetMessageName(message));
#endif // wxDEBUG_LEVEL >= 2
- rc.result = MSWDefWindowProc(message, wParam, lParam);
+ result = MSWDefWindowProc(message, wParam, lParam);
}
- return rc.result;
+ return result;
}
// ----------------------------------------------------------------------------
// m_cursor if the user code caught EVT_SET_CURSOR() and returned
// nothing from it - this is a way to say that our cursor shouldn't
// be used for this point
- if ( !processedEvtSetCursor && m_cursor.Ok() )
+ if ( !processedEvtSetCursor && m_cursor.IsOk() )
{
hcursor = GetHcursorOf(m_cursor);
}
if ( !hcursor && !GetParent() )
{
const wxCursor *cursor = wxGetGlobalCursor();
- if ( cursor && cursor->Ok() )
+ if ( cursor && cursor->IsOk() )
{
hcursor = GetHcursorOf(*cursor);
}
// to.
wxLogNull logNo; // suppress error if we couldn't load the bitmap
wxBitmap stdColourBitmap(wxT("wxBITMAP_STD_COLOURS"));
- if ( stdColourBitmap.Ok() )
+ if ( stdColourBitmap.IsOk() )
{
// the pixels in the bitmap must correspond to wxSTD_COL_XXX!
wxASSERT_MSG( stdColourBitmap.GetWidth() == wxSTD_COL_MAX,
WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
{
+ // Use the special wxWindowBeingErased variable if it is set as the child
+ // being erased.
+ wxWindowMSW * const child =
+#if wxUSE_UXTHEME
+ wxWindowBeingErased ? wxWindowBeingErased :
+#endif
+ this;
+
for ( wxWindowMSW *win = this; win; win = win->GetParent() )
{
- WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, this);
+ WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, child);
if ( hBrush )
return hBrush;
return event;
}
-// isASCII is true only when we're called from WM_CHAR handler and not from
-// WM_KEYDOWN one
-bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam)
+wxKeyEvent
+wxWindowMSW::CreateCharEvent(wxEventType evType,
+ WXWPARAM wParam,
+ WXLPARAM lParam) const
{
- wxKeyEvent event(wxEVT_CHAR);
+ wxKeyEvent event(evType);
InitAnyKeyEvent(event, wParam, lParam);
#if wxUSE_UNICODE
event.m_altDown = false;
}
+ return event;
+}
+
+// isASCII is true only when we're called from WM_CHAR handler and not from
+// WM_KEYDOWN one
+bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam)
+{
+ wxKeyEvent event(CreateCharEvent(wxEVT_CHAR, wParam, lParam));
return HandleWindowEvent(event);
}