开发者

Is mouse over Form?

开发者 https://www.devze.com 2023-01-30 06:15 出处:网络
This code is not working for me on Delphi XE: http://delphi.about.com/cs/adptips2000/a/bltip0800_5.htm

This code is not working for me on Delphi XE:

http://delphi.about.com/cs/adptips2000/a/bltip0800_5.htm

procedure TForm1.FormDeactivate(Sender: TObject) ;
begin
   ReleaseCapture;
end;

procedure TForm1.FormMouseMove
(Sender: TObject; Shift: TSh开发者_如何学GoiftState; X,Y: Integer) ;
begin
  If GetCapture = 0 then
    SetCapture(Form1.Handle) ;
    if PtInRect(Rect(Form1.Left,
                    Form1.Top,
                    Form1.Left + Form1.Width,
                    Form1.Top + Form1.Height),
                    ClientToScreen(Point(x, y))) then
     Form1.Caption := 'Mouse is over form' else
     Form1.Caption := 'Mouse is outside of form';
end;

No errors - it just has no effect.

Please help.

EDIT 1

It turned out the problem is not with the code, even mouse FormMouseEnter and FormMouseLeave are not working because I'm passing the form to a Unit I created with a function like this:

procedure Slide(Form: TForm; Show: Boolean);

I'm calling the Show method from inside this procedure. How can I overcome this problem?

Thanks.

EDIT 2

I don't want to use the function I posted now. I want to use what the people suggested below (FormMouseEnter and FormMouseLeave) but it's not working in my case as well.


You could use OnMouseEnter and OnMouseLeave events to keep track of whether the mouse is over the form or not without capturing the mouse cursor.


This is just a matter of entering the necessary code in the OnMouseEnter and OnMouseLeave events of the corresponding form. In my case, all I did was :

Create a new project in Delphi
Select the form you are working with
Go to the Object Inspector
Switch to the Events tab in the object inspector if necessary
Scroll down to the OnMouseEnter event, double click in the white space next to it which will generate an EventHandler. Make sure you end up with the following code in the event handler :

procedure TForm1.FormMouseEnter(Sender: TObject);
begin
  Self.Caption := 'Mouse in form';
end;

Go to the Object Inspector again
Find the OnMouseLeave event and double click in the white area to the right of it to generate a new event handler, and add the following code to it

procedure TForm1.FormMouseLeave(Sender: TObject);
begin
  Self.Caption := 'Mouse outside form';
end;

Run the app ... move your mouse over the form and the caption will change to 'Mouse inside form', move it outside the form and the caption will say 'Mouse outside form'

Works as a charm (Tested in Delphi 2010)


As far as I understand, using SetCapture for this is a bad idea. If it functioned like you wish, you would be robbing everyone else of the mouse messages just because you don't know a better way to track mouse.

But MSDN says (http://msdn.microsoft.com/en-us/library/ms646262(VS.85).aspx) that even with SetCapture, mouse messages from outside would not be redirected to your window unless mouse button is down (probably a measure to prevent exactly what are you trying to achieve: stealing mouse without a valid reason).

It doesn't matter where are you calling Show() from, so your problem is not in that.


I needed a form (frmTasks) with a heavily modified Caption. So I created a form with a hidden Caption. I simulate the Caption with a TImage (imgRedLogo) on which I draw the stuff I need. This code lets the user to click the fake caption (the image) and move the form around. Works like a charm WITHOUT capturing the mouse. It works even with the right mouse button (you have to test the 'Button' parameter in imgRedLogoMouseDown if you want to disable this 'feature').

FULL WORKING CODE:

VAR
  Dragged  : Boolean= FALSE;
  IsOverImg: Boolean= FALSE;  { True if mouse if over the image }
  OldPos   : TPoint;

procedure TfrmTasks.imgRedLogoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 Dragged:= True;
 GetCursorPos(OldPos);
end;

procedure TfrmTasks.imgRedLogoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
VAR NewPos: TPoint;
begin
 if Dragged AND IsOverImg then
  begin
    GetCursorPos(NewPos);
    frmTasks.Left:= frmTasks.Left- OldPos.X + NewPos.X;
    frmTasks.Top := frmTasks.Top - OldPos.Y + NewPos.Y;
    OldPos:= NewPos;
  end;
end;

procedure TfrmTasks.imgRedLogoMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 if Dragged
 then Dragged:= False;
end;

procedure TfrmTasks.imgRedLogoMouseEnter(Sender: TObject);
begin
 IsOverImg:= TRUE;
end;

procedure TfrmTasks.imgRedLogoMouseLeave(Sender: TObject);
begin
 IsOverImg:= FALSE;
end;

Enjoy.

0

精彩评论

暂无评论...
验证码 换一张
取 消