![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
При установке хука на мышь нужно по нажатию левой кнопки выполнять какие-либо действия, а при ее отжатии останавливать выполнение.
Суть проблемы такова: если, к примеру, ставить/снимать "галку" в CheckBox'e по нажатию/отжатию, то все нормально и быстро, но если прописать по нажатию кнопки что-то более длинноиграющее, то пока полностью не отработает функция - не прекращается. Выносить в отдельный поток не вариант, т.к. пользователь может нажимать кнопку мыши раз в минуту, а может и по 100 раз в секунду (ну, если пальцы не отвалятся )Как прервать на произвольном месте и при повторном нажатии запустить заново? Код:
procedure TForm1.WndProc(var Msg: TMessage);
if (Msg.Msg = MWM_LBUTTONDOWN) then
begin
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X+5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X+5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X+5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X+5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X+5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
end;
if (Msg.Msg = MWM_LBUTTONUP) then
begin
Exit;
end;
initialization
MWM_LBUTTONDOWN := RegisterWindowMessage('MWM_LBUTTONDOWN');
MWM_LBUTTONUP := RegisterWindowMessage('MWM_LBUTTONUP');
end. |
|
#2
|
||||
|
||||
|
Поменяйте местами проверки, сначало отжатие и лишь затем жим
З.Ы. Не предназначена ловушка для "тяжёлых" действий, лучше вынести весь спуд в отдельную процедуру с отслеживанием состояния глобального флажка, а вот в обработчике хука запустив её после как раз и управлять этим индикатом, тогда при переключении процедура сама отвалится при изменении состояния Последний раз редактировалось Alegun, 25.10.2015 в 12:18. |
|
#3
|
|||
|
|||
|
Цитата:
Цитата:
![]() |
|
#4
|
||||
|
||||
|
Цитата:
Код:
type
TForm1 = class(TForm)
...
procedure WndProc(var Msg: TMessage); override;
procedure ExternalWndProc;
...
var
Form1: TForm1;
flg: bool;
...
procedure TForm1.ExternalWndProc;
var
p: TPoint;
i: integer;
begin
for i:=0 to 100 do
if flg then
begin
GetCursorPos(p);
SetCursorPos(p.X-5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
GetCursorPos(p);
SetCursorPos(p.X+5, p.Y+5);
Sleep(85);
Application.ProcessMessages;
end
else exit;
end;
procedure TForm1.WndProc(var Msg: TMessage);
begin
inherited;
case Msg.Msg of
WM_LBUTTONDOWN:
begin
flg:= true;
ExternalWndProc;
end;
WM_LBUTTONUP: flg:= false;
end; {case}
end; |
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
vers0 (31.10.2015)
| ||
|
#5
|
|||
|
|||
|
Цитата:
Вы меня порадовали лаконичностью ответов...я уж приготовился к коментам вида "у вас фантазии не хватает", "хватит клянчить, книжки читай" ![]() |
|
#6
|
|||
|
|||
|
Цитата:
Если пишу так: Код:
procedure TForm1.ExternalWndProc;
begin
if (RadioGroup1.ItemIndex=0) and (ComboBox1.ItemIndex=4) then
begin
GetCursorPos(p);
SetCursorPos(p.X+5, p.Y+5);
...
end
else exit;
end; , то все нормально. Можете помочь, где я туплю?И не совсем понял вотэтот участок: Код:
begin
flg:= true;
ExternalWndProc;
end;Последний раз редактировалось vers0, 31.10.2015 в 15:09. |
|
#7
|
||||
|
||||
|
Undeclared identifier это значит не видно радиокнопки из этой процедуры, вторая ошибка связана с первой и исчезнет, возможно нужно добавить явную указку на родителя компонета (if (MyForm.RadioGroup1.ItemIndex =0)...)
Цитата:
|
|
#8
|
|||
|
|||
|
Цитата:
Так же не работает программа (вернее работает, но при отжатии не происходит прерывание, а полностью отрабатывает все смещения), но при этом еще и начало игнорить кнопку, при нажатии на которую запускался хук мыши. Уже месяц голову лома...заброшу наверное... Последний раз редактировалось vers0, 31.10.2015 в 16:29. |
|
#9
|
||||
|
||||
|
Вызывать можно, этим как раз "эффект разгрузки тяжёлой процедуры" и объясняется - просто сообщения шлются форме постоянно, и если в обработчике задержаться немного, то работающая копия замещается следующей и что-то остановить в прошлой будет довольно трудно
Я проверил предварительно этот код в работе - цикл во внешней процедуре прекрасно обрывается, а как вы там её у себя хотите модернизировать, мне к сожалению, не ведомо |
|
#10
|
||||
|
||||
|
Попробуй пусть твоя кнопка использует ShellAPI. Вызов другой программы для твоего большого кода выполнения. Тогда и прервать процесс будет легче. Так как другая программа будет выполнять поставленную задачу. Но и нагрузка на отслеживание нажата кнопка мыши или нет легче будет.
|