Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.07.2009, 14:47   #1
_Zergatul
 
Регистрация: 04.07.2009
Сообщений: 3
По умолчанию Перехват события нажатия мышки в любой области экрана

Собсвенно нужно отследить клик мышкой в чужом окне. Жду ваших советов
_Zergatul вне форума Ответить с цитированием
Старый 04.07.2009, 23:41   #2
Terran
Участник клуба
 
Аватар для Terran
 
Регистрация: 28.11.2007
Сообщений: 1,521
По умолчанию

Цитата:
Сообщение от _Zergatul Посмотреть сообщение
Собсвенно нужно отследить клик мышкой в чужом окне. Жду ваших советов
Код:
Var
HookHandle: HHook;
Function HookProc(Code: Integer; WParam: Word; LParam: Longint): Longint; Stdcall;
Var
Msg: PEVENTMSG;
Begin
If Code>=0 Then
Begin
Msg:=Pointer(LParam);
Case Msg.message Of
WM_LBUTTONDOWN: Form1.Memo1.Lines.Add('L-mouse');
WM_RBUTTONDOWN: Form1.Memo1.Lines.Add('R-mouse');
End;
End;
End;
Procedure TForm1.FormCreate(Sender: TObject);
Begin
HookHandle:=SetWindowsHookEx(WH_JOURNALRECORD,@HookProc,HInstance,0);
End;
Procedure TForm1.FormDestroy(Sender: TObject);
Begin
If HookHandle<>0 Then
UnhookWindowsHookEx(HookHandle);
End;
Всегда рад помочь!
Terran вне форума Ответить с цитированием
Старый 05.07.2009, 02:08   #3
_Zergatul
 
Регистрация: 04.07.2009
Сообщений: 3
По умолчанию

Код работает частично (использовал dll для установки ловушки):
  1. С первым параметром функции SetWindowsHookEx, WH_JOURNALRECORD - не работает. Использовал WH_GETMESSAGE.
  2. Эта ловушка не отлавливает нажатие левой кнопки мыши по таким елементам как заголовок окна, скролбары, и возможно, что-то ище.

Последний раз редактировалось _Zergatul; 05.07.2009 в 02:15.
_Zergatul вне форума Ответить с цитированием
Старый 05.07.2009, 02:31   #4
_Zergatul
 
Регистрация: 04.07.2009
Сообщений: 3
По умолчанию

Вот код моей длл-ки:

Код:
library MouseHook;

uses
  Windows, Messages;

var
  SysHook : HHook = 0;
  Wnd : HWND = 0;

function SysMsgProc(Code : Integer; wParam : Word; lParam : LongInt) : LongInt; stdcall;
var
  t : _SYSTEMTIME;
begin
  CallNextHookEx(SysHook, Code, wParam, lParam);
  GetLocalTime(t);
  if Code = HC_ACTION then
    case TMsg(Pointer(lParam)^).message of
      WM_LBUTTONDOWN :
        begin
          PostMessage(Wnd, WM_CLOSE, 0, 0);
        end;
    end;
end;

procedure RunStopHook(State : Boolean) export; stdcall;
begin
  if State then
    begin
      SysHook := SetWindowsHookEx(WH_GETMESSAGE, @SysMsgProc, HInstance, 0);
      Wnd := FindWindow(nil, '___');
    end
  else
    begin
      UnhookWindowsHookEx(SysHook);
      SysHook := 0;
    end;
end;

exports RunStopHook index 1;

begin
end.
При запуске ловушки ищется окно моей главной программы:

Код:
Wnd := FindWindow(nil, '___');
Почему оно закрывается только в том случае, если клик произошел по его области?
Хотя следующий код записывает в файл время нажатий клавиши мыши по любом окне:

Код:
library MouseHook;

uses
  Windows, Messages, SysUtils;

const
  FileName = 'd:\cl_new.txt';

var
  SysHook : HHook = 0;
  Wnd : HWND = 0;
  f : TextFile;

function SysMsgProc(Code : Integer; wParam : Word; lParam : LongInt) : LongInt; stdcall;
var
  t : _SYSTEMTIME;
begin
  CallNextHookEx(SysHook, Code, wParam, lParam);
  GetLocalTime(t);
  if Code = HC_ACTION then
    case TMsg(Pointer(lParam)^).message of
      WM_LBUTTONDOWN :
        begin
          AssignFile(f, FileName);
          if not FileExists(FileName) then
            ReWrite(f)
          else
            Append(f);
          WriteLn(f, IntToStr(t.wHour) + ':' + IntToStr(t.wMinute) + ':' + IntToStr(t.wSecond) + '.' + IntToStr(t.wMilliseconds));
          CloseFile(f);
        end;
    end;
end;

procedure RunStopHook(State : Boolean) export; stdcall;
begin
  if State then
    begin
      SysHook := SetWindowsHookEx(WH_GETMESSAGE, @SysMsgProc, HInstance, 0);
      Wnd := FindWindow(nil, '___');
    end
  else
    begin
      UnhookWindowsHookEx(SysHook);
      SysHook := 0;
    end;
end;

exports RunStopHook index 1;

begin
end.

Последний раз редактировалось _Zergatul; 05.07.2009 в 14:13.
_Zergatul вне форума Ответить с цитированием
Старый 05.07.2009, 14:55   #5
Фенрир
fenryrroa@mail.ru
Пользователь
 
Регистрация: 20.01.2009
Сообщений: 10
По умолчанию

вот исходники мышиного хука (отображает координаты при клике правой )
http://files.mail.ru/9L5Z0A
Большую часть кода написал Devnvd (borland.xportal.ru)
основано на использовании разделяемой памяти

проблема в том что работает только при клике в пределах окна приложения
до использования разделяемой памяти вообще не реагировало за пределами окна или когда оно свернуто/ неактивно
после введения проецирования в разделяемую память работает не правильно. (вылетает/ показывает нерпавильные координаты)

// Код Длл
Код:
    //---------------------------------------------------------------------------

#include <windows.h>
#include <stdio.h>
#include "HookData.h"
//#include "dllhook.h"

extern THookData *HookData; //Адрес разделяемой памяти

HINSTANCE hDllInstance = NULL;//Адресное пространство

 extern "C" BOOL __stdcall __declspec(dllexport) InstallHook(HWND hWnd,UINT message);
extern "C" BOOL __stdcall  __declspec(dllexport) RemoveHook();


extern void __stdcall DeleteParamData();
extern BOOL __stdcall CreateParamData();


  //---------------------------------------------------------


           /*Процедура обработки сообщений мыши*/
  LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
{
     if (nCode < 0)  return CallNextHookEx(HookData->hHook, nCode, wParam, lParam);

   if (wParam==WM_RBUTTONDOWN)  {
       FILE* f = fopen ("report.txt", "a");
       fprintf (f, "\n%d--%d\n", ((PMOUSEHOOKSTRUCT)lParam)->pt.x, ((PMOUSEHOOKSTRUCT)lParam)->pt.y);
       fclose(f);
     /*Посылаем хэндлу окна сообщение с параметрами мыши*/
     SendMessage(HookData->hWnd,HookData->message,(WPARAM)wParam,(LPARAM)lParam);
   
    }

              /*обработка следущего хука*/
    return CallNextHookEx(HookData->hHook, nCode, wParam, lParam);
}



    /*Установка хука*/
    // HWND hWnd - хэндл окна который будет получать сообщения
    // UINT message - тип сообщения

BOOL __stdcall InstallHook(HWND hWnd,UINT message)
{
    if(!HookData)return FALSE; //указатель на структуру нулевой
    if(HookData->hHook)return TRUE; //Уже установлен 
   
     /*Устанавлвиаем хук*/
    HookData->hHook =
      SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MouseProc,hDllInstance,0);

    if(!HookData->hHook )return FALSE;   //хук не установлен

    HookData->hWnd=hWnd; //Запомним кому будем передавать сообщение
    HookData->message=message; //Запомним тип сообщения 
    return TRUE;
}


          /*Убираем хук*/
BOOL __stdcall RemoveHook()
{
    /*если хук установлен - убираем*/
  if(HookData->hHook)UnhookWindowsHookEx(HookData->hHook); 
  HookData->hHook=NULL;   // зануляем хэндл хука
  return TRUE; 
}

#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{    FILE* f;
    switch (fwdreason) 
    { 
           // прикрепление длл к процессу
      case DLL_PROCESS_ATTACH :
           hDllInstance = hinstDLL;

           //Получим адрес на место где находятся наши переменные
         if(!CreateParamData())return 0;
           f = fopen ("atdat.txt", "a+");
           fprintf (f, "atached\n");
             fclose(f);
           break;

            // отделение от процесса
        case DLL_PROCESS_DETACH : 
          DeleteParamData();
          f = fopen ("atdat.txt", "a+");
           fprintf (f, "deatached\n");
             fclose(f);
             break;

    }
    return 1;
}
//---------------------------------------------------------------------------

Последний раз редактировалось Фенрир; 05.07.2009 в 15:00.
Фенрир вне форума Ответить с цитированием
Старый 05.07.2009, 15:01   #6
Фенрир
fenryrroa@mail.ru
Пользователь
 
Регистрация: 20.01.2009
Сообщений: 10
По умолчанию

// код HookData

Код:
 #include <windows.h> 
#include "Hookdata.h" 

    typedef struct
{
  HWND hWnd; // дескриптор окна получающего сообщения
  HHOOK hHook; // дескриптор хука
  UINT message; // идентификатор сообщения
}THookData;

 extern THookData *HookData = NULL; //Адрес разделяемой памяти


static HANDLE hFileMap = NULL;  //Идентификатор разделяемой памяти,где храним свои переменные 


static SECURITY_ATTRIBUTES sa; 
static char ForSecurityDescriptor[SECURITY_DESCRIPTOR_MIN_LENGTH]; 

static SECURITY_ATTRIBUTES * psa; 
static SECURITY_DESCRIPTOR * psd; 

void __stdcall DeleteParamData(); 
BOOL __stdcall  CreateParamData(); 



      
BOOL __stdcall CreateSecurity() 
{ 
            psa = &sa; 
            psd = (SECURITY_DESCRIPTOR *)ForSecurityDescriptor; 

            if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION)) 
            { 
                return FALSE; 
            } 
            else if (!SetSecurityDescriptorDacl(psd, TRUE, (PACL) NULL, FALSE)) 
            { 
                return FALSE; 
            } 
            else 
            { 
                psa->nLength = sizeof(*psa); 
                psa->lpSecurityDescriptor = psd; 
                psa->bInheritHandle = TRUE; 
            } 
    return TRUE; 
} 


/*Удаляянение параметров из разделяемой памяти*/
void __stdcall WINAPI DeleteParamData() 
{ 
         // убираем указательна структуру хука из разделяемой памяти
   if(HookData)UnmapViewOfFile ((LPVOID)HookData); 
   HookData=NULL; 
   
      // удаляем из ядра дескриптор разделяемой памяти
   if(hFileMap)CloseHandle (hFileMap); 
   hFileMap=NULL;


} 

BOOL __stdcall CreateParamData() 
{ 
  BOOL fInit, fIgnore; 
  char buf[40]; 

  hFileMap=NULL; // дескриптор разделяемой памяти
  HookData=NULL; //Указатель на место в памяти 

  //Создадим SECURITY_DESCRIPTOR
  if(!CreateSecurity())goto OnError; 
  
  //Создадим если нет или откроем если уже создан 
  hFileMap = CreateFileMapping ( 
                INVALID_HANDLE_VALUE, // use paging file 
                &sa,                 // no security attributes 
                PAGE_READWRITE,       // read/write access 
                0,                    // size: high 32-bits 
                sizeof (THookData),   // size: low 32-bits 
                "MouseHook"); // name of map object 
  if (!hFileMap)goto OnError;//Если так и  не  удалось создать 
  
  
   fInit = (GetLastError() != ERROR_ALREADY_EXISTS); // true если разделяемая память не существовала до создания
 
              // загружаем в разделяемую память
  HookData = (THookData *)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,2*sizeof (THookData));


  if (!HookData)goto OnError1; // не удалось загрузить
  
   
  if (fInit) {
   char *ptr=(char *)HookData;
   for(int i=0; i < sizeof(THookData); i++) *ptr++=0;
   }
   
  return TRUE;
   
    
        // метки ошибок
   OnError: 
   DeleteParamData();  // удаление параметров
  MessageBox(NULL,"Error Creating Security Atrubutes","HookDll",MB_OK); 
    return FALSE; 
 OnError1: 
   DeleteParamData(); 
  MessageBox(NULL,"HookData==NULL","HookDll",MB_OK); 
    return FALSE; 
  OnError2: 
    DeleteParamData(); 
  MessageBox(NULL,"Error from InstallHook","HookDll",MB_OK); 
    return FALSE; 

 

}
// Код приложения

Код:

  #include <vcl.h>

    TForm* Form1;
    #define UM_MOUSE WM_USER+1

    BEGIN_MESSAGE_MAP
       MESSAGE_HANDLER (UM_MOUSE, TMessage, OnGetMouse);
   END_MESSAGE_MAP (TComponent)

    typedef BOOL __declspec (dllimport)(*__stdcall SETHOOK) (HWND hWnd,UINT message);
typedef BOOL __declspec (dllimport)(*__stdcall UNHOOK) ();

SETHOOK SetHook;
UNHOOK UnHook;

HINSTANCE hDll;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   hDll = (HINSTANCE) LoadLibrary ("DLL\\mhook.dll");

   SetHook = (SETHOOK)  GetProcAddress (hDll, "InstallHook");

   UnHook = (UNHOOK)  GetProcAddress (hDll, "RemoveHook");
   SetHook (this->Handle, UM_MOUSE) ;   // установка хука

}
//---------------------------------------------------------------------------

  void TForm1 :: OnGetMouse (TMessage& ms) {
          LPMOUSEHOOKSTRUCT pMS = (MOUSEHOOKSTRUCT FAR*)ms.LParam;
      
       if  (ms.WParamLo==WM_RBUTTONDOWN){
          Memo1->Lines->Add("--------------");
         Memo1->Lines->Add(pMS->pt.x);
          Memo1->Lines->Add(pMS->pt.y);
     }
  }
  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//---
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
   FreeLibrary((PVOID)hDll);
}
//---------------------------------------------------------------------------
Фенрир вне форума Ответить с цитированием
Старый 05.07.2009, 15:06   #7
Фенрир
fenryrroa@mail.ru
Пользователь
 
Регистрация: 20.01.2009
Сообщений: 10
По умолчанию

Если кого не затруднит, дайте совет в каком направлении здесь смотреть.
У меня создается впечатление что память получается не совсем разделяемой и работает корректно только в приложении импортирующем функции из длл.
Фенрир вне форума Ответить с цитированием
Старый 05.07.2009, 17:03   #8
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от Фенрир Посмотреть сообщение
У меня создается впечатление что память получается не совсем разделяемой и работает корректно только в приложении импортирующем функции из длл.
в каком именно случае у тебя создаётся впечатление что она "не совсем разделяемая"
rpy3uH вне форума Ответить с цитированием
Старый 05.07.2009, 17:26   #9
Фенрир
fenryrroa@mail.ru
Пользователь
 
Регистрация: 20.01.2009
Сообщений: 10
По умолчанию

Если без мапирования то до окна приложения вообще не доходят мышиные сообщения. Если же использовать разделяемую память то сообщения доходят, но параметры неправильные.
Код:
                  /*Процедура обработки сообщений мыши*/
  LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
{
     if (nCode < 0)  return CallNextHookEx(HookData->hHook, nCode, wParam, lParam);

   if (wParam==WM_RBUTTONDOWN)  {
       FILE* f = fopen ("report.txt", "a");
       fprintf (f, "\nmess: %d--%d\n", ((PMOUSEHOOKSTRUCT)lParam)->pt.x, ((PMOUSEHOOKSTRUCT)lParam)->pt.y);
       fclose(f);
     /*Посылаем хэндлу окна сообщение с параметрами мыши*/
     SendMessage(HookData->hWnd,HookData->message,(WPARAM)wParam,(LPARAM)lParam);
   
    }

              /*обработка следущего хука*/
    return CallNextHookEx(HookData->hHook, nCode, wParam, lParam);
}
Я не понимаю почему в файл не пишется ничего, когда щелчок за пределами окна, но сообщение хэндлу окна посылается (коордмнаты неправильные либо ошибка).
Может нужно както синхронизовать? с помощью объектов синхронизации.
Я пока смутно себе представляю.
Фенрир вне форума Ответить с цитированием
Старый 06.07.2009, 14:34   #10
Фенрир
fenryrroa@mail.ru
Пользователь
 
Регистрация: 20.01.2009
Сообщений: 10
По умолчанию

С мышью чтото не выходит

Код:
     Текст окна всегда выводит корректно, а координаты мыши - нет
   void __fastcall TForm1 :: WndProc (TMessage& ms) {

   if (ms.Msg==UM_MOUSE) {
     LPMOUSEHOOKSTRUCT pMS = (MOUSEHOOKSTRUCT FAR*)ms.LParam;
         char str[100];
          GetWindowText((HWND)ms.WParam, (LPTSTR)str, sizeof(str));
          Memo1->Lines->Add(str);
         Memo1->Lines->Add(pMS->pt.x);
          Memo1->Lines->Add(pMS->pt.y);
   }

  TForm:: WndProc (ms);
}
HOOKPROC
Код:
   
           /*Процедура обработки сообщений мыши*/
  LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
{
      HWND AppWnd;

     if (nCode < 0)  return CallNextHookEx(HookData->hHook, nCode, wParam, lParam);

   if (wParam==WM_RBUTTONDOWN)  {
       AppWnd= GetForegroundWindow();
     /*Посылаем хэндлу окна сообщение с параметрами мыши*/
     SendMessage(HookData->hWnd,HookData->message,(WPARAM)AppWnd,(LPARAM)lParam);
   
    }

              /*обработка следущего хука*/
    return CallNextHookEx(HookData->hHook, nCode, wParam, lParam);
}
/*Устанавлвиаем хук*/
HookData->hHook =
SetWindowsHookEx(WH_MOUSE,(HOOKPROC )MouseProc,hDllInstance,0);
Фенрир вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программа отслеживания изменений области экрана. Elmirill Помощь студентам 7 17.02.2023 13:14
Обработка события нажатия кнопки masm Microsoft Office Access 6 22.08.2011 11:21
Как генерировать события от мышки? Serejka Общие вопросы Delphi 5 01.11.2008 13:48
Обновление заданной области экрана при нажатии клавиши Jack Torrance Win Api 3 26.05.2008 10:57
Перехват события juden Общие вопросы Delphi 5 23.05.2007 12:21