Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-07

(no subject)

6 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Leonardo Rame

Hi, I would like to drag the mouse over a form, while the mouse is dragged, FPos X and Y values must change in the direction of the move, but the mouse cursor must be fixed at the position where the first click was made.

This code does more or less what I want, but has two problems:

1 - The mouse still moves a little.
2 - The values of FPos.X and FPos.Y doesn't change.

What I'm doing wrong?.

Just add a TLabel over a form, and override TForm.OnMouseMove, OnMouseDown and OnPaint events.

unit Unit1;?
{$mode objfpc}{$H+}
interface
uses
? Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type

? { TForm1 }

? TForm1 = class(TForm)
? ? Label1: TLabel;
? ? procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
? ? ? Shift: TShiftState; X, Y: Integer);
? ? procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
? ? procedure FormPaint(Sender: TObject);
? private
? ? { private declarations }
? public
? ? FPos: TPoint;
? end;?
var
? Form1: TForm1;?
implementation
{$R *.lfm}

{ TForm1 }

procedure TForm1.FormPaint(Sender: TObject);
begin
? Label1.Caption := Format('X: %d - Y: %d', [FPos.X, FPos.Y]);
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
? Shift: TShiftState; X, Y: Integer);
begin
? if ssleft in shift then
? begin
? ? FPos.X := X;
? ? FPos.Y := Y;
? end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
? Y: Integer);
begin
? if ssLeft in shift then
? begin
? ? Mouse.CursorPos := ClientToScreen(FPos);
? ? FPos.X := X;
? ? FPos.Y := Y;
? ? Invalidate;
? end;
end;

Leonardo.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110730/b173b2c0/attachment.html>

Reply by email

Howard Page-Clark
to Leonardo Rame
Leonardo Rame wrote 22 lines
Hi, I would like to drag the mouse over a form, while the mouse is dragged, FPos X and Y values must change in the direction of the move, but the mouse cursor must be fixed at the position where the first click was made. This code does more or less what I want, but has two problems: 1 - The mouse still moves a little. 2 - The values of FPos.X and FPos.Y doesn't change. procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in shift then begin Mouse.CursorPos := ClientToScreen(FPos); FPos.X := X; FPos.Y := Y; Invalidate; end; end;

Changing the mouse cursor position interferes with the Invalidate call. Try this:

unit Unit1;
{$mode objfpc}{$H+}
interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, windows;

type
   { TForm1 }
   TForm1 = class(TForm)
     Label1: TLabel;
     procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
       Shift: TShiftState; X, Y: Integer);
     procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y:
Integer);
     procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
       Shift: TShiftState; X, Y: Integer);
     procedure FormPaint(Sender: TObject);
   private
     FPos: TPoint;
     FOldCursorPos: TPoint;
     FOldCursor: TCursor;
   end;
var
   Form1: TForm1;
implementation
{$R *.lfm}

{ TForm1 }

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
begin
   if ssleft in shift then
   begin
     FPos.X := X;
     FPos.Y := Y;
     FOldCursorPos:= FPos;
     FOldCursor := Cursor;
     Cursor := crNone;
   end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
   Y: Integer);
begin
   if ssLeft in shift then
   begin
     //Mouse.CursorPos := ClientToScreen(FPos);
     FPos.X := X;
     FPos.Y := Y;
     Invalidate;
   end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
begin
   Cursor := FOldCursor;
end;
procedure TForm1.FormPaint(Sender: TObject);
var
    HCursor : THandle;
begin
    Label1.Caption := Format('X: %d - Y: %d', [FPos.X, FPos.Y]);
    HCursor := Screen.Cursors[Ord(Screen.Cursor)];
    DrawIconEx(Canvas.Handle,
    FOldCursorPos.X, FOldCursorPos.y, HCursor, 32, 32, 0, 0, DI_NORMAL) ;
end;
end.

It is only a solution for Windows, and it does not remove the 'permanent' cursor until a second click, but it should get you on the right path.

Howard

Reply by email

Bart
to Howard Page-Clark

As an end-user I would get rather confused if my mouse cursor didn't move anymore when I was moving the mouse.

Bart

Howard Page-Clark wrote 120 lines
On 30/7/11 11:15, Leonardo Rame wrote: > Hi, I would like to drag the mouse over a form, while the mouse is > dragged, FPos X and Y values must change in the direction of the move, > but the mouse cursor must be fixed at the position where the first click > was made. > > This code does more or less what I want, but has two problems: > > 1 - The mouse still moves a little. > 2 - The values of FPos.X and FPos.Y doesn't change. > > procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, > Y: Integer); > begin > if ssLeft in shift then > begin > Mouse.CursorPos := ClientToScreen(FPos); > FPos.X := X; > FPos.Y := Y; > Invalidate; > end; > end; Changing the mouse cursor position interferes with the Invalidate call. Try this: unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, windows; type { TForm1 } TForm1 = class(TForm) Label1: TLabel; procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormPaint(Sender: TObject); private FPos: TPoint; FOldCursorPos: TPoint; FOldCursor: TCursor; end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if ssleft in shift then begin FPos.X := X; FPos.Y := Y; FOldCursorPos:= FPos; FOldCursor := Cursor; Cursor := crNone; end; end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in shift then begin //Mouse.CursorPos := ClientToScreen(FPos); FPos.X := X; FPos.Y := Y; Invalidate; end; end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Cursor := FOldCursor; end; procedure TForm1.FormPaint(Sender: TObject); var HCursor : THandle; begin Label1.Caption := Format('X: %d - Y: %d', [FPos.X, FPos.Y]); HCursor := Screen.Cursors[Ord(Screen.Cursor)]; DrawIconEx(Canvas.Handle, FOldCursorPos.X, FOldCursorPos.y, HCursor, 32, 32, 0, 0, DI_NORMAL) ; end; end. It is only a solution for Windows, and it does not remove the 'permanent' cursor until a second click, but it should get you on the right path. Howard -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Leonardo M. Ramé
to Bart
Bart wrote
As an end-user I would get rather confused if my mouse cursor didn't move anymore when I was moving the mouse. Bart

I agree, but some times is better to fix the cursor to a specific position. In my case, I have a N x M grid containing images in each cell (cells uses 256x256 pixels or bigger), and the user can drag the mouse to change its brightness and contrast, or zoom-in zoom-out inside the cell.

If I don't fix the cursor pos, the user can start working on one cell and continue in the cell at its side.

Reply by email

Leonardo M. Ramé
to Howard Page-Clark: Changing the mouse cursor position interferes with the Invalidate call. Try this: unit…
Howard Page-Clark wrote 112 lines
On 30/7/11 11:15, Leonardo Rame wrote: >Hi, I would like to drag the mouse over a form, while the mouse is >dragged, FPos X and Y values must change in the direction of the move, >but the mouse cursor must be fixed at the position where the first click >was made. > >This code does more or less what I want, but has two problems: > >1 - The mouse still moves a little. >2 - The values of FPos.X and FPos.Y doesn't change. > >procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, > Y: Integer); >begin > if ssLeft in shift then > begin > Mouse.CursorPos := ClientToScreen(FPos); > FPos.X := X; > FPos.Y := Y; > Invalidate; > end; >end; Changing the mouse cursor position interferes with the Invalidate call. Try this: unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, windows; type { TForm1 } TForm1 = class(TForm) Label1: TLabel; procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormPaint(Sender: TObject); private FPos: TPoint; FOldCursorPos: TPoint; FOldCursor: TCursor; end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if ssleft in shift then begin FPos.X := X; FPos.Y := Y; FOldCursorPos:= FPos; FOldCursor := Cursor; Cursor := crNone; end; end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in shift then begin //Mouse.CursorPos := ClientToScreen(FPos); FPos.X := X; FPos.Y := Y; Invalidate; end; end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Cursor := FOldCursor; end; procedure TForm1.FormPaint(Sender: TObject); var HCursor : THandle; begin Label1.Caption := Format('X: %d - Y: %d', [FPos.X, FPos.Y]); HCursor := Screen.Cursors[Ord(Screen.Cursor)]; DrawIconEx(Canvas.Handle, FOldCursorPos.X, FOldCursorPos.y, HCursor, 32, 32, 0, 0, DI_NORMAL) ; end; end. It is only a solution for Windows, and it does not remove the 'permanent' cursor until a second click, but it should get you on the right path. Howard

I tried this on Linux, with a slightly modified FormPaint event handler, but the effect is the same as in my example.

When I move the mouse, FPos is changed to the new values of X and Y, but when Mouse.CursorPos is called using FOldCursorPos as new position, OnMouseMove is called again, and FPos is changed again to its old position.

Here's my new code:

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssleft in shift then
  begin
    FPos.X := X;
    FPos.Y := Y;
    FOldCursorPos:= FPos;
    Cursor := crNone;
 end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if ssLeft in shift then
  begin
    FPos.X := X;
    FPos.Y := Y;
    Invalidate;
  end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Cursor := crDefault;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
  Label1.Caption := Format('X: %d - Y: %d', [FPos.X, FPos.Y]);
  Mouse.CursorPos := ClientToScreen(FOldCursorPos);
end;

Reply by email

Hans-Peter Diettrich
to Leonardo M. Ramé: I agree, but some times is better to fix the cursor to a specific position. In my case, I…
Show quoted text 13 lines
On 2011-07-31 15:58:26 +0200, Bart wrote: > As an end-user I would get rather confused if my mouse cursor didn't > move anymore when I was moving the mouse. > > Bart I agree, but some times is better to fix the cursor to a specific position. In my case, I have a N x M grid containing images in each cell (cells uses 256x256 pixels or bigger), and the user can drag the mouse to change its brightness and contrast, or zoom-in zoom-out inside the cell. If I don't fix the cursor pos, the user can start working on one cell and continue in the cell at its side.

That's why usually the user has to select a cell, before changes can be made to exactly the selected cell. IMO you should separate cell selection from other actions. Zooming may have the biggest risk for a changed cell under the mouse, so that I would apply zoom either to the entire grid, or only to a selected cell. When an individual cell has been zoomed out, all further operations can apply to exactly that cell, regardless of the mouse position.

DoDi

Reply by email