|
#1
|
|||
|
|||
KeyStat + Поток
Есть такая проблема, не уверен как ее лучше решить.
Есть ф-я определения зажатия контрола Код:
var KeyState: Word; begin KeyState := GetKeyState(VK_CONTROL); if KeyState and 1 = 1 then Result:= False else Result:=True; end; Код:
If true then pause else work Последний раз редактировалось nixon232, 06.01.2017 в 15:03. |
#2
|
|||
|
|||
Например, проверять состояние в главеом потоке, а в подчиненные потоки просто сообщать об этом. Т.е. не проверять из доп. потока. Похоже, что просто не доходит обновление состояния до потока по какой-то причине.
|
#3
|
||||
|
||||
Цитата:
Код:
Result:= Odd(GetKeyState(VK_CONTROL)); Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#4
|
|||
|
|||
Цитата:
Код:
property CTRL: Boolean read GetSCTRL write SetSCTRL default true; Код:
; CTRL := CanClick; if CTRL then begin |
#5
|
|||
|
|||
не важно где объявлена фунция. важно где она вызывается.
Еще раз. В потоке объявляешь проперти (ну или просто 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
|
|||
|
|||
а вы проверяли код? я вон для теста, по вашей аналогии сделал. Даже если пока не трогать поток, то получается, что он реагирует не на ЗАЖАТИЕ,а на НАЖАТИЕ, в этом наверное и проблема
Код:
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
|
|||
|
|||
|
#8
|
||||
|
||||
Цитата:
Код:
function CtrlDown : Boolean; var State : TKeyboardState; begin GetKeyboardState(State); Result := ((State[vk_Control] and 128) <> 0); end; Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
nixon232 (07.01.2017)
|
#9
|
|||
|
|||
Цитата:
|
#10
|
|||
|
|||
И все же основную проблема зависшего статуса кнопки это не решило. Отвисает только если проведешь по форме курсором. Казалось из-за работы с формой, но если ее не трогать, то все так же. Что может быть?
Последний раз редактировалось nixon232, 07.01.2017 в 20:41. |
#11
|
||||
|
||||
Да не видно без кода-то ничего, может из потока пытаетесь текст на статусе изменить, а на это существует табу, мож у вас "шкурка самца" установлена, альфаскин любит глючить, может ещё чего не хватает типа Application.ProcessMessage etc., да всё, что угодно
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#12
|
|||
|
|||
Проверяю в потоке (по таймеру все равно не так работало)
Без синхрона на 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. |