Search code examples
delphimousecursor-position

Wrap mouse around screen edges


problem description

I've got a Delphi component. To set a value, you can click and drag.

However, when you reach the edge of the screen, you can't go any further. You then need to go back to the component and drag further, which is not very user-friendly.

preferred solution

What I'd like is to have the mouse cursor wrap around the screen if you reach an edge, so you can continue scrolling a value. 3dsmax uses this type of GUI control extensively, and I like how that works.

Alternatively, it would be fine for me if the cursor goes off-screen, but continues to send X/Y coordinates that are out of the screen bounds.

what i have so far

I know that I can get/set the current mouse position via Mouse.CursorPos, and that the screen dimensions are available via Screen.Width and Screen.Height.

The code below does wrap the mousecursor around the way I want to.

procedure TFormXXXX.YYYYMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  LX, LY: Integer;
begin
  LX := Mouse.CursorPos.X;
  if LX < 1 then
    LX := Screen.Width - 1
  else
    if LX>Screen.Width -2 then
      LX := 0;

  LY := Mouse.CursorPos.Y;
  if LY < 1 then
    LY := Screen.Height - 1
  else
    if LY>Screen.Height -2 then
      LY := 0;

  Mouse.CursorPos := Point(LX, LY);
end;

There's still the problem that I have to "manually" keep track of the wraps to obtain a proper offset from the starting point, but I'll find a way to solve that.

I just don't know if this is a proper approach to do this. Maybe somebody has some experience or wise words to say about this...

main question

Is there a tried and tested common approach to this? Does windows provide stuff to do something like this maybe?

some doubts that I have

  • How will this behave when there are multiple monitors?
  • What happens if the user is connected via a slow (VNC?) connection.. will the cursorposition always reach 0 or the other extreme end of the screen?
  • What will happen if the input control is not a mouse, but a sketchpad or a touchscreen?
  • Is it bad practice to change the mouse position? I can imagine users don't like my application to mess with their mouse cursor position.

Solution

  • Rather than having a simple linear scale, you could accelerate the change with increasing distance from the control, and have a cutoff where past that it starts incrementing automatically. Basically have it work like dragging to select text does, where the window starts scrolling once the mouse reaches the bottom of a window, even if the mouse stops moving once it reaches that point.