capturar evento de scroll da roda do mouse fora da aplicação

Delphi

12/11/2008

como capturar o evento de scroll do mouse fora da minha aplicação?

quando eu digo fora, quero dizer com ela rodando, porem não estando ativa, mas minimizada.


Vitor Rubio

Vitor Rubio

Curtidas 0

Respostas

Wdrocha

Wdrocha

12/11/2008

Bom dia Vitor....

Vc pode usar uma HookProcedure pra isso...

Onde a Hook pod ser ligada ao iniciar sua aplicação e enquanto a mesma estiver rodando.....esta procedure vai interceptar todas as mensagens do mouse na fila de mensagens do Windows......tanto o scroll quanto os clicks....


outro dia....eu precisei d algo assim....mas eu precisava dos clicks do mouse.....se vc quiser.....eu t passo um exemplo...


Flw...


GOSTEI 0
Vitor Rubio

Vitor Rubio

12/11/2008

se você puder me passar eu agradeço

estou precisando criar um esquema de mouse gestures para o meu programa.

não consegui registrar uma hotkey com ctrl+shift+wheel do mouse.

Se fosse possivel a minha aplicação, não importa se está minimizada ou em segundo plano, interceptar o pressionamento de ctrl+shift e o rolamento do scroll seria ótimo.


GOSTEI 0
Vitor Rubio

Vitor Rubio

12/11/2008

a proposito, só sei o basicão de api hooking, não sei nem que api deveria hookar.


GOSTEI 0
Wdrocha

Wdrocha

12/11/2008

Espero q isso ajud vc.....


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, AppEvnts, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button_StartJour: TButton;
    Button_StopJour: TButton;
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure ApplicationEvents1Message(var Msg: tagMSG;
      var Handled: Boolean);
    procedure Button_StartJourClick(Sender: TObject);
    procedure Button_StopJourClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FHookStarted : Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}

var
  JHook, HandleJanela: THandle;
  Pos : TPoint;
  ClasseComponent : Pchar;


// O procedimento Hook JournalRecordProc é uma rechamada definida pela aplicação ou definida por uma biblioteca.
//Função usada com a função SetWindowsHookEx.
//A função registra mensagens que o sistema retira da fila de mensagem do sistema.
//Um procedimento de Hook JournalRecordProc não precisa estar necessariamente em uma DLL.
// Este procedimento pode estar na própria aplicação.

// WH_JOURNALPLAYBACK Hook Function

//Syntax

// JournalPlaybackProc(
// nCode: Integer;  {Código Hook }
// wParam: WPARAM;  {Este parâmetro não é usado}
// lParam: LPARAM  {ponteiro para TEventMsg structure}
// ): LRESULT;

function JournalProc(Code, wParam: Integer; var EventStrut: TEventMsg): Integer; stdcall;
var
  s: string;
begin
   {Está é JournalRecordProc}
  Result := CallNextHookEx(JHook, Code, wParam, Longint(@EventStrut));


  if Code < 0 then Exit;

  {Cancelar operação}
  if Code = HC_SYSMODALON then Exit;

  if Code = HC_ACTION then
  begin
    {
    O parâmetro lParam contém um ponteiro para um TEventMsg 
     que contém informações sobre
     a mensagem removida da fila de mensagens do sistema.
    }
    s := ´´;

    if EventStrut.message = WM_LBUTTONUP then
    Begin
      s := ´Left Mouse UP at X pos ´ +
        IntToStr(EventStrut.paramL) + ´ and Y pos ´ + IntToStr(EventStrut.paramH);

      Pos.X := EventStrut.paramL;

    Pos.Y := EventStrut.paramH;

    HandleJanela := WindowFromPoint(Pos);

    ClasseComponent := AllocMem(50);

    S := S + ´ - ´ + IntToStr (GetClassName(HandleJanela, ClasseComponent, 50));


    End;

    if EventStrut.message = WM_LBUTTONDOWN then
    Begin
      s := ´Left Mouse Down at X pos ´ +
        IntToStr(EventStrut.paramL) + ´ and Y pos ´ + IntToStr(EventStrut.paramH);

      Pos.X := EventStrut.paramL;

    Pos.Y := EventStrut.paramH;

    HandleJanela := WindowFromPoint(Pos);

    ClasseComponent := AllocMem(50);

    S := S + ´ - ´ + IntToStr (GetClassName(HandleJanela, ClasseComponent, 50));


    End;

    if EventStrut.message = WM_RBUTTONDOWN then
    Begin
      s := ´Right Mouse Down at X pos ´ +
        IntToStr(EventStrut.paramL) + ´ and Y pos ´ + IntToStr(EventStrut.paramH);

      Pos.X := EventStrut.paramL;

    Pos.Y := EventStrut.paramH;

    HandleJanela := WindowFromPoint(Pos);

    ClasseComponent := AllocMem(50);

    S := S + ´ - ´ +  IntToStr (GetClassName(HandleJanela, ClasseComponent, 50));


    End;

    if (EventStrut.message = WM_RBUTTONUP) then
    Begin
      s := ´Right Mouse Up at X pos ´ +
        IntToStr(EventStrut.paramL) + ´ and Y pos ´ + IntToStr(EventStrut.paramH);

      Pos.X := EventStrut.paramL;

    Pos.Y := EventStrut.paramH;

    HandleJanela := WindowFromPoint(Pos);

    ClasseComponent := AllocMem(50);

    S := S + ´ - ´ + IntToStr (GetClassName(HandleJanela, ClasseComponent, 50));

    End;

    if (EventStrut.message = WM_MOUSEWHEEL) then
      s := ´Mouse Wheel at X pos ´ +
        IntToStr(EventStrut.paramL) + ´ and Y pos ´ + IntToStr(EventStrut.paramH);  

    {if (EventStrut.message = WM_MOUSEMOVE) then
      s := ´Mouse Position at X:´ +
        IntToStr(EventStrut.paramL) + ´ and Y: ´ + IntToStr(EventStrut.paramH); }

    //ShowMessage(ClasseComponent);



    if s <> ´´ then
    Begin
       Form1.ListBox1.ItemIndex :=  Form1.ListBox1.Items.Add(s);
       Form1.Edit1.Text := ClasseComponent; //Tipo de componente que foi clicado pelo usuário
    End;
  end;
end;



procedure TForm1.Button_StartJourClick(Sender: TObject);
begin
  if FHookStarted then
  begin
    ShowMessage(´A hook já está estartada´);
    Exit;
  end;
  JHook := SetWindowsHookEx(WH_JOURNALRECORD, @JournalProc, hInstance, 0);

  if JHook > 0 then
  begin
    FHookStarted := True;
  end
  else
    ShowMessage(´No Journal Hook availible´);
end;

procedure TForm1.Button_StopJourClick(Sender: TObject);
begin
  FHookStarted := False;
  UnhookWindowsHookEx(JHook);
  JHook := 0;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  {cancela a hook se for pressionada Control + Alt + Del ou Control + Esc}
  Handled := False;
  if (Msg.message = WM_CANCELJOURNAL) and FHookStarted then
    JHook := SetWindowsHookEx(WH_JOURNALRECORD, @JournalProc, 0, 0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin

  if FHookStarted then
    UnhookWindowsHookEx(JHook);
end;

Procedure TForm1.FormCreate(Sender: TObject);
  Begin

     JHook := SetWindowsHookEx(WH_JOURNALRECORD, @JournalProc, hInstance, 0);

  End;


End.




Vc pod fazer N coisas com essa procedure....espero ter sido útil....


Flw


GOSTEI 0
Wdrocha

Wdrocha

12/11/2008

Ia esquecendo....e não importa se a sua aplicação estará minimizada.....a procedure estará na fila de mensagens do windows.....


Flw


GOSTEI 0
Vitor Rubio

Vitor Rubio

12/11/2008

vou dar uma ´mastigada´ nesse código e já te digo se funcionou!


GOSTEI 0
Vitor Rubio

Vitor Rubio

12/11/2008

só consigo pegar as posições x e y do mouse, não consigo pegar o wheel data, para saber se está rodando pra frente ou para trás.


GOSTEI 0
Vitor Rubio

Vitor Rubio

12/11/2008

fiz um esquema em que eu rodo o scrol do mouse para qualquer lado, segurando uma tecla do teclado. Então se segura uma tecla e roda é um atalho, se segura outra e roda é outro. mas ainda não consegui pegar o delta ou a direção em que o scroll está rodando.

Tentei dar um getmessage, ou então mudar o eventmessage para um ´twheel não sei o que ´ mas não deu certo. o wparam vem 0. não consigo saber a direção em que a roda está girando.


GOSTEI 0
Wdrocha

Wdrocha

12/11/2008

Sim....eu tbm tow tentando aq....e tbm não tow conseguindo....

talvez vc consiga encontrar algo no site Torry´s Delphi...


GOSTEI 0
Vitor Rubio

Vitor Rubio

12/11/2008

WDRocha, eu consegui.

Achei um exemplo chamado ´LowLevelMouseHook ´ no [url]http://www.torry.net/quicksearchd.php?String=mouse&Title=Yes [/url]

mas era um exemplo que usava dll, e tambem tinha muitas funções que eu não precisava, então eu arrumei um jeito de mesclar ela com o código que você me passou.

Bom, sempre numa função hookada do windows o wparam vai ter o mesmo codigo da mensagem. O lparam pode ser um simples inteiro com informações adicionais ou um ponteiro para uma estrutura com muitas outras informações (e outros ponteiros).

Tive que usar o WH_MOUSE_LL no lugar de WH_JOURNALPLAYBACK.
(O nome dessas coisas são mensagens de hook ou funções de hook?)

bom, de onde eu tirei essa WH_MOUSE_LL?
Tem varias dessas que não estão na unit windows do delphi, mas tem na api do windows. Tive que declarar, o valor dela é 14.

const
    WH_MOUSE_LL = 14;


esses links ajudaram bastante:

[url]http://msdn.microsoft.com/en-us/library/ms644959(VS.85).aspx[/url]
[url]http://msdn.microsoft.com/en-us/library/ms644970(VS.85).aspx[/url]

o segundo tem o tipo de estrutura a qual o lparam é um ponteiro para ela.

Estou exibindo o mousedata dessa estrutura em um edit. quando é negativo é rolagem para baixo, e quando é positivo é rolagem para cima.

a estrutura:

type
  TMSLLHOOKSTRUCT = packed record
    pt: TPoint;
    mouseData: Integer;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: PULONG;
  end;
  PTMSLLHOOKSTRUCT = ^TMSLLHOOKSTRUCT;


Como eu modifiquei a function

function JournalProc(Code: Integer; wParam, lParam:DWORD): LongInt; stdcall;
var msg: tagMSG;
begin

  {Está é JournalRecordProc}  //sei la como ela vai se chamar agora
  Result := CallNextHookEx(frmTransp.JHook, Code, wParam, lParam);

  if Code < 0 then Exit;

  {Cancelar operação} 
  if Code = HC_SYSMODALON then Exit;

  if Code = HC_ACTION then
  begin

    if (wParam = WM_MOUSEWHEEL) then
    begin

      frmTransp.Edit1.Text := IntToStr(PTMSLLHOOKSTRUCT(lParam)^.mouseData);

    end;

  end;
end;


como eu registrei:

JHook := SetWindowsHookEx(WH_MOUSE_LL, @JournalProc, 0, 0);



com isso eu consegui criar um programa que captura o handle de qualquer janela ativa com getForegroundWindow e deixa ela semitransparente ou opaca ao se segurar uma tecla de atalho e rolar o wheel do mouse para frente ou para tras.

Nesse link do msdn tem outras hooks, de teclado, de mouse... um monte.

Espero que seja util a você.

:wink:


GOSTEI 0
Wdrocha

Wdrocha

12/11/2008

Pow cara...mt bom....o código ficou ótimo...

olhei os links q vc me passou....


Eu tow tentando fazer um Keylogger....e as hooks procedures do teclado serão mt úteis...obrigado...

e o nome é Hook Procedure ...


dá uma olhada nesse tópico q é mt interessante....


[url]http://forum.devmedia.com.br/viewtopic.php?t=78248&sid=b989861f9eb0c1d546954fd6c61bb61f[/url]


vc vai gostar....quem sabe possamos construir alguma aplicação do tipo...


GOSTEI 0
POSTAR