Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Привязка мыши к точке [D5, Win2k, WinXP]


Страницы:   1 2

jack128 ©   (2004-06-24 16:55:00) 

День добрый.
Многие наверно видели в AutoCAD'e привязку курсора к мыши точке экрана (команда Osnap off/on)
Пытаюсь сделать, что то похоже. Вот что у меня получается:

type
 TForm1 = class(TForm)
   PaintBox: TPaintBox;
   Memo1: TMemo;
   procedure PaintBoxPaint(Sender: TObject);
   procedure PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
 private
   { Private declarations }
   // виртуальные координаты курсора относительно точки привязки, если бы мы не привязывали курсор
   dX, dY: Integer;
   // центр PaintBox'a - та точка к которой привязываемся
   function GetCenter: TPoint;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

const
CrossLen = 5;

procedure TForm1.PaintBoxPaint(Sender: TObject);
begin
 // Ресуем крест в центре пайнтбокса
 with PaintBox.Canvas, GetCenter do
 begin
   MoveTo(x - CrossLen, y);
   LineTo(x + CrossLen + 1, y);
   MoveTo(x, y - CrossLen);
   LineTo(x, y + CrossLen + 1);
 end;
end;

procedure TForm1.PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
var
 c: TPoint;
 r: TRect;
begin
 c := GetCenter;
 if (c.x = x) and (c.y = y) then exit;
 // если курсов внутри небольшой области рядом с точкой привязки
 if (abs(X - c.x) <= CrossLen) and (abs(Y - c.y) <= CrossLen) then
 begin
   inc(dX, x - c.x);
   inc(dY, y - c.y);
   if (abs(dX) > CrossLen) or (abs(dY) > CrossLen) then
   begin
     with PaintBox.ClientToScreen(Point(c.x + dx, c.y + dY)) do
       SetCursorPos(x, y);
     dX := 0; dY := 0;
   end
   else
     with PaintBox.ClientToScreen(c) do
       SetCursorPos(x, y);
 end;
end;

function TForm1.GetCenter: TPoint;
begin
 with PaintBox do
 begin
   Result.x := Width div 2;
   Result.y := Height div 2;
 end;
end;


Проблема в том, если курсор медленно перемещать в области привязки, то он мигает. Может у кого есть мысли как этого избежать?


Романов Р.В.   (2004-06-25 08:17:00) [1]

Свойства: Экран -> Настройка -> Дополнительно -> Устранение неполадок -> Отключить ускорение курсора и точечных рисунков. Используйте такую настройку при проблемах с курсором или при просмотре поврежденных файлов изображений.


jack128   (2004-06-25 05:47:00) [2]


> GuAV ©   (24.06.04 23:43)
ну вот, вспомнил былое... Тогда я был молодым и глупым :-)


MIGUR   (2004-06-25 03:33:00) [3]

Воспользуйся лучше компонентом LMD-Tools 7.0
В нем есть такой компонент как приязка крысы к любой точке монитора, и нетолько, короче чтобы увидеть качай весит 20mb, и crack скачать незабуть. Кстати неодин мой проект необходится без этого компонента. (*_*)


GuAV   (2004-06-24 23:43:00) [4]

Из архива...

jack128 ©  (06.06.04 15:32)  [41]

> Есть идея такая-скрыть нафиг курсор. рисовать самому курсор
> вместе с линеей и юзер нифига не заподозрит.
Слушай - я тебя боюсь ;-)) С такими приколами юзер у тя инфаркт может схватить..


:-))


jack128   (2004-06-24 23:27:00) [5]


> Собственно что мешает скрыть курсор и отрисовывать самому
> в какой угодно позиции как душе угодно...

угу. Это FX предложил, я попробую..


Palladin   (2004-06-24 23:14:00) [6]


>  jack128 ©

Собственно что мешает скрыть курсор и отрисовывать самому в какой угодно позиции как душе угодно...


GuAV   (2004-06-24 22:56:00) [7]


> Конструктивно. Сенкс.

Хм. Я то же самое написал в ветке про линию (только словамии), а ты сказал, что меня боишься :)  
Кстати, наверное знаешь - Electronic Workbench - так она осуществляет snap-to-grid при отпускании, а таскаешь объект и водишь курсор без этого.


jack128   (2004-06-24 20:06:00) [8]


> [11] FX ©   (24.06.04 19:39)

Конструктивно. Сенкс.


> А не пробовал делать двойную буферизацию?

курсор отрисововается аппаратно, на него такие вещи не влияют.

> Имхо snap-to-grid не для мыши обычно делают а для объекта.
> см. drag-drop в IDE Delphi.
ну естественно. Это так, я пример накидал. Реально мышкой переносятся элементы схемы.

> если это все та же прога, в которой линии проводишь, то
> я тебе сочувствую
угу, она же. А что так? Туго идет? ;-) Ну так не забывай - у мя экзамены, в июле дела быстрее пойдут..


GuAV   (2004-06-24 20:05:00) [9]

кстати, насчет глючности виндового mousemove - пригрузив комп можно добиться чтоб окно "ShowMessage" таскалось с запозданием!


GuAV   (2004-06-24 19:56:00) [10]


> есть. AFAIK любой обработчик соообщения - суть дин метод

Не знал. Тогда в OnMouseMove таких вызовов аж два.
Имхо snap-to-grid не для мыши обычно делают а для объекта. см. drag-drop в IDE Delphi.
зы - если это все та же прога, в которой линии проводишь, то я тебе сочувствую


QuasiLamo   (2004-06-24 19:45:00) [11]


> jack128 ©   (24.06.04 16:55)

А попробуй сделать чтобы курсов вообще на промежуточные позиции... то есть при перемещении мыши указатель прыгал сразу на соседнюю точку сетки... Строго говоря, в автокаде так и сделано кажется...
А не пробовал делать двойную буферизацию?


FX   (2004-06-24 19:39:00) [12]

type
 TForm1 = class(TForm)
   procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
   procedure DrawCursor(X, Y: Integer);
   procedure FormCreate(Sender: TObject);
   procedure FormPaint(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

var
 CurPt: TPoint;
 Grid: Byte = 12;

{$R *.DFM}

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
var
 dX, dY: Integer;
 NewPt: TPoint;
begin
 if X mod Grid <= Grid div 2 then dX:=0 else dX:=Grid;
 if Y mod Grid <= Grid div 2 then dY:=0 else dY:=Grid;
 NewPt:=Point(X div Grid *Grid + dX, Y div Grid *Grid + dY);
 Caption:=Format('%d, %d', [NewPt.x, NewPt.y]);
 if (NewPt.x = CurPt.x) and  (NewPt.y = CurPt.y)then Exit;
 DrawCursor(CurPt.x, CurPt.y);
 CurPt:=NewPt;
 DrawCursor(NewPt.x, NewPt.y);
end;

procedure TForm1.DrawCursor(X, Y: Integer);
begin
 with Canvas do begin
   Pen.Mode:=pmNotXor;
   MoveTo(X, Y-15);
   LineTo(X, Y+16);
   MoveTo(X-15, Y);
   LineTo(X+16, Y);
   Brush.Style:=bsClear;
   Rectangle(X-3, Y-3, X+4, Y+4);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Cursor:=-1;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
 X, Y: Integer;
begin
 for X:=0 to Width do
   if X mod Grid = 0 then
     for Y:=0 to Height do
       if Y mod Grid = 0 then
         Canvas.Pixels[X, Y]:=clBlack;
end;

end.


jack128   (2004-06-24 19:31:00) [13]


> Вызова динамического метода нет и

есть. AFAIK любой обработчик соообщения - суть дин метод


> Ещё можно дизассемблить ClipCursor - у меня опыта в этом
> нет

у меня еще меньше. Я вообще с асмом на Вы..

Ладно, к черту, забыли про эту привязку - сделаю опцию, кому нравится - пусть включает, кому не нравиться - пусть сам до пикселя курсор позиционирует ;-)


GuAV   (2004-06-24 18:50:00) [14]

Мыслишка такая, что как ни крути, MouseMove - вечный гемморой.

> OnMouseMove

можно попробовать WM_MOUSEMOVE. Чем может ускорить?... Вызова динамического метода нет и вроде там какие то ещё лишине поверки...

Ещё +совсем-чуть-чуть FCenter заместо GetCenter.

Ещё можно дизассемблить ClipCursor - у меня опыта в этом нет, но может ты сможешь. Хотя работает ли она без глюков - вопрос.


jack128   (2004-06-24 17:59:00) [15]

Может все же у кого мыслишки появились?

У мя duron800/256/WinXP-Home

то ли особенности линейки NT, то ли черт его знает.. Ненавижу!!!!


default   (2004-06-24 17:54:00) [16]

чудо техника не правда-ли?
пентиум 3, RAM 256, ОС - ME


Sandman25   (2004-06-24 17:53:00) [17]

PIV-2GHz, 510MB, Win2000 Server


jack128   (2004-06-24 17:51:00) [18]

гм... Хз..  А проц/память/ОС не могли бы указать?


default   (2004-06-24 17:41:00) [19]

у меня вообще не мелькает


jack128   (2004-06-24 17:40:00) [20]


> с другой стороны, если поставить
> with PaintBox.ClientToScreen(c) do
>       SetCursorPos(x, y);
> exit;
> в самое начало, то мелькания не будет.  Почему, не понимаю.

? Наверно от машины зависит.. У мя и в этом случае мелькает..


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо