Wczytywanie znaków przez program w tle

0

Witam!

Mam pytanie, w jaki sposób mogę wczytywać znaki z klawiatury, nawet, gdy okno konsoli jest nieaktywne? Np. zminimalizowane.
Nie to, żebym nic nie szukał. Na celowniku mam takie oto funkcje:
GetKeyState
GetKeyboardState
GetAsyncKeyState
Tylko mam problem, żeby rozszyfrować jak się z nich korzysta... Mógłby mi ktoś podpowiedzieć która funkcja by się najbardziej nadawała do mojego problemu (jeśli nie wybrałem złych :/)? I jak się mniej więcej z niej korzysta (jakie parametry przyjmuje, co zwraca, jak działa). Z góry dziękuje za odpowiedź.

0

Hook albo DirectInput

0

Ok, dzięki. Czyli te funkcje mi się nie przydadzą?

0

E tam, trochę Its not me panikuje. To znaczy, generalnie ma rację, do tego hooków się używa. "Swoją" metodą nie otrzymujesz informacji wtedy, kiedy klawisz został wciśnięty. Po prostu sprawdzasz stan klawiszy raz na jakiś czas. Keyloggera tym nie zrobisz, ale jakieś global hotkey'e... w sumie czego nie. Mi jakoś program poniższy działa, i procesora nie żre w najmniejszym stopniu - patrzyłem na zużyty czas Kernel/User/Total, a nie na procentowe, bo to ani procenta nawet nie bierze.

#include <windows.h>
#include <stdio.h>

BYTE keys[256] = {0};

bool scankeys(PBYTE keys, int num=-1) {
    if(num>0)
        keys[num]=GetAsyncKeyState(num);
    else
        for(int i=0; i<256; i++) keys[i]=GetAsyncKeyState(i);
    return true;
    }


int main() {

    while( !keys[27] ) {
        scankeys(keys);
        for(int i=0;i<256;i++) if(keys[i]) printf("%i ",i);
        Sleep(20);
        }

    return 0;
    }

użyłem tylko GetAsyncKeyState, ponieważ
GetKeyboardState z bliżej nieznanych mi powodów nie pobierał stanu całej klawiatury. Ba, nic nie pobierał - po prostu nie chciał menda współpracować.

0

Dzięki ;)
Tylko, że nie za bardzo rozumiem do czego tutaj służy zmienna num. I czy mógłbyś mi powiedzieć co zwraca funkcja GetAsyncKeyState() ? Bo tak właściwie to nie wiem co jest przypisywane do keys. Na podstawie twojego kodu napisałem coś takiego, czy to też jest prawidłowe?

#include <iostream>
#include <windows.h>

using namespace std;

BYTE keys[256] = {0};

bool scankeys(PBYTE keys)
{
     for (int i = 0; i < 256; i++)
         keys[i] = GetAsyncKeyState(i);
    return true;
}


int main()
{
    while (!keys[27])
    {
        scankeys(keys);
        for (int i = 0; i < 256; i++)
            if (keys[i])
               cout << i << ' ';
        Sleep(20);
    }
    return 0;
}
0

tak ciężko wpisać sobie w google nazwę funkcji:
http://msdn.microsoft.com/en-us/library/ms646293.aspx

ludzie nauczcie się, że na google są wszystkie wasze odpowiedzi,
przykładowo mój ojciec, nie wie co to pulpit, ikona i którym się minimalizuje i maksymalizuje (wie tylko co oznacza krzyżyk zamknięcia), ale wie, że jak już mu się uda jakimś cudem odpalić przeglądarkę z kartą startową(google.pl) to będzie mógł wpisać hasło i sobie czegoś tam poszuka...

0
crayze napisał(a)

tak ciężko wpisać sobie w google nazwę funkcji:
http://msdn.microsoft.com/en-us/library/ms646293.aspx

Ale żeś mi cynk dał, nigdy bym na to nie wpadł.... A spojrzałbyś na mojego pierwszego posta...
Znaleźć to ja sobie umiem, tylko gorzej u mnie z angielskim... Jak jest coś prostego to sobie poradzę, ale w tym przypadku ciężko mi to przetłumaczyć samemu, a translator głupoty gada.

0

No więc tak. Parametr jest taki opcjonalny - zresztą dałem domyślny dlatego. Po prostu zrobiłem sobie na potrzeby testów funkcję półuniwersalną. Jak nic nie podasz - czyta wszystko. Jak podasz kod klawisza - sprawdza tylko ten klawisz. Jak potrzeba tylko jednego klawisza, to oszczędzasz na operacjach. Robi się tylko to, co trzeba - nie wypełniasz całej tablicy.

Typ zwracany bool - też niepotrzebny. Możnaby dać void i nic nie zwracać. Po prostu nie lubię voidowych funkcji. IMO każda funkcja powinna brać pod uwagę, że coś może nie wyjść. I albo zwracać true/false (udało się/błąd) albo jakiś numer, albo rzucać wyjątkiem. Nawet taka funkcja, w której bieżącej implementacji błędy nie są zwracane> Może nowsza wersja tej funkcji już będzie mogła popełniać błędy - wtedy deklaracji i dokumentacji nie trzeba zmieniać - bo już dawno byliśmy przygotowani. Podobnie się często robi w języku C dając jakieś parametry/pola w strukutrze typu Reserved for future use (zarezerwowane dla przyszłych zastosowań).

To tak ideowo - masz omówienie pewnych praktyk/konwencji ;)

Konkretnie: dobrze funkcję przerobiłeś. A GetAsyncKeyState zwraca dla każdego klawisza liczbę, w której mogą być zapalone 2 bity: najmniej znaczący (0x01) i najbardziej (0x80). W tablicy masz więc: tablica[kod]. Jeśli:
(tablica[kod] & 0x01) - ktoś nacisnął i puścił klawisza od czasu, kiedy ostatnio sprawdzałeś
(tablica[kod] & 0x08) - klawisz jest wciśnięty teraz

Z czego myk z najmniej znaczącym bitem (0x01) jest niepewny, nie ma co o nim myśleć - bo inny program w Windowsie też może używać GetAsyncKeyState, i to on może dostać info 0x01 - skoro inny dostał, to tobie już on się nie trafi. Z tego względu dla ciebie istotne jest tylko, czy wartość pod danym indeksem (np VK_F11 dla F11) jest różna od zera. Jak jest różna, to ktoś właśnie w tej chwili trzyma wciśnięty.

//crayze: byłem szybszy ;)

0

GetAsyncKetState - zwraca czy dany przycisk jest naciśnięty w momencie wywołania funkcji i czy był naciśnięty od ostatniego wywołania, parametr-sprawdzany wirtualny kod przycisku, zwracanawartość: jeśli najbardziej znaczący bit jest ustawiony przycisk jest aktualnie naciśnięty, a najmniej znaczący bit wyznacza, czy nastąpiło naciśnięcie od ostatniego wywołania, w remarksie: napisane jest, że ostatnie naciśnięcie jest mierzone względem systemowego wywołania, tzn. jesli jakiś program także używa tej funkcji, to funkcja nie odróżnia tych programów i ta informacja jest pozostałością po 16bitówce, nie zaleca się korzystania z tego

no coś tego typu

0

Ok, dzięki wam za pomoc, już zrozumiałem ;)

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