Прихващане на WM_INPUT на всички прозорци

Трябва да определя коя от двете мишки, свързани към компютъра, е активна в момента, намерих пример за работа чрез RawInput в Интернет. Програмата работи чудесно само когато прозорецът на моята програма е активен, ако превключите на друг прозорец, програмата спира да получава съобщения от мишки (WM_INPUT). Трябва да получавам съобщения за дейността на мишката (WM_INPUT), когато прозорецът ми е активен или не. Не знам как да приложа това (ето кода на програмата:

използва Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, RawInput_h, AppEvnts, StdCtrls, ExtCtrls;

const ENUMERATE_EXISTING_MICE=0; MAX_DEVICES=2; MAX_DEVICE > тип TForm1 = class(TForm) Memo1: TMemo; Събития на приложението1: TApplicationEvents; procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean); процедура FormCreate(Подател: TObject); частен < Лични декларации > публичен < Публични декларации > край;

тип RAW_INPUT_DATA = запис брой_мишки: цяло число; AMouseHandle: масив[0..MAX_DEVICES] от THandle; AMouseID: масив [0..MAX_DEVICES,0..MAX_DEVICEID_LEN] от кардинал; dataBuf: показалец; data_buf_size: WORD; край;

TMouse_Info=запис мишка: цяло число; данни за мишката: ^RAWMOUSE; край;

const WM_INPUT = WM_KEYFIRST-1;

var Формуляр1: TForm1; отървете: RAW_INPUT_DATA; mInfo: TMouse_Info;

функция FindMouseNum(hdevice:THandle):integer; var i,j,k: integer; Име на разработка: масив [0..MAX_DEVICEID_LEN] от кардинал; max: кардинал; започнете max:=2048; for i:=0 to rid.num_mice-1 do if r > начало ако r > GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, @rid.AmouseID[i], max); резултат:=i; изход; край; GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, @DevName, max); for i:=0 to rid.num_mice-1 do begin k:=0; за j:=0 до MAX_DEVICEID_LEN направете ако DevName[j] = rid.AmouseID[i,j] тогава inc(k); ако k >= MAX_DEVICEID_LEN тогава започнете r > резултат:=i; изход; край; край; ако rid.num_mice r > r > резултат:=rid.num_mice-1; изход; край; резултат:=-1; край;

procedure RawInputInit; var nDevices: Cardinal; pRawIn: PRAWINPUTDEVICELIST; hRawIn: масив [1..100] от RAWINPUTDEVICELIST; rawInDev: RAWINPUTDEVICE; begin r > r > if GetRawInputDeviceList(nil, nDevices, sizeof(RAWINPUTDEVICELIST)) <> 0 след това showMessage("Грешка 1"); pRawIn:=нула; pRawIn:=@hRawIn; ако GetRawInputDeviceList(pRawIn, nDevices, sizeof(RAWINPUTDEVICELIST)) = -1 тогава showMessage("Грешка 2"); r > rawInDev.usUsagePage:=1; rawInDev.usUsage:=2; rawInDev.dwFlags:=0; rawInDev.hwndTarget:=0; RegisterRawInputDevices(@rawInDev,1,sizeOf(rawInDev)); край;

функция HandleWMInput(wnd:HWND; lPar:LPARAM):TMouse_Info; var Raw: RAWINPUT; dwSize: UINT; res: TMouse_Info; hRawIn: HRAWINPUT; pRawIn: PRAWINPUT; мишка: цяло число; начало res.mouse:=-1; res.mouseData:=нула; hRawIn:=lPar; GetRawInputData(hRawIn,RID_INPUT, нула, dwSize, sizeof(RAWINPUTHEADER)); ако dwSize = 0 тогава showMessage("Не може да се разпредели памет"); Ново(pRawIn); ако GetRawInputData(hRawIn,RID_INPUT,pRawIn,dwSize,sizeof(RAWINPUTHEADER)) <> dwSize then showMessage("GetRawInputData does""не връща правилен размер!"); суров:=pRawIn^; res.mouse:=-1; ако raw.header.dwType = RIM_TYPEMOUSE тогава започнете mouse:=FindMouseNum(raw.header.hDevice); res.mouse:=мишка; res.mouseData:[email protected]; резултат:=res; край; край;

функция GetInfo(wnd:HWND; lPar:LPARAM):TMouse_Info; begin result:=HandleWMInput(wnd,lpar); end;

процедура TForm1.FormCreate(Подател: TObject); начало RawInputInit; край;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean); var m: TMouse_Info; p: TPoint; започнете ако msg.message = WM_INPUT тогава започнете m:=GetInfo(msg.hwnd,msg.lParam); Memo1.Lines.Add("Активна мишка: "+intToStr(m.mouse)); if m.mouse = 1 then begin //*** Mouse 1 работи end else begin if m.mouse = 0 then begin //*** Mouse 0 работи end; край; край; край;

Задайте глобална кука като WH_LL_MOUSE

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

Зададох куката WH_MOUSE_LL, но сега функцията за откриване на мишката (HandleWMInput) спря да работи и дава грешка:GetRawInputData не връща правилния размер!

Ето как го наричам:

функция SysMsgProc(код: цяло число; wParam: дума; lParam: longint): longint; stdcall; var m: TMouse_Info; Съобщение: TMsg; започнете съобщение := TMsg(Показател(lParam)^); m:=GetInfo(msg.hwnd,msg.lParam); bit.Canvas.TextOut(10,10,"mouse: "+inttostr(m.mouse)+" WND: "+inttostr(wparam)+" Lparam: "+inttostr(lparam)); Резултат:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam); end;

какъв може да е проблема??

wParam: думата беше в Win16. Можете да забравите за това.

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

Промяната на типа резултат не даде.

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

Така че сега му давате напълно различен параметър ..

Тя очаква HRAWINPUT от вас и по някаква причина вие й казватепоставете указател към MSLLHOOKSTRUCT, който се предава от системата като параметър lParam при извикване на hook функцията.

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

Как да получа HRAWINPUT в куката на мишката?

> как да получа HRAWINPUT в куката на мишката?

И sobssno защо?

Какво ви липсва в структурата MSLLHOOKSTRUCT?

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

За да го предадете на HandleWMInput

> ?Какво ви липсва в структурата MSLLHOOKSTRUCT?

И какво трябва да се предаде на HandleWMInput от MSLLHOOKSTRUCT, за да може процедурата HandleWMInput да работи правилно?

Попитах - ЗА КАКВО са ви необходими RAW данни за мишката? КАКВО ви липсва в MSLLHOOKSTRUCT? Там имате текущи координати, там имате информация за натискане / освобождаване на бутоните на мишката ..

DelphiN! (20.05.2009 18:00) [10]

Сензорен екран е свързан към един компютър като втори монитор, оператор работи на основния монитор. Клиентът щраква върху сензорния екран (за да гласува как операторът го е обслужил добре или зле), при щракване върху сензора, показалецът на мишката се движи върху основния монитор, сякаш основният монитор е сензорен и щрака върху него (функция на сензорните екрани). За да направя това, трябва да определя кой е щракнал върху екрана (сензор или основна мишка) и ако щракването е направено от сензорния монитор, след това да преместя позицията на текущата позиция на показалеца на Screen.Width по координатата x и да емулирам щракване с мишката. Тоест имам нужда от RAW данни за мишката, за да определя кой е кликнал върху екрана с мишка или сензорен екран.

> сензорен екран като втори монитор, на основния монитор > Операторътработи

И на двата екранапоказва се същият прозорец, който виждат и операторът, и потребителят?

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

Не, вторият екран е допълнение към първия. Те виждат различни неща. Просто тъчскрийнът има такава особеност, че ако цъкнеш, после прави щракане на главния екран, така че трябва да го извратиш. Писахме на производителите за този "бъг", те казаха, че не може да бъде решен, а сензорният дисплей е предназначен за тях да се използва като основен монитор.

> 2-ри екран - добавяне 1-ви

Какво означава "добавка"?

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

Свързан като 2-ри монитор. Изображението на тях е различно, на 1-во - прозорец на оператора, на 2-ро - прозорец на цял екран за клиента с атрибут fsStayOnTop.

Тези. Искате да кажете, че Формуляр 2 на вашето приложение, показан на сензорния екран, няма фокус за въвеждане (фокусът за въвеждане има друг формуляр 1 от същото приложение, показан на екрана на оператора), но въпреки това събитията при докосване се получават като съобщения за въвеждане на мишката в опашката за съобщения на прозореца на Формуляр 1?

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

Операторът може да работи с прозорец, който не е мой (например с Word), в този момент нито 1-вата форма, нито моята 2-ра форма са на фокус. В този момент обаче клиентът може да щракне върху екрана на сензора и аз трябва да определя дали това щракване е от сензора и, ако е така, да го обработя. За постоянен контрол обаче ми трябва глобална кука, но на този етап за съжаление не мога да определя индекса на устройството, от което е направено щракването в глобалната кука.

Очевидно RegisterRawInputDevices трябва да се извика в процедурата за инициализация на dll модула на глобалната кука WH_GETMESSAGE.

DelphiN! (04.06.2009 13:50) [18]

Точно! Помогнах, благодаря! Само сега има друг проблем. Когато преместя или натисна 1-вата или 2-рата мишка, програмата ги разграничава една от друга, но щом щракна с мишката върху 2-рия монитор, програмата определя индекса на устройството при симулиране като -1, след като основната (1-ва) мишка е дефинирана като втора. Как да решим този проблем? Ето симулационния код: SetCursorPos(X, Y); mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)