Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 25.10.2015, 10:05
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
Вопрос Прекращение работы программы

При установке хука на мышь нужно по нажатию левой кнопки выполнять какие-либо действия, а при ее отжатии останавливать выполнение.

Суть проблемы такова: если, к примеру, ставить/снимать "галку" в 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  
Старый 25.10.2015, 12:08
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Поменяйте местами проверки, сначало отжатие и лишь затем жим

З.Ы. Не предназначена ловушка для "тяжёлых" действий, лучше вынести весь спуд в отдельную процедуру с отслеживанием состояния глобального флажка, а вот в обработчике хука запустив её после как раз и управлять этим индикатом, тогда при переключении процедура сама отвалится при изменении состояния

Последний раз редактировалось Alegun, 25.10.2015 в 12:18.
Ответить с цитированием
  #3  
Старый 26.10.2015, 10:28
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Поменяйте местами проверки, сначало отжатие и лишь затем жим
Сути это не поменяло (первое, что попробовал сделать)

Цитата:
Сообщение от Alegun
лучше вынести весь спуд в отдельную процедуру с отслеживанием состояния глобального флажка, а вот в обработчике хука запустив её после как раз и управлять этим индикатом, тогда при переключении процедура сама отвалится при изменении состояния
Понедельник день тяжелый...да и я не особо тру-программист. Поподробней можно, хотя бы что и где читать, что б понять
Ответить с цитированием
  #4  
Старый 26.10.2015, 11:53
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от vers0
...Понедельник день тяжелый...
Полностью согласен с данным утверждением :-) вот рабочий пример выноса "тягомотины" на внешний обработчик с отслеживанием состояния флажка
Код:
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  
Старый 28.10.2015, 08:46
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Полностью согласен с данным утверждением :-) вот рабочий пример выноса "тягомотины" на внешний обработчик с отслеживанием состояния флажка
Благодарю, суть ясна, будем "пилить" Вы меня порадовали лаконичностью ответов...я уж приготовился к коментам вида "у вас фантазии не хватает", "хватит клянчить, книжки читай"
Ответить с цитированием
  #6  
Старый 31.10.2015, 15:06
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
Вопрос

Цитата:
Сообщение от Alegun
на внешний обработчик с отслеживанием состояния флажка

Если пишу так:
Код:
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;
то выдает ошибку "Undeclared identifier: 'RadioGroup1' " и "extended but identifier 'ItemIndex' found". Если выношу обратно (где и было смещение курсора - procedure TForm1.WndProc(var Msg: TMessage), то все нормально. Можете помочь, где я туплю?
И не совсем понял вотэтот участок:
Код:
begin
    flg:= true;
    ExternalWndProc;
   end;

Последний раз редактировалось vers0, 31.10.2015 в 15:09.
Ответить с цитированием
  #7  
Старый 31.10.2015, 15:29
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Undeclared identifier это значит не видно радиокнопки из этой процедуры, вторая ошибка связана с первой и исчезнет, возможно нужно добавить явную указку на родителя компонета (if (MyForm.RadioGroup1.ItemIndex =0)...)
Цитата:
...И не совсем понял...
Сначало устанавливается флаг начала процесса в true, затем процедура запускается - т.к. кнопка уже нажата, в последующий вызов обработчика сообщений формы она снова не запустится пока не будет "отбоя" в виде отлова мессаги типа WM_LBUTTONUP
Ответить с цитированием
  #8  
Старый 31.10.2015, 16:15
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 26
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Сначало устанавливается флаг начала процесса в true, затем процедура запускается - т.к. кнопка уже нажата, в последующий вызов обработчика сообщений формы она снова не запустится пока не будет "отбоя" в виде отлова мессаги типа WM_LBUTTONUP
Это понятно, меня строка ExternalWndProc смущает, можно ли таким образом вызвать из одной процедуры другую?

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

Уже месяц голову лома...заброшу наверное...

Последний раз редактировалось vers0, 31.10.2015 в 16:29.
Ответить с цитированием
  #9  
Старый 31.10.2015, 16:48
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Вызывать можно, этим как раз "эффект разгрузки тяжёлой процедуры" и объясняется - просто сообщения шлются форме постоянно, и если в обработчике задержаться немного, то работающая копия замещается следующей и что-то остановить в прошлой будет довольно трудно

Я проверил предварительно этот код в работе - цикл во внешней процедуре прекрасно обрывается, а как вы там её у себя хотите модернизировать, мне к сожалению, не ведомо
Ответить с цитированием
  #10  
Старый 01.11.2015, 05:47
Аватар для Rerter
Rerter Rerter вне форума
Прохожий
 
Регистрация: 21.09.2015
Адрес: Экибастуз
Сообщения: 11
Версия Delphi: Delphi 7
Репутация: 10
Радость

Попробуй пусть твоя кнопка использует ShellAPI. Вызов другой программы для твоего большого кода выполнения. Тогда и прервать процесс будет легче. Так как другая программа будет выполнять поставленную задачу. Но и нагрузка на отслеживание нажата кнопка мыши или нет легче будет.
__________________
Владение информацией - владение ситуацией...
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 04:18.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025