Dlaczego nie działa VK_RETURN w grze?

abcaaaaaaa
2014-08-29 21:59
abcaaaaaaa
0

W jednej grze można otworzyć okno konsoli by wpisywać w niej komendy i wysyłam komunikaty za pomocą SendMessage() do głównego okna gry, bo jak konsola jest aktywna to i tak wtedy jak każę wysłać litery ABC to wysyła je do gry do konsoli dobrze, VK_SPACE też działa w konsoli, ale VK_RETURN, czyli ENTER nie działa w ogóle w konsoli. Sprawdziłem też, czy poza konsolą, w samej grze działa np. spacja, ale tam już nic nie działa, ani spacja, ani nic.

Skoro do konsoli trafiają litery i spacja działa, to dlaczego enter nie działa w niej? VK_KEYDOWN robię, identycznie jak dla spacji, to dziwne jest by jeden klawisz działał, a drugi (czyli enter) już nie, a bez entera żadnej komendy nie można potwierdzić w konsoli dlatego zależy mi na tym enterze i proszę was o pomoc.

Pozostało 580 znaków

2014-08-29 23:07
Moderator

Rejestracja: 11 lat temu

Ostatnio: 2 miesiące temu

Lokalizacja: Szczecin

0

Napisałeś tak, że nie wiadomo do końca o co chodzi. Albo ja się w tym połapać nie mogę. Nie piszę w C++, ale w Delphi. Jednak z moich testów wynika, że powinno pomóc wysłanie przez PostMessage. Oczywiście również z "puszczeniem" danego klawisza. A w ogóle do symulowania naciśnięć oraz "puszczeń" klawiszy, polecam taki jak poniżej sprawdzony kod w Delphi. Przetłumacz go sobie sam na C++.

procedure KeyDownUp(KeyToSend : Byte; KeyDown : boolean);
const
  DownUp_Flags_Arr : array[boolean] of DWORD = (0, KEYEVENTF_KEYUP);
  Extended_Flags_Arr : array[boolean] of DWORD = (0, KEYEVENTF_EXTENDEDKEY);
var
  Input : TagINPUT;
  KeyExtended : boolean;
begin
  Input.Itype := INPUT_KEYBOARD;
  Input.ki.wVK := KeyToSend;
  Input.ki.wScan := MapVirtualKey(KeyToSend, 0);
  KeyExtended := KeyToSend in [VK_CONTROL, VK_LCONTROL, VK_RCONTROL,
    VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME, VK_END, VK_PRIOR,
    VK_NEXT, VK_INSERT, VK_DELETE, VK_MENU];
  Input.ki.dwFlags := DownUp_Flags_Arr[not KeyDown] or Extended_Flags_Arr[KeyExtended];
  Input.ki.time := 0;
  SendInput(1, Input, SizeOf(Input));
end;

EDIT: sprawdziłem uchwyt otwartego okna cmd.exe i taki kod działa ok. Pewnie są też ważne sposoby w jaki sposób tworzysz okno konsoli i nadajesz jej atrybuty. Oczywiście na bazie funkcji WinAPI enumerujących, można sobie napisać coś, co zwróci uchwyt z danego PID'u. Jednak takie kody mam tylko pod Delphi. Gdyż takie są mi przydatne.

var
  H : HWND;
begin
  H := $180234; // okno o klasie "ConsoleWindowClass";
  if H > 0 then
  begin
    PostMessage(H, WM_KEYDOWN, VK_RETURN, 0);
    PostMessage(H, WM_KEYUP, VK_RETURN, 0);
  end;
end;

edytowany 1x, ostatnio: olesio, 2014-08-29 23:12
array[boolean]? - spartanPAGE 2014-08-30 09:54
@spartanPAGE: tak, a dlaczego Ciebie to dziwi? Lepiej zrobić tak. Niż później stosować if. Mniej kodu. - olesio 2014-08-30 14:00
Nie nie, o konstrukcję pytam :P pierwszy raz się z tym spotkałem - spartanPAGE 2014-08-30 14:13

Pozostało 580 znaków

abcaaaaaaa
2014-08-29 23:17
abcaaaaaaa
0

z PostMessage też sprawdzałem nim jeszcze temat tu założyłem i nie działał enter (chodzi o grę sieciową, strzelankę, popularną)

Pozostało 580 znaków

2014-08-29 23:36

Rejestracja: 16 lat temu

Ostatnio: 3 minuty temu

0

Spróbuj z SendInput.

No ja mu właśnie pokazałem jak z SendInput zasymulować klawisze. Ktoś to kiedyś też ode mnie tutaj to dostał i przetłumaczył na C++. Także pytający musi poszukać. - olesio 2014-08-29 23:56

Pozostało 580 znaków

abcaaaaaaa
2014-08-29 23:56
abcaaaaaaa
0

a czy ten SendInput umożliwi wysłanie polecenia do zminimalizowanej gry? bo nie chcę mieć jej zmaksymalizowanej i aktywnej

Pozostało 580 znaków

2014-08-30 00:09
Moderator

Rejestracja: 11 lat temu

Ostatnio: 2 miesiące temu

Lokalizacja: Szczecin

1

Nie. SendInput symuluje naciskanie klawiszy przy aktualnym stanie tego co widzisz. Ale jeśli nawet upierasz się przy jakimś "czitowaniu" kiedy gra jest w tle. To pozostaje sprawdzić na przykład "poczepiając się" przez techniki takie jak injekcja własnej dllki w proces gry lub dll spoofing pod funkcję obsługi komunikatów i sprawdzić jak w grze jest przekazywany VK_RETURN. Może do obsługi niektórych klawiszy okno używa własnych metod, jak na przykład emulator Amigi WinUAE. Zauważ też, że komunikat WM_KEYDOWN moze mieć dodatkowe flagi w parametrze LParam. Poczytaj o nich na MSDNie.


Pozostało 580 znaków

abcaaaaaaa
2014-08-30 00:25
abcaaaaaaa
0

o czity nie chodziło, a o legalne używanie konsoli w grze i legalnych komend (nielegalnych komend pewnie nie ma :D), a tam enter jest potrzebny by zatwierdzić wpisaną komendę, ale mniejsza z tym. Skoro mam kombinować z dll injection to daruję sobie. Dzięki mimo wszystko, że poświęciliście mi czas.

Pozostało 580 znaków

2014-08-30 00:37
Moderator

Rejestracja: 11 lat temu

Ostatnio: 2 miesiące temu

Lokalizacja: Szczecin

0

Nie musisz koniecznie kombinować z injekcją. Moze być spoofnięcie dllki z dodanym własnym kodem logowania wysyłanych komunikatów plus WParam i LParam do pliku. To nic trudnego. Każdy prawdziwy C++ madafaka może to ogarnąć. Skoro taki Delphiaczowy amator jak ja mógł ;)

A tak poważnie. Pisałem kiedyś coś takiego, jak zapodałem w załączniku. Nie jest to idealne. Bo: działa tylko dla 32 bitowych aplikacji, nie listuje do końca prawidłowo procesów, więc wielu nie ma, nie zawsze się da podczepić pod konkretne okno, może proces się nam wykrzaczyć itd, itp. Ale może w przypadku Twojej gry uda się wyśledzić jak dokładnie obsługiwany jest ręcznie wciskany enter w konsoli. Spróbuj pokombinować.

A w ogóle to napisz może też, o jaką grę konkretnie chodzi? Być może ktoś się tym już zajmował dla swoich potrzeb. I będzie umiał tutaj coś więcej doradzić. Jedno jest pewne standardowa konsola według mnie raczej powinna przyjmować różne klawisze, w tym Enter. Zarówno poprzez WM_KEYDOWN/UP jak i WM_CHAR.


Pozostało 580 znaków

2014-08-30 15:12

Rejestracja: 6 lat temu

Ostatnio: 1 rok temu

0

a dziala ci ten enter jak okno z gra jest na pierwszym planie?


edytowany 1x, ostatnio: mca64, 2014-08-30 15:13

Pozostało 580 znaków

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