The documentation will frequently talk about "client coordinates."
For example, wxKeyEvent::GetPosition documentation reads: "Obtains the position (in client coordinates) at which the key was pressed."
These coordinates refer to the position in pixels relative to the top-left corner of the window, whatever window it happens to be.
In the case of a Frame, the top-left corner include the title bar.
Frame starts here \ ----------------------------------------- | Title Bar | ----------------------------------------- |\ | | \ | | Panel within Frame starts here | | | | | | | | | -----------------------------------------
Getting Client coordinates from Screen Coordinates
You can get client coordinates, given screen coordinates.
wx.GetMousePosition returns screen coordinates; We can coax them into client coordinates.
1 panel_pos = panel.ScreenToClient(wx.GetMousePosition())
That will get you the position of the mouse on the client panel. (0,0) will be the top-left corner of the panel.
1 panel_pos = frame.ScreenToClient(wx.GetMousePosition())
Perhaps bizarrely, (I can't account for it..!), this will give you the mouse position in terms of the panel as well!
You would think it would do it in terms of the frame, with (0,0) being the top-left corner of the title bar. (It's like this when you get the PositionOfAnEvent, where the event is tied to a frame.)
Nope. It does it in terms of the panel immediately contained, instead, with (0,0) being just below the bottom-left corner of the title bar.
Why? I don't know.
Client Coordinates in the wxWindows Code
You can see the client coordinates being constructed:
wxWidgets-2.6.3/src/mswapp/window.cpp
// --------------------------------------------------------------------------- // keyboard handling // --------------------------------------------------------------------------- // create the key event of the given type for the given key - used by // HandleChar and HandleKeyDown/Up wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType, int id, WXLPARAM lParam, WXWPARAM wParam) const { ... (ommitted) ... // translate the position to client coords POINT pt; #ifdef __WXWINCE__ GetCursorPosWinCE(&pt); #else GetCursorPos(&pt); #endif RECT rect; GetWindowRect(GetHwnd(),&rect); pt.x -= rect.left; pt.y -= rect.top; event.m_x = pt.x; event.m_y = pt.y; return event; }
MSDN documentation for those functions:
GetCursorPos -- "The cursor position is always specified in screen coordinates and is not affected by the mapping mode of the window that contains the cursor."
GetWindowRect -- "The GetWindowRect function retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen."
So the client coordinates are defined with respect to the top-left corner of the window.
ScreenToClient in the wxWindows Code
wxWidgets-2.6.3/src/msw/window.cpp
void wxWindowMSW::DoScreenToClient(int *x, int *y) const { POINT pt; if ( x ) pt.x = *x; if ( y ) pt.y = *y; ::ScreenToClient(GetHwnd(), &pt); if ( x ) *x = pt.x; if ( y ) *y = pt.y; }
ScreenToClient MSDN documentation -- "The ScreenToClient function converts the screen coordinates of a specified point on the screen to client-area coordinates."
See Also
PositionOfAnEvent -- the page that inspired this study