| Autor | Správa |
vama
 Užívateľ
 Založený: 20.11.2009 Príspevky: 213 Bydlisko: Myjava Vek: 19
 | Zaslal: Št 07.01.10 13:50 |   |
Ako mam v Delphi urobit aplikaciu aby sa vykonal (jeden) prikaz len pri stlaceni prislusnych dvoch tlacidiel?
Napr.: Stlacim LEFT + UP a vyskoci mi sprava (showmessage). Ked stlacim LEFT tak mi ina vyskoci |
| |
    |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 908
 | Zaslal: Št 07.01.10 14:19 |   |
Na to, aby sa mohla zisťovať štatistiky klávesnice, je nutné použiť buď timer, alebo háky (hooks) - to je ale trocha komplikované na tak jednoduché použitie. Takže pomocou timeru by sa to dalo napríklad takto:
| kód: | procedure TForm1.Timer1Timer(Sender: TObject);
begin
if ( ((GetKeyState(VK_UP) and 128) = 128) and ((GetKeyState(VK_LEFT) and 128) = 128) ) then
ShowMessage('ok');
end; |
Ten timer nech má interval okolo 20 ms.
Existuje viacero možností pre monitorovanie stlačených klávesov, ale ja používam túto funkciu. Neviem presne, čo konkrétne má obsluhovať, takže možno nebude vyhovovať. (Napríklad, ak bude kombinácia klávesov stlaćená príliš dlho, ShowMessage sa vyvolá viackrát. |
| |
   |
 |
vama
 Užívateľ
 Založený: 20.11.2009 Príspevky: 213 Bydlisko: Myjava Vek: 19
 | Zaslal: Št 07.01.10 14:33 |   |
... no ono to nema obsluhovat ShowMessage, to bol iba taky priklad, obsluhovat to bude prenos cez RS232. Ale praveze to je dobre pocas celeho stlacenia, ze to bude znovu vyvolavane. A tych 128 co znamena ?
A ten soft sa neda urobit ako pri stlaceni 1 tlacidlom, nejakym ANDom?
| kód: | procedure TForm1.FormKeyDown(Sender:TObject; var Key:Word;
Shift:TShiftState);
begin
case Key of
vk_left:
vk_right:
end;
end;
|
|
| |
    |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 908
 | Zaslal: Št 07.01.10 14:55 |   |
Tvoj kód bude fungovať, iba ak formulár bude mať focus (zameranie). Ak bude mať focus nejaký ovládací prvok na forme, tak to nepôjde.
and 128 znamená ...
| citácia: | | If the high-order bit is 1, the key is down |
..., že z návratovej hodnoty "vyberieme" ôsmy bit (to je to "and 128" -- 128 je v binárnej sústave 10000000). Ak je ôsmy bit 1 (čize 10000000), tak kláves je stlačený (to je to "= 128" ). |
| |
   |
 |
vama
 Užívateľ
 Založený: 20.11.2009 Príspevky: 213 Bydlisko: Myjava Vek: 19
 | Zaslal: Št 07.01.10 15:09 |   |
Dobre tak diky za rady. Uz som to skusal ide to.
A keby som nieco ine potreboval urobit, tak sa chcem este opytat ako sa to da urobit cez ten AND co som hore pisal pretoze mi to vobec nevyskoci:
| kód: |
case Key of
(vk_left) and (vk_up): ShowMessage('ok');
end;
|
|
| |
    |
 |
vama
 Užívateľ
 Založený: 20.11.2009 Príspevky: 213 Bydlisko: Myjava Vek: 19
 | Zaslal: Št 07.01.10 15:21 |   |
Este by som potreboval dalsi prikaz ktory by sa vykonal po pusteni tych dvoch tlacidiel |
| |
    |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 908
 | Zaslal: Št 07.01.10 15:34 |   |
Udalosť OnKeyDown sa spustí iba pri stlačení klávesu, tzn., keď je stlačený, už táto udalosť neprebehne. Táto udalosť vo svojom parametri Key nevracia štatistiku stlačených klávesov, takže vykoná sa pri každom stlačenom klávese IBA raz. Aj keď sa možno zdá, že užívateľ stlačí naraz dve klávesy, ale vždy prebehne táto udalosť najprv s jednou virtuálnou hodnotou klávesy v parametri a potom s druhou ==> nedá sa použiť akási kompinácia pomocu AND. A okrem toho stále platí, že kláves by sa zaznamenal, iba ak na forme nie je nejaké tlačidlo, edit, memo, atď (pretože automaticky by dostali focus).
| vama napísal: | | Este by som potreboval dalsi prikaz ktory by sa vykonal po pusteni tych dvoch tlacidiel |
Namiesto ShowMessage to zobrazí do Memo, pre lepší prehľad, takže ho treba pridať na form.
| kód: | procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (not push_down) then
if ((GetKeyState(VK_LEFT) and 128 = 128) and (GetKeyState(VK_UP) and 128 = 128)) then
begin
push_down:= true;
Memo1.Lines.Add('stlačené');
end;
if (push_down) then
if ((GetKeyState(VK_LEFT) and 128 = 0) and (GetKeyState(VK_UP) and 128 = 0)) then
begin
push_down:= false;
Memo1.Lines.Add('pustené');
end;
end; |
Premenná push_down je na začiatku inicializovaná ako false (napríklad v OnCreate formulára) |
| |
   |
 |
M.Valasek
 Zablokovaný užívateľ
 Založený: 08.10.2007 Príspevky: 70 Bydlisko: Myjava
 | Zaslal: Št 07.01.10 15:57 |   |
Cize to pustenie je vyriesene FLAGom (priznakom) |
| |
  |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 908
 | Zaslal: Št 07.01.10 16:01 |   |
Pri pustení je ôsmy bit návratovej hodnoty GetKeyState nastavený na nulu, preto tam je "if GetKeyState(...) and 128 = 0". To signalizuje uvoľnenie klávesu. |
| |
   |
 |
vama
 Užívateľ
 Založený: 20.11.2009 Príspevky: 213 Bydlisko: Myjava Vek: 19
 | Zaslal: Št 07.01.10 16:06 |   |
a to -- push_down -- je tam na co? |
| |
    |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 908
 | Zaslal: Št 07.01.10 16:10 |   |
No veď tá premenná signalizuje, či je kláves stlačený (push_down = true) alebo či je uvoľnený (push_down = false). |
| |
   |
 |
M.Valasek
 Zablokovaný užívateľ
 Založený: 08.10.2007 Príspevky: 70 Bydlisko: Myjava
 | Zaslal: Št 07.01.10 16:13 |   |
a tu premennu treba deklarovat push_down ? |
| |
  |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 908
 | Zaslal: Št 07.01.10 16:20 |   |
| Fico napísal: | | Premenná push_down je na začiatku inicializovaná ako false (napríklad v OnCreate formulára) |
Keď je false, tak je zrejme boolean, nie? Ale pre istotu to radšej rozpíšem:
| kód: | var
push_down: boolean = false; |
|
| |
   |
 |
M.Valasek
 Zablokovaný užívateľ
 Založený: 08.10.2007 Príspevky: 70 Bydlisko: Myjava
 | Zaslal: Št 07.01.10 16:30 |   |
Dobre vsetko uz chapem. Robim totiz SOCu a taku premakanejsiu robot stopar, s moznostou dialkoveho ovladania a dokonca aj ovladanie cez PC joystickom. Vsetko som si sam vymyslal - schemu, programovanie mikrokontrolera,.. a nakoniec som este toto potreboval co si mi poradil ty.
Velmi ty dakujem a aj na zaver SOCky ty podakujem. Ak budes chciet vidiet toho robota ked bude dokoncety poslem ti foto + video. |
| |
  |
 |
vama
 Užívateľ
 Založený: 20.11.2009 Príspevky: 213 Bydlisko: Myjava Vek: 19
 | Zaslal: So 06.02.10 11:30 |   |
Este by som sa chcel opytat, ta detekcia tlacidiel dala by sa urobit cez podmienku CASE?
Ze by som pre kazde tlacidlo nemusel davat podmienku IF:
| kód: |
IF ((GetKeyState(VK_UP) and 128) = 128) then // pri stlaceni UP
zapis('vpred'); // vyvola proceduru
IF ((GetKeyState(VK_DOWN) and 128) = 128) then // pri stlaceni DOWN
zapis('vzad'); // vyvola proceduru
|
|
| |
    |
 |
|