Jump to content
Mike Warren

Detecting MouseUp When Outside The Form

Recommended Posts

Considering how long FireMonkey has been around, I'm really surprised by how much basic functionality is still missing.

 

In a VCL app, if a mouse button is pressed and held within the form's client area, then the MouseUp will still fire, even if the mouse has been moved outside the form while the button was held down.

 

This does not happen with a FMX application. If the MouseUp occurs anywhere except over the control that triggered the MouseDown, the MouseUp event it is ignored.

 

Tested on Windows and Mac.

 

I don't like my chances of Embarcadero fixing this any time soon, considering the Alt+Key problem was reported several years ago.

 

Can anybody suggest a workaround?

 

Edited by Mike Warren

Share this post


Link to post

FMX doesn't auto-capture the control the mouse went down on. But you can do this manually, either by TForm.MouseCapture (that's for the form itself) or with TForm.SetCaptured(AnyControl) - this is for a particular control on the form.

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  if (Sender <> self) then
    SetCaptured(TControl(Sender))
  else
    MouseCapture;

  memo1.lines.add(Sender.Classname + ' mouse down');
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  ReleaseCapture;

  memo1.lines.add(Sender.Classname + ' mouse up');
end;

 

Setting the mouse capture is important if you do anything in MouseDown that interacts with the control being clicked. Without capture, the user may click (mouse-down) on Panel1, move it, and release it on Panel2. The MouseUp will come from Panel2 in this case, or no mouse-up at all. By setting the mouse capture, you are guaranteed that you'll receive a MouseUp from that control that is being captured. VCL does this automatically, FMX does not.

 

If you don't need the MouseDown on form level, but just for particular controls, use TControl.AutoCapture instead.

Edited by Alexander Halser
  • Thanks 1

Share this post


Link to post

Thanks for your reply Alexander. This looks very promising so far.

 

I currently use AutoCapture to move controls within a frame in a TScrollBox (left click) and to move the frame itself within the scroll box (middle click). Unfortunately, the mouse up is lost if it is released outside the scrollbox or form.

 

MouseCapture definitely overcomes this problem, but it clashes with AutoCapture, so I'll have to rethink what I'm doing.

 

I think you've pointed me in the right direction.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×