symulowanie wcisniecia klawiszy [naprawde nikt nie wie? :(]

0

Mam maly klopot z symulowaniem wcisniecia kombinacji klawiszy. Otoz pobralem z dzialu Delphi unit Sendkeys (w sumie nie wiem po co) i sie nim bawilem, potem z sama f-cja Keybd_Event i efekt byl totalnie beznadziejny. Testowalem sobie, ze po nacisnieciu buttona sumulowana jest kombinacja ctrl alt del. Efektu zadnego (okno nie wyskakuje), ale system zachowywal sie totalnie dziwnie.

Moim celem jest, aby programowo wmowic systemowi, ze uzytkownik wcisnal na klawiaturze np. ctrl alt s, a inne aplikacje skojarzone z tymze skrotem zareaguja na niego odpowiednio. Robil ktos cos podobnego?

Aha, skorzystalem oczywiscie z wyszukiwarki :), ale natrafilem jedynie na masowe posty Szymka (wymagala tego masowa ilosc pytan o zwiazane z tym zagadnienie) o tresci "Keybd_Event" :).

dopisane:
na msdn znalazlem informacje, ze dla systemow NT/2000/XP nalezy uzywac f-cji SendInput. Ja uzywam wlasnie win 2000, wiec mozliwe ze to bylo przyczyna moich problemow, ale dalej nie jestem pewien czy efekt o jaki mi chodzi jest mozliwy do uzyskania tak prosta droga.

dopisane #2:
odpalilem kod ktory znalazlem na swissdelphicenter wykorzystujacy SendInput - mial symulowac wcisniecie kombinacji alt+tab. Efekt - prawie ze zwis kompa ;-|

0

Odpowiedz masz w tematach jak wcisnac enter itp tam jest to mozliwe wystarczy uzyc 2 klawiszy kodow i masz efekt ten o ktorym mowisz :-) i to dzialajacy , cos zle wykonujesz skoro Ci sie wydaje ze nie dziala :-) bo dziala na 100%

0

Tu masz dwie procedury do symulacji wciśnięcia i wyciśnięcia klawisza z użyciem SendInput oraz przykład symulacji Alt-TAB:


Procedure SymulujKeyDown(Key: Cardinal);
  Var
  Input: tagINPUT;
 Begin
  Input.Itype:=INPUT_KEYBOARD;
  Input.ki.wVK:=Key;
  Input.ki.wScan:=MapVirtualKey(Key, 0);

  If Key in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME,
             VK_END, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE]
    then Input.ki.dwFlags:=KEYEVENTF_EXTENDEDKEY
    else Input.ki.dwFlags:=0;
  Input.ki.time:=0;
  SendInput(1, Input, SizeOf(Input));
 end;

Procedure SymulujKeyUp(Key: Cardinal);
  Var
  Input: tagINPUT;
 Begin
   Input.Itype:=INPUT_KEYBOARD;
   Input.ki.wVK:=Key;
   Input.ki.wScan:=MapVirtualKey(Key, 0);

   If Key in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME,
              VK_END, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE]
     then Input.ki.dwFlags:=KEYEVENTF_KEYUP or KEYEVENTF_EXTENDEDKEY
     else Input.ki.dwFlags:=KEYEVENTF_KEYUP;
   Input.ki.time:=0;
   SendInput(1, Input, SizeOf(Input));
 end;

Egzampl:

procedure TForm1.Button1Click(Sender: TObject);
begin
  SymulujKeyDown(VK_LMENU); //lewy Alt

 SymulujKeyDown(VK_TAB); 
 Sleep(500);
 SymulujKeyUp(VK_TAB);

 SymulujKeyDown(VK_TAB);
 Sleep(500);
 SymulujKeyUp(VK_TAB);

 SymulujKeyDown(VK_TAB);
 Sleep(500);
 SymulujKeyUp(VK_TAB);

 SymulujKeyDown(VK_TAB);
 Sleep(500);
 SymulujKeyUp(VK_TAB);

  SymulujKeyUp(VK_LMENU);
end;

Pzdr.
Marogo

0

Marogo: dziękuję za Twój kod, bo to pierwsze proste rozwiązanie, które działa
również w grach pod DirectX. Jednak co ciekawe działają strzałki, działa enter
lecz za nic nie mogę wymusić zasymulowania wciśnięcia prawego controla - w
oknie emulatora WinUAE. Robiłem tak jak poniżej, tylko zmieniałem AKey na:
VK_CONTROL, VK_RĆONTROL i nic, w sumie chciałbym mieć także możliwość
zasymulowania wciśnięcia oraz puszczenia klawisza prawy Control, ktory przy
ustawieniu emulacji joysticka na layout B służy jako Fire. Skoro już taki dość
stary temat zostal odgrzebany to mógłbym Ciebie Marogo prosić tutaj o jakieś
dalsze wskazówki, bo co ciekawe pod aplikacjami okienkowymi na przykład w
Total Comanderze trzymany prawy Control i wciśnięcie T oraz puszczenie obu
klawiszy otwiera nową zakładkę, jednak dlaczego WinUAE ignoruje Control'a?
autoHotKey jakoś to na niskim poziomie obchodzi. Lcz ja nie ogarniam wcale
jego źródel w C++ toteż nie mam pojęcia, jak moge zrobić to co bym chciał.

var
  H : HWND;
  AKey : Cardinal;
begin
  H := FindWindow('PCSuxRox', nil);
  if H > 0 then
  begin
    AKey := vK_RETURN;
    SetForegroundWindow(H);
    Sleep(200);
    SymulujKeyDown(AKey);
    Sleep(200);
    SymulujKeyUp(Akey);
  end;
end;
0

Nie potrzebne 2 procedury (osobna od down osobna up) można to zoptymalizować do postaci:

procedure SymulujKey(Key: Cardinal; Up: Boolean = False);
const
  KEYEVENTF_KEYDOWN = 0; //dziwne up jest zdefinowany a jako stala a down nie (w Delphi)
  KEY_FLAGS: array [Boolean] of Integer = (KEYEVENTF_KEYDOWN, KEYEVENTF_KEYUP);
var
  Input: tagINPUT;
begin
  Input.Itype:=INPUT_KEYBOARD;
  Input.ki.wVK:=Key;
  Input.ki.wScan:=MapVirtualKey(Key, 0);

  if Key in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME,
              VK_END, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE]
  then Input.ki.dwFlags:= KEY_FLAGS[Up] or KEYEVENTF_EXTENDEDKEY
    else Input.ki.dwFlags:=KEY_FLAGS[Up];
  Input.ki.time:=0;
  SendInput(1, Input, SizeOf(Input));
end;

EDIT//olesio nie używam tego emulatora i nie wiem czemu akurat w tej aplikacji nie działa prawy control ale znalazłem stronę ze skrótami i tam piszą, że prawy control i prawy alt to Fire (na klawiaturze B) więc może uda się z ALT'em

http://www.apc74.ppa.pl/help/153/skrotyklawiszowe.html

0

kAzek: dzięki za odpowiedź, stronę apc74 znam i mam opanowane jako tako używanie zarowno
emulowanej Amigi pod WinUAE jak i swojej prawdziwej 1200. Jednak Alt również nic nie daje, z
początku kodu dalem AKey := VK_RMENU i mimo tego emulator nie reagował. Moge sprobować
na forum EAB zapytać się autora ów emulatora, ale pewnie niewiele On mi pomoże. Pewnie jak
nie działa w tej aplikacji to i w innych grach pod DirectX też nie będzie działalo, lecz co mnie tu
dziwi to fakt, że wszystkie inne klawisze jak kierunki i litery oraz Enter działają tak, jak należy.
Ciekawe w takim razie jak HotKeye robione są pod AutoHotKey, na pewno Hookiem, ktory pod
Delphi umiem zrobić, ale nie umiem podmienić w trakcie dzialania Hooka jednego klawisza, na
jakiś inny. A to robi AytoHotKey, bo są programy które umożliwają wciskanie Lewego Controla
lub prawego Altra aby zsymulować prawy Control dla osób, ktorym prawy Control źle działa i z
niektorymi dwoma kierunkami wciśniętymi na raz się blokuje. Ja tak miałem na starej klawie.

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