Nie działa SetWindowshookex na Windows 8

0

Mam pytanie zaimplementowałem w swojej aplikacji kod z poniższego linka:
http://www.delphitricks.com/source-code/windows/trap_mouse_events_outside_of_my_application.html

Całość bardzo fajnie działa na windowsie 7 (64 bity) natomiast na Windowsie 8 nie odpala się już nic. Czy ktoś z was się spotkał z tym problemem? Może jesteście w stanie coś podpowiedzieć? Aplikacje na Win8 uruchomiłem jako administrator i wyłączyłem UAC, a mimo to nie działa.

1

A czy musi być koniecznie Hook na WH_JOURNALRECORD? Nie może być normalnie, po ludzku na WH_MOUSE_LL? Być może ten pierwszy źle działa, bo o ile wiem służy chyba do nagrywania jakichś ruchów. Ogólnie może sprawiać problemy. Z tym drugim z wyłączonym UAC pod Windows 8 na VM u mnie wszystko jest ok. Zobacz sobie dołączony do tego posta kod oraz exek. Potrzebujesz jakiś plik typu wav lub mp3 do testów. Może coś być z podkatalogu MEDIA w Windows, jeżeli nie masz nic innego.

Btw, dałeś się chyba zabajerować niepewnym info z google. Skoro wiadomo, GLOBALNE hooki na klawiarurę robimy WH_KEYBOARD_LL to po co z myszką masz "bawić się w żurnalistę"? ;) Należy też doczytać, czy nie ma jak z hookiem na klawiarurę, że Windowsy nowsze od XP wymagają jako przedostatniego parametru podania na przykład HInstance. Ale ja tam się w żurnalistę nie bawię, tylko w niskopoziomowca i jest ok.

0

Olesio dzięki za odp. Dzięki twojemu skryptowi dowiedziałem się, że problem nie leży w hooku tylko w wykonaniu późniejszej instrukcji. Zasadniczo hook jest tylko po to aby zapamiętać ostatnią pozycję kursora, a później moja aplikacja robi klik w tą konkretną zapamiętaną pozycję kursora. No i na Win8 nie działa mi ten kod:

SetCursorPos(gPozX, gPozY);  // ustaw w wybranej pozycji
  { kliknij na pozycje }
    mouse_event(MOUSEEVENTF_LEFTDOWN, gPozX, gPozY, 0, 0);
    mouse_event(MOUSEEVENTF_LEFTUP, gPozX, gPozY, 0, 0);

W każdym razie sobie poradziłem i można temat zamknąć.

1

No proszę Cię. Rozumiem jakaś gimbaziarska lameria, ale żebyś Ty pisał jakieś herezje o skrypcie. Nawet nie wolno tak pisać doświadczonemu userowi, jako skrót myślowy. Delphi to nie AutoHotKey czy AutoIt albo coś tego typu :/ Natomiast co do kliknięcia, jeśli kontrolka jest na pierwszym planie, to kod powinien zadziałać. Ewentualnie może na poniższy kod zareeaguje lepiej - spróbuj. Bo o ile pamiętam to mouse_event jak i keybd_event zdaje się, z tego co sugerują na MSDN, są przestarzałe. I należy raczej korzystać z SendInput.

//...
type
  TMouseButton = (mbLeft, mbRight, mbMiddle);

procedure MouseDownUp(MouseButton : TMouseButton; ButtonDown : boolean);
const
  Mouse_Up_Arr : array[TMouseButton] of DWORD =
    (MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_RIGHTUP);
  Mouse_Down_Arr : array[TMouseButton] of DWORD =
    (MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN);
var
  MP : TPoint;
  Input : TInput;
begin
  Windows.GetCursorPos(MP);
  Input.Itype := INPUT_MOUSE;
  if not ButtonDown then
  begin
    Input.mi.dwFlags := Mouse_Up_Arr[MouseButton];
  end
  else
  begin
    Input.mi.dwFlags := Mouse_Down_Arr[MouseButton];
  end;
  Input.mi.dx := MP.X;
  Input.mi.dy := MP.Y;
  Input.mi.time := 0;
  Input.mi.dwExtraInfo := 0;
  SendInput(1, Input, SizeOf(Input));
end;
0

Sorki za ten skrypt :P zapomniałem się, a co do SendInput to fakt, też na necie znalazłem ten artykuł Poniżej kod dla całego ciągu znaków (może komuś się przyda)

procedure SendKey(pStr: string);
var
  Inp: TInput;
  i: Integer;
begin
  for i := 1 to Length(pStr) do
  begin
    // press
    Inp.Itype := INPUT_KEYBOARD;
    Inp.ki.wVk := Ord(UpCase(pStr[i]));
    Inp.ki.dwFlags := 0;
    SendInput(1, Inp, SizeOf(Inp));

    // release
    Inp.Itype := INPUT_KEYBOARD;
    Inp.ki.wVk := Ord(UpCase(pStr[i]));
    Inp.ki.dwFlags := KEYEVENTF_KEYUP;
    SendInput(1, Inp, SizeOf(Inp));

    Application.ProcessMessages;
    Sleep(80);
  end;
end;
1

@woolfik - niepotrzebnie dublujesz dwie instrukcje, a możesz to skrócić:

procedure SendKey(pStr: string);
var
  Inp: TInput;
  i: Integer;
begin
  for i := 1 to Length(pStr) do
  begin
    Inp.Itype := INPUT_KEYBOARD;
    Inp.ki.wVk := Ord(UpCase(pStr[i]));

    // press
    Inp.ki.dwFlags := 0;
    SendInput(1, Inp, SizeOf(Inp));
    // release
    Inp.ki.dwFlags := KEYEVENTF_KEYUP;
    SendInput(1, Inp, SizeOf(Inp));

    Application.ProcessMessages;
    Sleep(80);
  end;
end;
0

słusznie dzięki

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