Jak poprawnie sprawdzić wciśnięcie klawisza (GetKeyState) w TTimer?

0
var
  wykonano_polecenie: Boolean = false;

procedure TForm1.Timer1Timer(Sender: TObject); //timer ustawiłem na 800ms
var
  i: Integer;
  k: Integer;
begin
  k := GetKeyState(VK_OEM_MINUS);

  if k < 0 then //wcisniety
  begin
    Form1.Caption := 'wcisniety';
    if not wykonano_polecenie then ShowMessage(IntToStr(Random(1000)));
    wykonano_polecenie := True;
  end else //puszczony
    begin
      Form1.Caption := 'puszczony';
      wykonano_polecenie := False;
    end;
end;

Nie rozumiem dlaczego gdy przytrzymam przycisk MINUS przez chwilę to wykonuje się kilka razy ShowMessage (timer ustawiony na 800 ms).
Przecież zaraz po ShowMessage() program ustawia zmienną boolean na True i tym samym jak timer drugi raz się wykonuje to powinien mieć mieć w zmiennej wartość TRUE i nie spełnić warunku, a spełnia.

A nawet jak wywalę kod pod ELSE to i tak ShowMessage() wykona się wiele razy przy trzymaniu minusa, choć jak byk ma rozkaz ustawić boolean na true po jednym wykonaniu ShowMessage().

Proszę o znalezienie błędu w tym kodzie.

ten Timer może jakiś zbugowany jest? Dopisałem pod ShowMessage() linijkę:

Timer1.Enabled := False;

A on i tak mi wykonuje spam ShowMessage() tak długo aż nie puszczę klawisza i dopiero wtedy się wyłącza, a przecież powinien wyłączyć się po JEDNYM showmessage!

Już chyba wiem o co chodzi. ShowMessage() tworzy nowe okno i chyba ono buguje Timera, bo jak ShowMessage wywalę i dam by dodawał nowe linie do TMemo to wtedy dodaje tylko jedną linijkę i koniec i działa prawidłowo. Pozostaje więc pytanie dlaczego okno ze ShowMessage robi taki bug?

0

Powinieneś raczej robić to w wątku i to czy coś jest trzymane sprawdza się nieco inaczej. Teraz nie piszę z PC. Jednak jeśli uważnie pogoglujesz to znajdziesz choćby nową wersję mojego pluginu dla XMPlay do obsługi klawiszy multimedialnych. Przeanalizuj sobie jego kod źródłowy, który w oryginale służył w Cheat Engine do globalnej obsługi hotkey'ów.

0

Aha, to wrzuć później link do swojego źródła pluginu jak chcesz lub wytnij z niego ten kawałek kodu i wklej tutaj, będę wdzięczny. Ogólnie to ze 4 klawisze potrzebuję sprawdzać z okna dowolnej aplikacji.

0

Konkretny przykład to dopiero jutro wieczorem najwyżej. Zamiast czekać, o wiele szybciej założysz konto na forum XMPlay'a, pobierzesz zip i sobie przeanalizujesz kod.

0

@olesio a daj nazwę tego pluginu, bo bez nazwy ciężko znaleźć

ok znalazłem chyba http://www.un4seen.com/forum/?topic=12499.0;hl=key

0

No znalazłeś, ale czy tak trudno wpisać w Google słowa '"xmplay olesio" bez cudzysłowiów?

0

Właśnie rzuciłem okiem na kod, ale tak w kilka sekund. Wystarczyło napisać RegisterHotKey i już bym wiedział :)

np.
w **OnCreate **Formy:

RegisterHotKey(Handle, 101, 0, Ord('A')); {"A" w ascii jest jako 65, btw. http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx }

**OnDestroy **Formy:

UnregisterHotKey(Handle, 101);

pod private:

procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;

i przy tej linijce wciskamy CTR + SHIFT + C by utworzyło nam kod procedury i w niej wrzucamy:

case Msg.HotKey of
101: //kod jakis
end;

to chyba tyle. Fajnie, że nie trzeba dwóch przycisków wciskać by hotkey działał. Dzięki za pomoc. Temat można zamknąć.

0

Muszę tutaj dodac, że RegisterHotKey zadziałają globalnie tylko jeżli użyjemy w sekcji uses mojego modułu global_hotkeys po Windows. Ponieważ normalnie ta funkcja API służy do rejestracji HotKeyów tylko w obrębie własntj aplikacji. To tak dla ścisłości. A najprościej trzymanie na przykład obojętnie którego klaiwsza Control sprawdzisz w następujący sposób:

        ControlKeyDown := GetAsyncKeyState(VK_CONTROL) shr ((SizeOf(SHORT) * 8) - 1) <> 0;

1 użytkowników online, w tym zalogowanych: 0, gości: 1