Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перемещение картинки мышкой, курсор должен всегда быть посередине 
V
    Опции темы
ALeXandrK
  Дата 11.8.2007, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 3
Всего: 6



Решается избитая задача - передвижение картинки мышкой.
Т.е. кликаем на картинку (TImage) и начинаем её тоскать по форме... где курсор, там и картинка.

Но есть проблема: если курсор передвинуть очень быстро, то он выйдет за пределы картинки 
(если картинка маленькая). Идеальный вариант - это рисовать картинку вместо курсора, но сами
знаете, что нелюбую картинку можно поставить курсором.

Как быть, кто знает??? smile 

P.s.: У меня в программе есть TStringGrid, а его ячейки я рисую сам (цвет, текст). 
Я пытаюсь реализовать перетаскивание ячеек следующим образом: 
  • Кликаем на ячейку
  • Создаем TImage
  • Rect ячейки копирую в TImage
  • TImage двигаю куда нужно
  • ну и копирую Rect из TImage в нужную ячейку
Я бы рат не прорисовывать ничего, а просто вид курсора поменять, но пользователь должен точно знать что он тащит.


P.p.s.:
Метод перетаскивания картинки:
В методе OnMouseMove:

Код

SetBounds(Left+X-Width div 2,Top+Y-Height div 2,Width,height);


Это сообщение отредактировал(а) ALeXandrK - 11.8.2007, 00:45


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
Sanchezzz
  Дата 11.8.2007, 01:40 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 5
Всего: 60



не знаю устроит тебе такой код  но работает четко и без мерцаний 

Код

implementation var
imgflag:boolean;
x0,y0:integer;
{$R *.dfm}


procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if button <> mbLeft then
    imgflag := false
  else
  begin
    imgflag := true;
    x0 := x;
    y0 := y
  end
end;


procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
 begin
if imgflag=true then
  begin
(Sender as TImage).SetBounds((Sender as TImage).Left + x - x0
{div 2 тогда прикольное сочитание получится}, (Sender as TImage).Top + y - y0
{div 2 тогда прикольное сочетание получится}
, (Sender as TImage).width, (Sender as TImage).height);
end;
 end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
imgflag:=false;
end;


Это сообщение отредактировал(а) Sanchezzz - 11.8.2007, 02:07


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
MetalFan
Дата 11.8.2007, 09:19 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Sanchezzz @  11.8.2007,  01:40 Найти цитируемый пост)
implementation var
imgflag:boolean;
x0,y0:integer;

глобальные переменные - зло! тем более тогда, когда можно и без них обойтись


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
ALeXandrK
  Дата 11.8.2007, 11:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 3
Всего: 6



СТОП!
Мерцаний у меня нет! Я от них избавляюсь 
Код

DoubleBuffer:=true;


Вопрос совершенно в другом:
Если резко дернуть курсор, то он убежит с картинки, а он должен оставаться всегда на середине компонента!

Глобальных переменных у меня тоже нет smile 

Само передвижение у меня прекрасно работает!

P.s.:
Sanchezzz: я примерно таким кодом все и двигаю, только глобальных переменных у меня нет smile 

Это сообщение отредактировал(а) ALeXandrK - 11.8.2007, 11:40


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
Sunvas
Дата 11.8.2007, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Соль и сахар
****


Профиль
Группа: Участник
Сообщений: 3388
Регистрация: 12.3.2006
Где: Тосно

Репутация: 28
Всего: 89



Цитата(ALeXandrK @  11.8.2007,  11:38 Найти цитируемый пост)
Если резко дернуть курсор, то он убежит с картинки, а он должен оставаться всегда на середине компонента!

Ты что-то не так делаешь значит. Правильнее всего перемещать картинку - это обрабатывать ее OnMouseMove. Если уж ты "взял" картинку и не "отспускаешь" ее, то где бы не находился курсор (даже за пределами картинки) все равно будет выполняться событие OnMouseMove!


Цитата(MetalFan @  11.8.2007,  09:19 Найти цитируемый пост)
глобальные переменные - зло! тем более тогда, когда можно и без них обойтись

Ммм. Интересно, как ты предлагаешь лучше всего обойтись без глобальных переменных? Ведь все-равно, обрабатывая OnMouseMove, мы должны знать нажата ли левая кнопка в момент перетаскивания.


--------------------
Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их.
PM MAIL   Вверх
ALeXandrK
  Дата 11.8.2007, 13:16 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 3
Всего: 6



У меня наследник от TImage. А код передвижения я сразу реализовал в наследнике.
Так что роль глобальной переменной играет сам созданный экземпляр класса.

Условия при движении я не проверяю. Компонент создан, значит двигаем.


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
Sunvas
Дата 11.8.2007, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Соль и сахар
****


Профиль
Группа: Участник
Сообщений: 3388
Регистрация: 12.3.2006
Где: Тосно

Репутация: 28
Всего: 89



Цитата(ALeXandrK @  11.8.2007,  13:16 Найти цитируемый пост)
 Компонент создан, значит двигаем.

В том-то и проблема.. Если бы ты обрабатывал OnMouseMove после OnMouseDown - за тебя Windows решила бы твою проблему... А в твоем случае решить проблемму удобно невозможно, разве что таймер поможет.


--------------------
Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их.
PM MAIL   Вверх
ALeXandrK
Дата 11.8.2007, 13:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 3
Всего: 6



Цитата

В том-то и проблема.. Если бы ты обрабатывал OnMouseMove после OnMouseDown - за тебя Windows решила бы твою проблему... А в твоем случае решить проблемму удобно невозможно, разве что таймер поможет.

Ну вот. Уже хорошо.

Значит мне нужно каким-то образом вызвать OnMouseDown;
Но как? Если у меня картинка создается при событии OnMouseUp грида.

Прикрепил пример того, что я делаю.

Это сообщение отредактировал(а) ALeXandrK - 11.8.2007, 14:20

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  MovingImage.rar 3,28 Kb


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
Sunvas
Дата 11.8.2007, 15:10 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Соль и сахар
****


Профиль
Группа: Участник
Сообщений: 3388
Регистрация: 12.3.2006
Где: Тосно

Репутация: 28
Всего: 89



Цитата(ALeXandrK @  11.8.2007,  13:40 Найти цитируемый пост)
Значит мне нужно каким-то образом вызвать OnMouseDown;Но как? Если у меня картинка создается при событии OnMouseUp грида.

Попробуй просто послать это сообщение вручную.


--------------------
Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их.
PM MAIL   Вверх
ALeXandrK
Дата 11.8.2007, 15:18 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 3
Всего: 6



Написал вот это:
Код

...
        h := FindWindowEx(Handle, 0, 'TStringGrid', NIL);
        SendMessage(h, WM_MOUSELEAVE, 1, 0);
        h := FindWindowEx(h, 0, 'TMovingCell', NIL);
        SendMessage(h, WM_ACTIVATE, 1, 0);
        SendMessage(h, WM_LBUTTONDOWN, 1, 0);
...


Не помогло.


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
Snowy
Дата 11.8.2007, 15:39 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



А так не пойдёт?
Сделал через фрейм - не люблю компоненты...

Добавлено через 6 минут и 30 секунд
Если очень нужно, чтобы курсор был именно посередине, то поправить кусочек в Unit2 так:
Код
procedure TFrame2.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  BringToFront;
  Left := Left + X - Image1.Width div 2;
  Top := Top + Y - Image1.Width div 2;
  ReleaseCapture;
  Perform(WM_SYSCOMMAND, $F012, 0);
end;


Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  MovingImage.zip 5,71 Kb
PM MAIL   Вверх
ALeXandrK
  Дата 11.8.2007, 16:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 3
Всего: 6



Snowy: Интересное решение, но оно мне все-таки не подходит.

Это сообщение отредактировал(а) ALeXandrK - 11.8.2007, 17:36


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
ALeXandrK
  Дата 11.8.2007, 18:30 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 342
Регистрация: 31.1.2007
Где: Санкт-Петербург

Репутация: 3
Всего: 6



УРА!!! Нашел решение. 
Спасибо всем. Каждый хоть немного, но помог!

Нужны были всего лишь две строчки:
Код

ReleaseCapture;
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);


Т.к. курсор я ставлю посередине при создании картинки, то это событие просто
вызывает левый клик мыши и все идет как нужно smile 

Прикрепляю рабочий пример:

Это сообщение отредактировал(а) ALeXandrK - 11.8.2007, 19:34

Присоединённый файл ( Кол-во скачиваний: 10 )
Присоединённый файл  MovingImage.rar 4,71 Kb


--------------------
Богат не/ни тот, у кого много, а тот, кому хватает
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0576 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.