Global Hook puszczenie klawisza

0

Witam mam problem napisałem taki kod:

function KeyHook(Code: Integer; wParam : WPARAM; lParam : LPARAM): Longint; stdcall;
var
Buffer: TEventMsg;
begin
result := 0;
Buffer := PEventMsg(lParam)^;
if Buffer.message = wm_    ?? then begin
Form1.Timer1.Enabled:=True;
If Buffer.message= wm_ ?? then begin
Form1.Timer1.Enabled:=False:

end;
end;

Chodzi o to by za pomoca globalhooka gdy control zostanie wcisniety włącza timera a gdy zostanie puszczony wyłącza go, lecz nie zbyt wiem jak to zrobić?

0

tak tylko zeby wykonywało te opcje tylko przy CTRL ? pokaże ktoś Ifa z wykorzystaniem tych funkcji?

0

Podałem ci linki na opis WM_KEYDOWN oraz WM_KEYUP, możesz sprawdzić czy przy okazji był wciśnięty Cntrl, z tym że jak dasz ten sam warunek przy WM_KEYUP to na pewno nie będzie ci działać poprawnie.
Jeżeli wciśnięto <Ctrl+F1> to puszczać te klawisze użytkownik może w dowolnej kolejności albo najpierw Ctrl a potem F1 albo na odwrót.

0

Niezbyt wiem jak to użyć zaprezentujesz jakiś przykład?

0

Poniżej masz przykład Hooka z VK_TAB, który kiedy jest on wciśnięty pokazuje Panel1, a kiedy zostanie
zwolniony chowa go. Ty u siebie możesz zrobić podobnie - tylko zamiast Visible, dajesz TimerX.Enabled.
Później oczywiście kAzek zaprezentował w temacie gdzie podalem ten kod, lepszy sposób ze zdarzeniem
dla Application.OnMessage. Ale jeżeli wyłączanie i włączenie Timera ma się odbywać również kiedy Twój
program nie będzie aktywny, czyli działać w całym systemie, to polecam Ci właśnie poniższe rozwiązanie.

//...
const
  WH_KEYBOARD_LL = $000D;

type
  tagKBDLLHOOKSTRUCT = packed record
    vkCode : DWord;
    ScanCode : DWord;
    Flags : DWord;
    Time : DWord;
    dwExtraInfo : integer;
  end;
  KBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;
  PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;

var
  Form1 : TForm1;
  HKHook : HHook;

implementation

{$R *.dfm}

function LowLevelKeyboardProc(nCode : Integer; wParam : Integer; lParam : Integer) : Integer; stdcall; export;
var
  Hook : PKBDLLHOOKSTRUCT;
begin
  Hook := Pointer(lParam);
  case nCode of
    HC_ACTION :
      begin
        Form1.Panel1.Visible := (GetForeGroundWindow = Form1.Handle)
          and (Hook.vkCode = VK_TAB) and (Hook.Flags = 0);
      end;
  end;
  Result := CallNextHookEx(HKHook, nCode, wParam, lParam);
end;

procedure HookIt;
begin
  HKHook := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, hInstance, 0);
end;

procedure UnHookIt;
begin
  UnHookWindowsHookEx(HKHook);
end;

procedure TForm1.FormCreate(Sender : TObject);
begin
  Hookit;
  Panel1.Visible := False;
end;

procedure TForm1.FormDestroy(Sender : TObject);
begin
  UnHookit;
end;
0

a jeszcze takie pytanie czy można założyć równocześnie dwa hooki?

Jak wstawiłem VK_Control to na controlu głupieje cos i źle działa

0

Można wszystko zrobić w jednej procedurz obsługi Hook'a. Pod adresem: http://pastebin.pl/37620 wkleiłem
przykład modułu, który blokuje różne kombinacje klawiszy, na nim się wzorowałem od dawna przy hookach.

0

Teraz mam inny problem,
Znalazłem w internecie kod do symulacji wciskania klawiszy

procedure jump(Key : Cardinal; KeyUp : boolean);
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
  begin
    Input.ki.dwFlags := KEYEVENTF_EXTENDEDKEY;
  end
  else
  begin
    if KeyUp = False then
    begin
      Input.ki.dwFlags := 0;
    end
    else
    begin
      Input.ki.dwFlags := KEYEVENTF_KEYUP;
    end;
  end;
  Input.ki.time := 0;
  SendInput(1, Input, SizeOf(Input));
end;

A w timera daje:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
       jump(Ord('6'), False);
        sleep(5);
       jump(Ord('6'), True);
end;
function LowLevelKeyboardProc(nCode : Integer; wParam : Integer; lParam : Integer) : Integer; stdcall; export;
var
  Hook : PKBDLLHOOKSTRUCT;
begin
  Hook := Pointer(lParam);
  case nCode of
    HC_ACTION :
      begin
        Form1.Timer1.Enabled := (GetForeGroundWindow = Form1.Handle)
          and (Hook.vkCode = VK_LCONTROL) and (Hook.Flags = 0);
      end;
  end;
  Result := CallNextHookEx(HKHook, nCode, wParam, lParam);
end;

Lecz to nie działa, chodzi o to że gdy trzymam Lewy Kontrol to program wciska 6 w windowsie ogólnie, nie w danym oknie, I reakcja na Ctrl jest tylko w oknie programu, gdy testowałem na showmessage w timerze to tylko w programie działało a generowanie 6 w ogóle nie działą w timerze ani w procedurze a jak wpisze w formcreate to działa. ja tego nie rouzmiem.

0

Tan kod co podalem na PasteBin działa ok, ale jeżeli chodzi o ten drugi co podałeś z
KeyUp : boolean, to chyba przerabial to tutaj na forum Użytkownik kAzek i powinno
to działać. Jednak brakuje Tobie podstawowej wiedzy, bo źle kombinujesz, Sleep w
Timerze może mieć minimalny Interval 100 milisekund, można dać mniej ale to nie
da efektu, co innego wątek, także zmień odstęp na 100 milisekund i wtedy sprobuj
jednak jeżeli nie zadziała to nie mam innego pomysły, może ktoś inny coś doradzi.

0

ok, funkcja showmessage dla testu z timerem i controlem działa dobrze ale

       jump(Ord('6'), False);
        sleep(5);
       jump(Ord('6'), True);

W timerze nie chce działać za nic próbowałem bez sleepa ze sleepem 100,1000 nic ciagle to samo. To samo ze w procedurze np

procedure wcisnij;
begin
       jump(Ord('6'), False);
        sleep(5);
       jump(Ord('6'), True);
end;

tez nic sie nie dzieje po wywołaniu wcisnij, a jak dodam

       jump(Ord('6'), False);
        sleep(5);
       jump(Ord('6'), True);

np pod button1 to wpisze poprawnie

0

To nie mam pojęcia dlaczego, jedno jest pewne jeżeli Interval Sleepa będzie poniżej 100 milisekund
to i tak odstęp będzie 100 milisekundowy. AFAIK jedynie w wątku mozna osiągnąć krótsze odstępy.

0

dobra poza programem to nie działa, ten sposób po prostu nie działa jak napisać warunek ze
if VK_LCONTROL UP
if VK_LVONTROL Down

bo to nie działa krzaczy się gdy dam showmessage albo label to pokazuje ze uruchamia timer a liczb nie wpisuje jak dałem button1.click a w buttonie procedura kilkania to nie działa, A jak odpale timera1. na true TO DZIAŁA, nie rouzmiem tego, poza programem nie działa w ogóle na żadnym klawiszu.

0

Nie wiem co chcesz osiągnąć, ale z doświadczenia wiem, że ShowMessge nie można użyć w wątku, bo będzie błąd o
niemożliwości malowanie na płótnie, a w tej procedurze obsługi Hook'a nie można nawet pokazać - wiem, bo to już
próbowałem - zwykłego MessageBoxa, bo otrzymamy komunikat o błędzie, lecz najlepiej zrobić sobie dodawanie do
Memo linijki z opisem stanu wartości, coś jak poniżej. Widać wtedy, że puszczając klawisz Flags wynosi 128, nie 0.

//...
  case nCode of
    HC_ACTION :
      begin
        MainForm.TestMemo.Lines.Add(Format('vkCode: %d ScanCode: %d Flags: %d Time: %d ExtraInfo: %d',
          [Hook.vkCode, Hook.ScanCode, Hook.Flags, Hook.Time, Hook.dwExtraInfo]));
//...
0

Podałbyś jakiś kontakt do Ciebie?
Albo napisz na mail
[email protected]
Przesłałbym ci pliki źródłowe i jeśli możesz to przebadaj o co chodzi.

0

Napisałem już Tobie jak rozróżnić w Hooku wciskanie oraz puszczanie jakiegokolwiek klawisza. A jeżeli chcesz to wrzuć źródła na jakiś
hosting, najlepiej na http://www.speedyshare.com (bo najłatwiej szybko stamtąd pobrąc) i podaj link do archiwum ze źródłami stutaj,
to ktoś może inny coś doradzi. Ja pomagam tutaj na forum, o ile potrafię, a nie ma sensu mailować, bo na forum więcej osób siedzi.

0

Pod adresem: http://www.speedyshare.com/files/27320412/h3h3_fixed.rar poprawione źródło. Chciałeś aby Timer działal tylko jeżeli Twoja aplikacja jest na wierzchu i trzymany jest Ctrl, jak dobrze zrozumiałem. No to teraz to robi. A i poza tym straszne kombinowanie z niewidocznym Buttonem4, tak się nie robi. Poza tym pisałem Timer nie może mieć Intervalu poniżej 100 ms, tak samo - o ile się nie mylę - Sleep poza wątkiem również nie może mieć mniejszego Intervalu niż 100 ms. A jeżeli o nie o to co zrobilem chodziło to nie wiem. Z pewnością program by wciskał to S, ale nie wiem gdzie to ma robić, kod z funkcją Jump wywaliłem, ale jest on na pewno prawidłowy, bo go testowalem w swojej innej aplikacji. Jednak Interval 5 milisekund to i tak bardzo mało, a poza wątkiem będzie to nadal 100 ms. Dodam, że teraz Timer1 robi cokolwiek sensownego, bo losuje liczby z zakresu od 0 do 99999 i pokazuje je na Captionie Formatki.

0

mi chodzi o to aby poza programem Control tez reagował i aby timera wpisywał liczbę 6 za pomocą funkcji jump gdy trzymany jest CTRL

0

Masz: http://www.speedyshare.com/files/27325107/for_lazy_tomek.rar i ostatni raz tyle kombinuje za kogoś, bo po prostu wiadomo, że kod nie reagował w wątku czy Timerze, bo Hook na klawisze sam się w sobie jakby zapętlał, pomogło dodanie Exit przy tworzeniu wątku i reszta tak, jak zrobiłem. Chwilkę sam byś podumał to byś do tego doszedł, ale podejrzewam, że się Ci nie chciało ;/

0

To jeszcze nie jest to, bo wtym kodzie gdy ustawiam większego sleepa to = 1s to nie działa, a gdy trzymam na sleepie 10ms to tylko przez jakis czas wciska liczbę.

0

Ech, Ty to jesteś mega leniem. Dostałeś przykład, wiesz w czym tkwił błąd ode mnie, ja też nie jestem nieomylny, ale nie działa to zamiast pomyśleć chwilę i poprawić samodzielnie to zaraz piszesz na forum. Teraz powinno być ok, jeżeli znowu coś nie tak - to już kombinuj po swojemu. Jedno jest pewne nie potrzeba Timera skoro odstęp czasowy ma być mniejszy niż 100 milisekund i nie trzeba wychodzić Exitem, zaś dyrektywa WARNINGS OFF jest po to żeby nie marudzil, że funkcja obslugi Hooka może nie zwracać rezultatu. Link do źródła i exe: http://www.speedyshare.com/files/27338868/for_very_lazy_tomek.rar

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