Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2011.08.28;
Скачать: [xml.tar.bz2];

Вниз

Перехват WM_INPUT всех окон   Найти похожие ветки 

 
DelphiN!   (2009-05-10 14:15) [0]

Мне необходимо определить какая из двух мышек поключенных к компьютеру в данный момент активна, нашел в интернете пример работы через RawInput. Программа замечательно работает только когда окно моей программы активно, если перейти на другое окно, программа перестает получать сообщения от мышек(WM_INPUT).
Мне необходимо получать сообщения об активности мыши (WM_INPUT) всегда, активно мое окно или нет. Как это реализовать я не знаю ( Вот код программы :


unit Unit1;

interface

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

const
 ENUMERATE_EXISTING_MICE=0;
 MAX_DEVICES=2;
 MAX_DEVICEID_LEN=2048;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   ApplicationEvents1: TApplicationEvents;
   procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

type
 RAW_INPUT_DATA = record
   num_mice:      integer;
   AMouseHandle:  array[0..MAX_DEVICES] of THandle;
   AMouseID:      array[0..MAX_DEVICES,0..MAX_DEVICEID_LEN] of Cardinal;
   dataBuf:       Pointer;
   data_buf_size: WORD;
 end;

 TMouse_Info=record
   mouse:     integer;
   mouseData: ^RAWMOUSE;
 end;

 const
  WM_INPUT = WM_KEYFIRST-1;

var
 Form1: TForm1;
 rid:   RAW_INPUT_DATA;
 mInfo: TMouse_Info;

implementation

{$R *.dfm}

function FindMouseNum(hdevice:THandle):integer;
var
 i,j,k:   integer;
 DevName: array[0..MAX_DEVICEID_LEN] of Cardinal;
 max:     cardinal;
begin
 max:=2048;
 for i:=0 to rid.num_mice-1 do
   if rid.AMouseHandle[i] = hdevice then
     begin
       if rid.AMouseID[i,0] = 0 then
         GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, @rid.AmouseID[i], max);
       result:=i;
       exit;
     end;
 GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, @DevName, max);
 for i:=0 to rid.num_mice-1 do
   begin
     k:=0;
     for j:=0 to MAX_DEVICEID_LEN do
       if DevName[j] = rid.AmouseID[i,j] then
         inc(k);
     if k >= MAX_DEVICEID_LEN then
       begin
         rid.AMouseHandle[i]:=hdevice;
         result:=i;
         exit;
       end;
   end;
 if rid.num_mice < MAX_DEVICES then
   begin
     for j:=0 to MAX_DEVICEID_LEN do
       rid.AmouseID[rid.num_mice,j]:=devName[j];
     rid.AMouseHandle[rid.num_mice]:=hDevice;
     rid.num_mice:=rid.num_mice+1;
     result:=rid.num_mice-1;
     exit;
   end;
 result:=-1;
end;

procedure RawInputInit;
var
 nDevices: Cardinal;
 pRawIn:   PRAWINPUTDEVICELIST;
 hRawIn:   array[1..100] of RAWINPUTDEVICELIST;
 rawInDev: RAWINPUTDEVICE;
begin
 rid.dataBuf:=nil;
 rid.data_buf_size:=0;
 if GetRawInputDeviceList(nil, nDevices, sizeof(RAWINPUTDEVICELIST)) <> 0 then
   showMessage("Error 1");
 pRawIn:=nil;
 pRawIn:=@hRawIn;
 if GetRawInputDeviceList(pRawIn, nDevices, sizeof(RAWINPUTDEVICELIST)) = -1 then
   showMessage("Error 2");
 rid.num_mice:=0;
 rawInDev.usUsagePage:=1;
 rawInDev.usUsage:=2;
 rawInDev.dwFlags:=0;
 rawInDev.hwndTarget:=0;
 RegisterRawInputDevices(@rawInDev,1,sizeOf(rawInDev));
end;

function HandleWMInput(wnd:HWND; lPar:LPARAM):TMouse_Info;
var
 Raw:    RAWINPUT;
 dwSize: UINT;
 res:    TMouse_Info;
 hRawIn: HRAWINPUT;
 pRawIn: PRAWINPUT;
 mouse:  integer;
begin
 res.mouse:=-1;
 res.mouseData:=nil;
 hRawIn:=lPar;
 GetRawInputData(hRawIn,RID_INPUT, nil, dwSize, sizeof(RAWINPUTHEADER));
 if dwSize = 0 then
   showMessage("Can not allocate memory");
 New(pRawIn);
 if GetRawInputData(hRawIn,RID_INPUT,pRawIn,dwSize,sizeof(RAWINPUTHEADER)) <> dwSize then
   showMessage("GetRawInputData doesn""t return correct size !");
 raw:=pRawIn^;
 res.mouse:=-1;
 if raw.header.dwType = RIM_TYPEMOUSE then
   begin
     mouse:=FindMouseNum(raw.header.hDevice);
     res.mouse:=mouse;
     res.mouseData:=@raw.mouse;
     result:=res;
   end;
end;

function GetInfo(wnd:HWND; lPar:LPARAM):TMouse_Info;
begin
 result:=HandleWMInput(wnd,lpar);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 RawInputInit;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
 m: TMouse_Info;
 p: TPoint;
begin
 if msg.message = WM_INPUT then
   begin
     m:=GetInfo(msg.hwnd,msg.lParam);
     Memo1.Lines.Add("Aktivna mishka : "+intToStr(m.mouse));
     if m.mouse = 1 then
     begin
//*** Работает мышь 1
     end
     else
     begin
       if m.mouse = 0 then
       begin
//*** Работает мышь 0
       end;
     end;
   end;
end;


end.


 
Сергей М. ©   (2009-05-10 20:44) [1]

Ставь глоб.хук типа WH_LL_MOUSE


 
DelphiN!   (2009-05-11 11:01) [2]


> Сергей М. ©   (10.05.09 20:44) [1]


Поставил WH_MOUSE_LL хук, однако теперь функция определения мыши (HandleWMInput) перестала работать выдает ошибку : GetRawInputData doesn""t return correct size !

Вот как я ее вызываю :


function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
var
 m: TMouse_Info;
 Msg: TMsg;
begin
   msg := TMsg(Pointer(lParam)^);
   m:=GetInfo(msg.hwnd,msg.lParam);
   bit.Canvas.TextOut(10,10,"mouse: "+inttostr(m.mouse)+" | WND: "+inttostr(wparam)+" | Lparam: "+inttostr(lparam));
 Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
end;


в чем может быть проблемма??


 
Юрий Зотов ©   (2009-05-11 12:29) [3]

wParam: integer;

wParam: word было в Win16. Об этом можно забыть.


 
DelphiN!   (2009-05-14 15:28) [4]


> Юрий Зотов ©   (11.05.09 12:29) [3]


Изменение типа результата не дало ...


 
Сергей М. ©   (2009-05-14 16:36) [5]


> функция определения мыши (HandleWMInput) перестала работать


Так ты же ей теперь совсем другое передаешь параметром..

Она у тебя ожидает HRAWINPUT, а ты ей почему-то тычешь указатель на MSLLHOOKSTRUCT, который системой передается параметром lParam при вызове хук-функции..

Читать сюда:

http://msdn.microsoft.com/en-us/library/ms644986(VS.85).aspx


 
DelphiN!   (2009-05-15 22:48) [6]


> Сергей М. ©   (14.05.09 16:36) [5]


А как получить HRAWINPUT в хуке на мышь?


 
Сергей М. ©   (2009-05-16 10:10) [7]


> как получить HRAWINPUT в хуке на мышь?


А собссно зачем ?

Чего тебе не хватает в структуре MSLLHOOKSTRUCT ?


 
DelphiN!   (2009-05-18 20:52) [8]


> Сергей М. ©   (16.05.09 10:10) [7]
А собссно зачем ?


Чтобы передать его в HandleWMInput


> ?Чего тебе не хватает в структуре MSLLHOOKSTRUCT ?


А что нужно передать в HandleWMInput из MSLLHOOKSTRUCT чтобы процедура HandleWMInput работала правильно?


 
Сергей М. ©   (2009-05-18 21:28) [9]

)

Я спросил - для ЧЕГО тебе RAW-данные мыши ?
ЧЕГО такого тебе не хватает в MSLLHOOKSTRUCT ? Там тебе и тек.координаты, там тебе и информация о нажатиях/отпусканиях мышиных кнопок ..


 
DelphiN!   (2009-05-20 18:00) [10]


> Сергей М. ©   (18.05.09 21:28) [9]


К одному компьютеру подключен сенсорный экран как второй монитор, на основном мониторе работает оператор. Клиент щелкает по сенсорному экрану(чтобы проголосовать как его обслужил оператор хорошо или плохо), при щелчке по сенсору указатель мыши перемещается на основном мониторе так будто бы сенсорным является основной монитор и щелкнули по нему(особенность сенсорных экранов). Для этого мне необходимо определить кто произвел щелчок по экрану(сенсор или основная мышь) и если клик произвели с сенсорного монитора то перенести положение текущего положения указателя на Screen.Width по координате x и сэмулировать нажатие мыши.
 То есть RAW данные мыши мне нужны для определения кто щелкнул по экрану мышь или сенсорный экран ...


 
Сергей М. ©   (2009-05-21 15:55) [11]


> сенсорный экран как второй монитор, на основном мониторе
> работает оператор


На обоих экранах выводится одно и то же окно, которое видит и оператор и юзер ?


 
DelphiN!   (2009-05-22 16:26) [12]

Нет, 2ой экран - дополнение 1го. Видят они разное. Просто у сенсорного экрана такая особенность, что если щелкают по нему то щелчок он делает на основном экране, вот и приходится извращаться. Писали производителям об этом "глюке", они сказали что решить это нельзя, а сенсорный дисплей у них рассчитан что его используют как основной монитор...


 
Сергей М. ©   (2009-05-22 16:45) [13]


> 2ой экран - дополнение 1го


Что значит "дополнение" ?


 
DelphiN!   (2009-05-22 18:17) [14]


> Сергей М. ©   (22.05.09 16:45) [13]


Подключен как 2ой монитор. Изображение на них разное, на 1ом - окна оператора, на 2ом развернутое во весь экран окно для клиента с атрибутом fsStayOnTop ...


 
Сергей М. ©   (2009-05-24 19:45) [15]

Т.е. ты хочешь сказать, что форма 2 твоего приложения, показанная на экране сенсорного монитора, не имеет фокуса ввода (фокус ввода имеет другая форма 1 твоего же приложения, показанная на экране оператора), но тем не менее события сенсорного ввода поступают как сообщения о мышином вводе в очередь сообщений окна формы 1 ?


 
DelphiN!   (2009-05-27 11:41) [16]


> Сергей М. ©   (24.05.09 19:45) [15]


Оператор может работать с не моим окном(например с Wordом), в этот момент ни 1ая форма ни 2ая моя форма не имеет фокус. Однако в этот момент клиент может щелкнуть по экрану сенсора и мне нужно определить был ли этот щелчок с сенсора и если да, то обработать его. Однако для постоянного контроля мне нужен глобальный хук, но на данном этапе я к сожалению не могу определить индекс устройства с которого был произведен щелчок в глобальном хуке.


 
Сергей М. ©   (2009-05-28 12:51) [17]

Видимо, RegisterRawInputDevices следует вызывать в процедуре инициализации dll-модуля глобального WH_GETMESSAGE-хука .


 
DelphiN!   (2009-06-04 13:50) [18]


> Сергей М. ©   (28.05.09 12:51) [17]


Точно! Помогло, спасибо!
Только теперь появилась другая проблема.
Когда я двигаю или нажимаю 1ой или 2ой мышкой программа отличает их друг от друга,
 на как только я эмитирую нажатие мыши на 2ом мониторе программа определяет индекс устройства при имитации как -1, после основная(1ая) мышь определяется как вторая. Как решить эту проблему?
Вот код имитации :

 SetCursorPos(X, Y);
 mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
 mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)


 
MadNash ©   (2009-08-12 15:12) [19]

Для того, что бы окно получала WM_INPUT в неактивном состоянии надо значение rawInDev.dwFlags установить в $00000100 (RIDEV_INPUTSINK), кроме того, с помощью флагов можно даже установить фильтр по значению UsagePage и Usage.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2011.08.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.004 c
15-1304354356
@!!ex
2011-05-02 20:39
2011.08.28
Как влияет Range check на работу результирующего кода?


1-1264209222
Gear
2010-01-23 04:13
2011.08.28
вызов MessageDlg из отдельной нитки


15-1305011498
Фокс Йовович
2011-05-10 11:11
2011.08.28
Аутстаффинг


3-1263280888
Tornado
2010-01-12 10:21
2011.08.28
Не могу записать библиотеку


1-1265138738
Vincent
2010-02-02 22:25
2011.08.28
Как прочитать память у DLL (ReadProcessMemory):DllName.dll+offset





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский