PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » PureBasic для Windows » Как сделать задержку срабатывания нажатой клавиши


Как сделать задержку срабатывания нажатой клавиши

Сообщений 1 страница 22 из 22

1

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

0

2

Можно запустить таймер или поток и через нужное время проверить функцией GetKeyState нажата ли клавиша.

0

3

а как таймер один раз запустить, и таймер должен сброситься если клавишу раньше отпустить
у меня огород получается и всё равно правильно не работает

0

4

newJS написал(а):

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

В процедуре вызываемой таймером, отключаете его. Там же проверяете нажата ли кнопка.

0

5

Пётр, если бы я понял как это сделать, не стал бы спрашивать

так работает, но неправильно, срабатывает в разное время
а как сделать правильно, фантазия кончилась

Код:
EnableExplicit

Procedure win()
Protected ev
OpenWindow(1234, 870, 640, 400, 300, "text")
AddWindowTimer(1234, 123, 1000)

Repeat
ev=WaitWindowEvent()

If GetAsyncKeyState_(#VK_ESCAPE)=32768
If ev = #PB_Event_Timer And EventTimer() = 123
Break
EndIf
EndIf

Until ev=#PB_Event_CloseWindow

EndProcedure

win()

0

6

После нажатия кнопки, запускаете таймер. После срабатывания таймера, останавливаете его.

Код:
EnableExplicit

Procedure win()
  Protected ev, TimOn=#False
  OpenWindow(1234, 870, 640, 400, 300, "text")
  
  Repeat
    ev=WaitWindowEvent(100)
    
    If TimOn=#False And GetAsyncKeyState_(#VK_ESCAPE)=32768
      TimOn=#True
      AddWindowTimer(1234, 123, 1000)
    EndIf
    
    If ev = #PB_Event_Timer And EventTimer() = 123
      RemoveWindowTimer(1234, 123)
      TimOn=#False
      Debug "Таймер"
    EndIf
    
  Until ev=#PB_Event_CloseWindow
EndProcedure

win()

0

7

спасибо, теперь как надо
флаг пробовал, запускать/удалять таймер пробовал, но почему то получался большой не работающий огород

0

8

у меня код немного отличался, изначально не туда свернул, потому и не работал
спасибо Пётр, показал куда надо идти :crazyfun:
вот вариант API

Код:
EnableExplicit
Global timer

Procedure myCallback(hwnd, msg, wParam, lParam) 
Protected res
res = #PB_ProcessPureBasicEvents
Select msg
Case #WM_CHAR
If timer=#False And wParam=#VK_ESCAPE
timer=#True
SetTimer_(WindowID(1234), 123, 1000, 0)
EndIf

Case #WM_TIMER
KillTimer_(WindowID(1234), 123)
timer=#False
End

EndSelect; msg
ProcedureReturn res
EndProcedure

Procedure win()
Protected ev
OpenWindow(1234, 870, 640, 400, 300, "text")
SetWindowCallback(@MyCallback())

Repeat
ev=WaitWindowEvent()
Until ev=#PB_Event_CloseWindow
EndProcedure

win()

0

9

неправильный код, срабатывает при коротком нажатии, таймер то сразу запускается, надо его выключать если клавишу раньше отпустили
так заработало

Код:
Procedure win()
Protected ev, TimOn=#False
OpenWindow(1234, 870, 640, 400, 300, "text")

Repeat
ev=WaitWindowEvent(100)
If TimOn=#False And GetAsyncKeyState_(#VK_ESCAPE)=32768
Debug "1 "+Bool(GetAsyncKeyState_(#VK_ESCAPE)=32768)
TimOn=#True
AddWindowTimer(1234, 123, 1000)
ElseIf  TimOn=#True And GetAsyncKeyState_(#VK_ESCAPE)=0
Debug "2"
RemoveWindowTimer(1234, 123)
TimOn=#False
ElseIf ev = #PB_Event_Timer And EventTimer() = 123
Debug "3 "+Bool(GetAsyncKeyState_(#VK_ESCAPE)=32768)
RemoveWindowTimer(1234, 123)
TimOn=#False
Break
EndIf
Until ev=#PB_Event_CloseWindow
Debug "save"
EndProcedure

win()

0

10

Функция

Пётр написал(а):

GetKeyState

эта и ей подобные вдруг стали популярными в последнее время  :D

0

11

newJS написал(а):

а как таймер один раз запустить, и таймер должен сброситься если клавишу раньше отпустить
у меня огород получается и всё равно правильно не работает

Используейте счетчики и флаги состояния, я когдато на контроллере писал прогу для дребезга контактов и анализа скорости
повторного ввода буквы при долгом нажатии кнопки. Помогло.
Если нажата кнопка то считаем количество времени, если прошо то зачет, меняем флаг и сокращаем время ожидания,
это делает повтор ввода буквы быстрее. Пустили клаву, флаги сбросили в исходное состояние.

0

12

newJS написал(а):

у меня код немного отличался, изначально не туда свернул, потому и не работал

Иногда полезно форматировать код проги, тогда видно начало и конец условий, циклов и пречего.
И ошибки иногда виднее.

Я про одступы в виде табуляций.

0

13

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

0

14

последняя модернизация, но таки всё равно нет гарантии что не закроется ещё одно окно, но ложные закрытия уменьшились, теперь надо постараться

Код:
If SendMessage_(chk("esc1")\hwnd, #BM_GETCHECK, 0, 0)=#BST_CHECKED And GetForegroundWindow_()=ws\hwnd
If timOut=#False And GetAsyncKeyState_(#VK_ESCAPE)=32768
timOut=#True
AddWindowTimer(ws\num, 123, sESC)
ElseIf  timOut=#True And GetAsyncKeyState_(#VK_ESCAPE)=0
RemoveWindowTimer(ws\num, 123)
timOut=#False
ElseIf ev = #PB_Event_Timer And EventTimer() = 123
RemoveWindowTimer(ws\num, 123)
timOut=#False
Break
EndIf
EndIf

0

15

Если у вас окно, то самым надёжным будет AddKeyboardShortcut() и он не будет распространять нажатие Esc на следующие окна, так как поглотит событие.

0

16

Насчет нажатия Escape - я делал иначе.

Код:
    Repeat 
      ev=WaitWindowEvent()
      If GetAsyncKeyState_(#VK_ESCAPE)&32768;=-32767
        Break
      EndIf
      Select ev
        Case #PB_Event_Menu
          Select EventMenu()
            Case 1:
              I$ = UCase( InputRequester("insert char", "enter number($ for hex)", "") )
              While GetAsyncKeyState_(#VK_ESCAPE)&32768
              Wend

Смысл в том, что после вызова Requester добавлен опрос нажатия той же клавиши - пользователь может нажать Escape, чтобы закрыть диалоговое окно, но это нажатие не должно распространиться на цикл опроса событий.

0

17

сколько хозяек, столько борщей  :crazyfun:

посмотрим как твоя версия работает

0

18

предыдущая самая правильная версия имеет один недостаток
если есть несколько окон и у них небольшая задержка
то немного придержав клавишу можно было закрыть несколько окон

ещё одна самая правильная версия  :crazyfun:
в этой версии в отличии от предыдущей невозможно одним нажатием закрыть несколько окон
так как срабатывает на отпускание
но здесь случайное нажатие гарантировано закроет окно :dontknow:
возможно придётся спаривать две версии, время покажет

Код:
Procedure senior()
Protected ev
If OpenWindow(1234, 870, 640, 400, 300, "text")

Repeat
ev=WaitWindowEvent()
Select ev
Case #WM_KEYUP
;Debug 2
If GetAsyncKeyState_(#VK_ESCAPE)&1
;Debug 3
Break
EndIf
EndSelect
Until ev=#PB_Event_CloseWindow
EndIf
EndProcedure

senior()


0

19

newJS написал(а):

предыдущая самая правильная версия имеет один недостаток
если есть несколько окон и у них небольшая задержка
то немного придержав клавишу можно было закрыть несколько окон

ещё одна самая правильная версия  
в этой версии в отличии от предыдущей невозможно одним нажатием закрыть несколько окон
так как срабатывает на отпускание
но здесь случайное нажатие гарантировано закроет окно 
возможно придётся спаривать две версии, время покажет

Не фунциклирует:

Код:
  If OpenWindow(0, 0, 0, 300, 30, "Position of the mouse on the desktop", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(0, 10, 6, 200, 20, "OK")
    
    Repeat
      Event = WaitWindowEvent()
        Select Event
     Case #WM_KEYUP
If GetAsyncKeyState_(#VK_ESCAPE)&1
Break
EndIf
       Case #PB_Event_Gadget
         Select EventGadget()
           Case 0
  StandardFile$ = "D:\"   ; set initial file+path to display
  ; With next string we will set the search patterns ("|" as separator) for file displaying:
  ;  1st: "Text (*.txt)" as name, ".txt" and ".bat" as allowed extension
  ;  2nd: "PureBasic (*.pb)" as name, ".pb" as allowed extension
  ;  3rd: "All files (*.*) as name, "*.*" as allowed extension, valid for all files
  Pattern$ = "Text (*.txt)|*.txt;*.bat|PureBasic (*.pb)|*.pb|All files (*.*)|*.*"
  Pattern = 0    ; use the first of the three possible patterns as standard
  File$ = OpenFileRequester("Please choose file to load", StandardFile$, Pattern$, Pattern)
;   If File$
;     MessageRequester("Information", "You have selected following file:" + Chr(10) + File$, 0)
;   Else
;     MessageRequester("Information", "The requester was canceled.", 0) 
;   EndIf
         EndSelect
     EndSelect
   
     
    Until Event = #PB_Event_CloseWindow
  EndIf

смысл кода: появляется диалоговое окно открытия файла, я жму Esc и окно закрывается.

У меня вышло совсем другое - были открыты два окна разных программ. Нажал Esc и оба окна закрылись.

0

20

Код:
  If OpenWindow(0, 0, 0, 300, 50, "Position of the mouse on the desktop", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ButtonGadget(0, 0, 0, 200, 20, "OK")
    If CreateMenu(0, WindowID(0))
     MenuTitle("Menu")
     MenuItem(1, "quit Esc")
AddKeyboardShortcut(0,#VK_ESCAPE,1)
   EndIf
   
    Repeat
      Event = WaitWindowEvent()
        Select Event
;      Case #WM_KEYUP
; If GetAsyncKeyState_(#VK_ESCAPE)&1
; Break
; EndIf/
       Case #PB_Event_Menu
         Select EventMenu()
           Case 1 : Break

         EndSelect

       Case #PB_Event_Gadget
         Select EventGadget()
           Case 0
  StandardFile$ = "D:\"   ; set initial file+path to display
  ; With next string we will set the search patterns ("|" as separator) for file displaying:
  ;  1st: "Text (*.txt)" as name, ".txt" and ".bat" as allowed extension
  ;  2nd: "PureBasic (*.pb)" as name, ".pb" as allowed extension
  ;  3rd: "All files (*.*) as name, "*.*" as allowed extension, valid for all files
  Pattern$ = "Text (*.txt)|*.txt;*.bat|PureBasic (*.pb)|*.pb|All files (*.*)|*.*"
  Pattern = 0    ; use the first of the three possible patterns as standard
  File$ = OpenFileRequester("Please choose file to load", StandardFile$, Pattern$, Pattern)
;   If File$
;     MessageRequester("Information", "You have selected following file:" + Chr(10) + File$, 0)
;   Else
;     MessageRequester("Information", "The requester was canceled.", 0) 
;   EndIf
         EndSelect
     EndSelect
   
     
    Until Event = #PB_Event_CloseWindow
  EndIf

с меню работает

0

21

поменял обработку на #wm_keydown - пока что работает.

0

22

да, с мессагой закрывается, и это непонятно, не должно

egons написал(а):

поменял обработку на #wm_keydown - пока что работает.

ну и почему? в чём разница, на нажатие или отпускание
а на нажатие даже удобней

egons написал(а):

с меню работает

само меню совсем не обязательно

пробовал на апи сделать закрытие, ругается на репеат, говорит что репеат без окна остался
что тут федя накрутил, как получается что окно отдельно
ну и винда кривая, вот и гадаем где собака зарыта

0


Вы здесь » PureBasic - форум » PureBasic для Windows » Как сделать задержку срабатывания нажатой клавиши