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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 06.01.2017, 14:47
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию KeyStat + Поток

Есть такая проблема, не уверен как ее лучше решить.
Есть ф-я определения зажатия контрола
Код:
var KeyState: Word;
begin
   KeyState := GetKeyState(VK_CONTROL);

  if KeyState and 1 = 1 then
    Result:= False
  else
    Result:=True;
end;
Само по себе все хорошо, но эта проверка происходит в зацикленном потоке и если на время зажать контрол, то оно как бы стакает проверки и когда отпускаешь получается, что долго идет проверка старого состояния. то есть если функция приняла False, То True она примет не когда контрол опушен. как тогда лучше реализовать проверку зажатия CTRL?

Код:
If true then
pause
else 
work

Последний раз редактировалось nixon232, 06.01.2017 в 15:03.
Ответить с цитированием
  #2  
Старый 06.01.2017, 21:29
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

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

Цитата:
Сообщение от nixon232
Код:
var KeyState: Word;
begin
   KeyState := GetKeyState(VK_CONTROL);

  if KeyState and 1 = 1 then
    Result:= False
  else
    Result:=True;
end;
А не проще одной строкой
Код:
Result:= Odd(GetKeyState(VK_CONTROL));
Ответить с цитированием
  #4  
Старый 06.01.2017, 23:26
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

Цитата:
Сообщение от lmikle
Например, проверять состояние в главеом потоке, а в подчиненные потоки просто сообщать об этом. Т.е. не проверять из доп. потока. Похоже, что просто не доходит обновление состояния до потока по какой-то причине.
Да вот все равно как-то никак, либо не так делаю. сделал даже через Property
Код:
 property CTRL: Boolean read GetSCTRL write SetSCTRL default true;
и в потоке Присваиваю, где Canclick - ф-я с первого поста, объявленная в главном потоке
Код:
  ;
   CTRL := CanClick;

    if CTRL then begin
Ответить с цитированием
  #5  
Старый 07.01.2017, 01:27
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,003
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

не важно где объявлена фунция. важно где она вызывается.
Еще раз.
В потоке объявляешь проперти (ну или просто public атрибут, это не принципиально, бо как поток его должен только читать).
В основной программе кидаешь на форму таймер и, например, с задержкой 250 мс (Interval) пишешь примерно такой код:
Код:
procedure TMainForm.Timer1Timer(Sender : TObject);
var
  I : Integer;
  ctrlState : Boolean;
begin
  Timer1.Enabled := False;
  ctrlState := Odd(GetKeyState(VK_CONTROL));
  // Тут проходим по всем потокам (я не знаю как ты хранишь на них ссылки) и устанавливаем свойство
  // Пусть ссылки на потоки хранятся в массиве MyThreads : Array Of TMyThread
  For I := Low(MyThreads) To High(MyThreads) Do 
    MyThreads[i].CTRL := ctrlState;
  Timer1.Enabled := True;
end;
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
nixon232 (07.01.2017)
  #6  
Старый 07.01.2017, 13:34
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

а вы проверяли код? я вон для теста, по вашей аналогии сделал. Даже если пока не трогать поток, то получается, что он реагирует не на ЗАЖАТИЕ,а на НАЖАТИЕ, в этом наверное и проблема
Код:
procedure TForm1.TCtrlTimer(Sender: TObject);
 var
 ctrlstate:Boolean;

begin
  TCtrl.Enabled := False;
ctrlstate:=Odd(GetKeyState(VK_CONTROL));
 // TMThr.ICTR :=ctrlstate;
  // Тут проходим по всем потокам (я не знаю как ты хранишь на них ссылки) и устанавливаем свойство
  // Пусть ссылки на потоки хранятся в массиве MyThreads : Array Of TMyThread
if not ctrlstate then
status.Panels[0].Text:='CTRL!'
else status.Panels[0].Text:='';
  TCtrl.Enabled := True;
end;
Ответить с цитированием
  #7  
Старый 07.01.2017, 14:04
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

Вот решение http://www.delphisources.ru/pages/fa..._key_down.html
Ответить с цитированием
  #8  
Старый 07.01.2017, 14:07
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от nixon232
...получается, что он реагирует не на ЗАЖАТИЕ,а на НАЖАТИЕ...
Тогда и проверять нужно "НАЖАТИЕ" а не "ЗАЖАТИЕ"
Код:
function CtrlDown : Boolean;
var
 State : TKeyboardState;
begin
 GetKeyboardState(State);
 Result := ((State[vk_Control] and 128) <> 0);
end;
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
nixon232 (07.01.2017)
  #9  
Старый 07.01.2017, 14:17
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Alegun
Тогда и проверять нужно "НАЖАТИЕ" а не "ЗАЖАТИЕ"
Код:
function CtrlDown : Boolean;
var
 State : TKeyboardState;
begin
 GetKeyboardState(State);
 Result := ((State[vk_Control] and 128) <> 0);
end;
Именно. На него выше ссылку и дал. Всем спасибо.
Ответить с цитированием
  #10  
Старый 07.01.2017, 20:37
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

И все же основную проблема зависшего статуса кнопки это не решило. Отвисает только если проведешь по форме курсором. Казалось из-за работы с формой, но если ее не трогать, то все так же. Что может быть?

Последний раз редактировалось nixon232, 07.01.2017 в 20:41.
Ответить с цитированием
  #11  
Старый 07.01.2017, 21:34
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Да не видно без кода-то ничего, может из потока пытаетесь текст на статусе изменить, а на это существует табу, мож у вас "шкурка самца" установлена, альфаскин любит глючить, может ещё чего не хватает типа Application.ProcessMessage etc., да всё, что угодно
Ответить с цитированием
  #12  
Старый 08.01.2017, 12:21
nixon232 nixon232 вне форума
Активный
 
Регистрация: 26.01.2014
Сообщения: 282
Версия Delphi: delphi xe4
Репутация: выкл
По умолчанию

Проверяю в потоке (по таймеру все равно не так работало)
Без синхрона на Getstate не хочет работать. Waitme - sleep без фризов интерфейса. Синхроном работает, но только если курсор на форме
Код:
procedure TStateKB.Execute;
begin
while not Terminated do

  GetState;
  WaitMe(300)

end;

procedure TStateKB.GetState;
var State: TKeyboardState; r: Boolean;
begin
Application.ProcessMessages;
  r :=  CtrlDown;
       Win.ctrl:=r;
end;
Ну и проверка как-то так.
Код:
    if CTRL then

            Synchronize(Something);
Еще, до проверки есть
Код:
function EnumWindowsProc(h: HWND; lParam: lParam): Boolean; stdcall;
var CN: array [0 .. 1023] of Char; i: integer; s: string; WndRect: TRect;
begin
  Application.ProcessMessages;
  Result := TRUE;
----
и все работает, независимо где курсор, пока нет искомого окна

Последний раз редактировалось nixon232, 08.01.2017 в 17:00.
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter