Where is the cursor?
By Kent Reisdorph
Sometimes you need to know where the cursor is on the screen. For an application, the VCL makes this fairly easy by exposing the cursor X and Y coordinates in the OnMouseMove event handler. However, there are some cases where the OnMouseMove event handler won’t be available to you (when writing components or when writing mouse hook callbacks, for example). In those cases you will need to go to the Windows API in order to determine the position of the cursor.
Getting the cursor position
The GetCursorPos() Windows API function will tell you the current location of the cursor relative to the desktop. This method takes a pointer to a POINT structure as its only parameter. The x and y members of this structure will contain the X and Y coordinates of the cursor position when GetCursorPos() returns. You can substitute a VCL TPoint structure for a POINT structure if you prefer. The following code gets the cursor position and displays the coordinates in a label:
TPoint pt; GetCursorPos(&pt); Label3->Caption = String(pt.x) + ", " + String(pt.y);
The return value of GetCursorPos() is nonzero if the call succeeds, or zero if the call fails. I doubt most programmers check the return value of GetCursorPos() as the chances of failure are quite low.
Window-relative cursor positions
As I said earlier, GetCursorPos() gets the position of the cursor relative to the desktop. It is often necessary to get the cursor position relative to a particular window. If you were writing a visual component, for example, you may need to determine the cursor position relative to the component rather than the desktop.
You can convert screen (desktop) coordinates to window coordinates by calling the ScreenToClient() function. Both the VCL and the Windows API have functions by this name, and they differ in their use. The Windows version is declared as follows:
BOOL ScreenToClient( HWND hWnd, LPPOINT lpPoint);
The first parameter is the handle of the window for which the coordinates will be converted. The second parameter is a point to a POINT (or TPoint) structure. You fill in the x and y members of this structure prior to calling ScreenToClient(), and after the function reuturns, the POINT structure will contain the converted values.
The VCL version of ScreenToClient() is different two ways. First, it does not have a window handle parameter. It automatically uses the window handle of the window (form or component) of the object. Second, it takes a reference to a TPoint structure as a parameter, and returns a new TPoint containing the converted coordinates. If you are writing a VCL application the compiler will automatically assume the VCL version of this function because it is in the most immediate scope.
ScreenToClient() is most often used in conjunction with GetCursorPos(). The following example uses the VCL version of ScreenToClient() to obtain the current cursor position relative to the form (assuming this code were called from within a TForm descendant):
TPoint pt; GetCursorPos(&pt); pt = ScreenToClient(pt);
Finally, let me add that there is also a ClientToScreen() function (both API and VCL). This function can be used in conjunction with ScreenToClient() to convert the cursor position of one window to coordinates relative to a second window.