Вверх ↑
Этот топик читают: Гость
Ответов: 578
Рейтинг: 14
#16: 2011-06-20 19:09:36 ЛС | профиль | цитата
Ivann, можешь добавить реакцию на нажатие кнопок мыши
карма: 0

0
Ответов: 3349
Рейтинг: 233
#17: 2011-06-20 20:57:21 ЛС | профиль | цитата
GanjaKyp, Хватит?
code_24439.txt
карма: 1

1
файлы: 1code_24439.txt [4.5KB] [448]
Голосовали:GanjaKyp
Ответов: 3889
Рейтинг: 362
#18: 2011-06-20 21:21:52 ЛС | профиль | цитата
Ivann, под WOW64 (Win7 x64) работает через раз (перезапускать приходится), когда "работает" выдаёт несуразное типа "удерживается клавиша 54780" или, при движениях мыши, тысячи "отпущена клавиша мыши ". Сейчас попробую старый пример.

В общем, выдаёт onMouseEvent вечный ноль (байт), что на тачпаде, что на USB-мышке (

Осталось джойстики добить и различение нескольких одновременных мышек и клавиатур ))
------------ Дoбавленo в 21.20:
Мда, на ноутбуке под WOW64 на все кнопки выдаёт код 30254
------------ Дoбавленo в 21.21:
То же самое с внешней клавиатурой на USB...
карма: 1

0
Ответов: 3349
Рейтинг: 233
#19: 2011-06-20 21:30:22 ЛС | профиль | цитата
1nd1g0, Видимо RI как то не так там работает, протестируй на x32
------------ Дoбавленo в 21.30:
Эх...Видимо старания все зря
карма: 1

0
Ответов: 3889
Рейтинг: 362
#20: 2011-06-20 21:36:53 ЛС | профиль | цитата
Ivann, ничего не было зря, разберёмся, будь уверен. Ты уже много сделал. Трудно переоценить. На x32 XP SP3 первый пример работал, сейчас на планшете (!!) под Tablet PC запущу оба примера, гляну какие устройства ввода оно найдёт )) Потом на планшете под Windows 7 x86 (32 bit).
Полезное дело делаешь, коллега. Ты пока посмотри, как можно различать девайсы меж собой. Чтобы, скажем, тачпадом одно делать, мышкой - другое) Или две клавиатуры под каждую руку, красота) Джойстики и геймпады ниже приоритетом, но тоже интересны, если есть такие у тебя. Пойду на планшеты схожу.
карма: 1

0
Ответов: 3349
Рейтинг: 233
#21: 2011-06-20 21:40:00 ЛС | профиль | цитата
1nd1g0 писал(а):
Полезное дело делаешь, коллега. Ты пока посмотри, как можно различать девайсы меж собой. Чтобы, скажем, тачпадом одно делать, мышкой - другое) Или две клавиатуры под каждую руку, красота) Джойстики и геймпады ниже приоритетом, но тоже интересны, если есть такие у тебя. Пойду на планшет схожу.

Есть только мыши и клавиатуры. Но вед RI выдает тип устройства(Мышь, Клава,HID)?
карма: 1

0
Ответов: 3889
Рейтинг: 362
#22: 2011-06-20 21:52:45 ЛС | профиль | цитата
Ivann, да, тип-то выдаёт. Я про одновременное использование однотипных устройств. При приёме сообщений там, кажется, можно увидеть, какая именно клавиатура (из десятка) его породила. Система, конечно, для генерации обычных событий их все в одну объединяет, но работающая с RI программа может решить, как реагировать, скажем, если нажали на пробел на клавиатуре №2, или №1, не так?
------------ Дoбавленo в 21.52:
Ivann писал(а):
Есть только мыши и клавиатуры

Да нет, всякие джойстики тожедолжны быть, всё, что не клавиатура и мышка, должно быть "HID". А уже внутри HID своя классификация (там сотни устройств). Главное получить все данные, потом поразбираться и поклассифицировать могу попробовать. А пока пойду решать проблему с клавиатурой и мышью по WOW64 на NT6.x.
карма: 1

0
Ответов: 3349
Рейтинг: 233
#23: 2011-06-20 22:11:42 ЛС | профиль | цитата
1nd1g0, Хендл устройства возвращает ведь
карма: 1

0
Ответов: 3889
Рейтинг: 362
#24: 2011-06-20 23:00:07 ЛС | профиль | цитата
Ivann, На планшете под NT5.1 (Tablet PC 2005 = XP SP3 32bit) самый самый первый пример с опросом нашёл дубликаты - 2 HID (видимо, спецкнопки планшета), 2 MOUSE (видимо, перо), 2 Keyboard (это он так многозначительно курсорный джойстик и пару кнопок называет), имён (name) устройств выдать не смог, выдал символ вертикальной палочки. Не может ли так быть, что мы что-то упустили в индийском коде (моё сообщение на первой странице темы), который нужен обязательно для работы с GetRawInputDeviceList
функция GetRawInputDeviceList - один из лучших примеров индийского кода, порождённого в Microsoft. При её использовании приходится помнить о некоторых подводных камнях, описанных тут. Теперь понятно, почему практическое использование RI встречается достаточно редко - надо быть либо очень внимательным и дотошным человеком, либо ... индусом.


Второй пример на планшете под NT5.1 x32 клавиши считывает правильно, из того десятка, которые вообще есть на планшете.

Нажатия пера вообще за мышь не считает (хотя мышь-то нашёл... которой там не было... а надо бы прицепить... да... пошёл пробовать). Надо на обычной XP с обычной мышкой завтра попробовать.

Сейчас перейду на Win7 x86 (32 bit), помучаю там.

[offtop]не смотрите на прикреплённый файл, он прилип с первой страницы во время цитирования, жалко удалять )))[/offtop]
------------ Дoбавленo в 23.00:
Прицепил USB мышку к планшету с NT5.1, третий пример, что с мышкой, стал корректно отрабатывать на клике левой кнопкой, даже пером. Сейчас попробую под NT6.x 32bit...
карма: 1

0
файлы: 1rawinput.png [15.4KB] [1532]
Ответов: 3349
Рейтинг: 233
#25: 2011-06-20 23:08:33 ЛС | профиль | цитата
1nd1g0, Я спать, утро вечера мудренее (c)
карма: 1

0
Ответов: 3889
Рейтинг: 362
#26: 2011-06-20 23:18:48 ЛС | профиль | цитата
Windows 7 32 bit Tablet PC - RAW INPUT
------------ Дoбавленo в 23.18:
Ivann, творческих озарений во сне, я последую твоему примеру. Как видишь, на Win7 32 bit все твои примеры работают, на скриншоте планшет Toshiba и его тачпад, перо, клавиатура и куча спецустройств HID, включая акселлерометр (датчик положения). Так что ненулевая вероятность, что проблемы в 64-битной системе с её эмуляцией. Впечатление, будто там 64-хбитный RawInput, оттуда такие гигантские числа в сканкодах

Если у кого-то из сочувствующих под рукой 64-хразрядная система, проверьте, пожалуйста, работу пары схем:

Опрос устройств интерфейса с человеком в системе:

Add(MainForm,5093709,161,154)
{
Width=600
Height=437
link(onCreate,4674337:doEnum,[])
}
Add(InlineCode,4674337,210,168)
{
WorkPoints=#6:doEnum|
EventPoints=#8:onDevice|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|29:uses kol,Share,Debug,Windows;|0:|4:type|31: tagRAWINPUTDEVICELIST = record|18: hDevice:THandle;|15: dwType:DWORD;|5: end;|0:|32: tagRID_DEVICE_INFO_HID = record|22: dwVendorId: DWORD;|23: dwProductId: DWORD;|27: dwVersionNumber: DWORD;|22: usUsagePage: WORD;|18: usUsage: WORD;|6: end;|0:|37: tagRID_DEVICE_INFO_KEYBOARD = record|18: dwType: DWORD;|21: dwSubType: DWORD;|26: dwKeyboardMode: DWORD;|34: dwNumberOfFunctionKeys: DWORD;|32: dwNumberOfIndicators: DWORD;|31: dwNumberOfKeysTotal: DWORD;|7: end; |1: |34: tagRID_DEVICE_INFO_MOUSE = record|16: dwId: DWORD;|29: dwNumberOfButtons: DWORD;|24: dwSampleRate: DWORD;|7: end; |2: |52: RID_DEVICE_INFO_HID = tagRID_DEVICE_INFO_HID;|58: RID_DEVICE_INFO_KEYBOARD = tagRID_DEVICE_INFO_KEYBOARD; |54: RID_DEVICE_INFO_MOUSE = tagRID_DEVICE_INFO_MOUSE;|0:|28: tagRID_DEVICE_INFO = record|18: cbSize: DWORD;|18: dwType: DWORD;|19: case Integer of|38: 0: (mouse: RID_DEVICE_INFO_MOUSE);|44: 1: (keyboard: RID_DEVICE_INFO_KEYBOARD);|34: 2: (hid: RID_DEVICE_INFO_HID);|6: end;|38: RID_DEVICE_INFO = tagRID_DEVICE_INFO;|1: |45: TRAWINPUTDEVICELIST = tagRAWINPUTDEVICELIST;|44: PRAWINPUTDEVICELIST = ^TRAWINPUTDEVICELIST;|0:|78: TGetRawInputDeviceList = function (pRawInputDeviceList: PRAWINPUTDEVICELIST;|58: var puiNumDevices: UINT; cbSize: UINT): UINT; stdcall;|4: |87: TGetRawInputDeviceInfo = function (hDevice: THANDLE; uiCommand: UINT; pData: POINTER;|38: var pcbSize: UINT): UINT; stdcall;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|28: User32DllHandle:THandle;|49: GetRawInputDeviceList:TGetRawInputDeviceList;|52: RAWINPUTDEVICELIST:array of TRAWINPUTDEVICELIST;|49: GetRawInputDeviceInfo:TGetRawInputDeviceInfo;|9: public|23: onDevice:THI_Event;|3: |45: procedure doEnum(var dt:TData; idx:word);|5: end;|0:|14:implementation|0:|40:const USER32 = 'User32.DLL';|29: RIM_TYPEHID = 2;|29: RIM_TYPEKEYBOARD = 1;|29: RIM_TYPEMOUSE = 0;|37: RIDI_DEVICENAME = $20000007;|37: RIDI_DEVICEINFO = $2000000b;|37: RIDI_PREPARSEDDATA = $20000005;|0:|31:function IsWindowsNt():boolean;|33:var OSVersionInfo:TOSVersionInfo;|5:begin|15: Result:=false;|50: FillChar(OSVersionInfo,SizeOf(TOSVersionInfo),0);|61: OSVersionInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);|29: GetVersionEx(OSVersionInfo);|69: result := OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT; |14: result:=true;|4:end;|0:|29:procedure THiAsmClass.doEnum;|13:var c,s:UINT;|14: i:integer;|33: n:array[0..1023] of AnsiChar;|17: t,name:TData;|5:begin|20: if IsWindowsNt then|7: begin|47: User32DllHandle := GetModuleHandle(USER32);|31: if User32DllHandle = 0 then|9: begin|45: User32DllHandle := LoadLibrary(USER32);|14: end; |87: @GetRawInputDeviceList := GetProcAddress(User32DllHandle, 'GetRawInputDeviceList');|88: @GetRawInputDeviceInfo := GetProcAddress(User32DllHandle, 'GetRawInputDeviceInfoA');|11: c := 0;|61: GetRawInputDeviceList(nil,c,SizeOf(TRAWINPUTDEVICELIST));|92: SetLength(RAWINPUTDEVICELIST,c); |80: GetRawInputDeviceList(@RAWINPUTDEVICELIST[0],c,SizeOf(TRAWINPUTDEVICELIST));|30: for i:=0 to c - 1 do begin|79: GetRawInputDeviceInfo(RAWINPUTDEVICELIST[i].hDevice,RIDI_DEVICENAME,@n,s);|41: case RAWINPUTDEVICELIST[i].dwType of|42: RIM_TYPEHID: dtString(t,'HID');|44: RIM_TYPEMOUSE: dtString(t,'MOUSE');|53: RIM_TYPEKEYBOARD: dtString(t,'KEYBOARD'); |9: end;|22: dtString(name,n);|22: t.ldata := @name;|29: _hi_OnEvent(onDevice,t);|8: end;|6: end;|4:end;|0:|4:end.|
link(onDevice,4274780:doStr,[])
}
Add(StringTable,12067686,322,168)
{
Top=25
Width=600
Height=375
Columns=#8:type=100|8:name=495|
}
Add(MT_String,4274780,266,168)
{
link(onResult,12067686:doAdd,[])
}


Глобальный захват нажатий мыши и клавиатуры без hook.dll, рекомендуемый Microsoft (по MSDN). Требуется модуль RInput.pas от из этого архива, достаточно переташить папку HiAsm на одноимённую папку с установленной средой у Вас.




Add(MainForm,3921136,315,189)
{
Point(PHandle)
link(onCreate,8770334:SetRawInput,[(359,209)(359,244)(303,244)(303,279)])
}
Add(InlineCode,8770334,315,273)
{
WorkPoints=#11:SetRawInput|
EventPoints=#9:onKeyDown|7:onKeyUp|8:onRepeat|12:onMouseEvent|0:|
VarPoints=#1:X|1:Y|5:Flags|6:BFlags|
DataPoints=#7:Control|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|45:uses kol,Share,Debug,Windows,RInput,Messages;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|26: OldMessage:TOnMessage;|18: ctrl:PControl;|17: key,mes:UINT;|33: mx,my,_flags,_bflags:integer;|4: |68: function onMessage( var Msg: TMsg; var Rslt: Integer ): Boolean;|10: public |4: |62: Control,onKeyDown,onKeyUp,onRepeat,onMouseEvent:THI_Event;|3: |50: procedure SetRawInput(var dt:TData; Idx:WORD);|40: procedure X(var dt:TData; Idx:WORD);|40: procedure Y(var dt:TData; Idx:WORD);|44: procedure Flags(var dt:TData; Idx:WORD);|45: procedure BFlags(var dt:TData; Idx:WORD);|5: end;|0:|14:implementation|0:|34:procedure THiAsmClass.SetRawInput;|38:var rid:array[0..1] of RAWINPUTDEVICE;|5:begin|43: ctrl:=PControl(ReadInteger(dt,Control));|32: OldMessage := ctrl.OnMessage;|35: Ctrl.OnMessage := onMessage; |27: RID[0].usUsagePage := 1;|27: RID[0].usUsage := 6;|40: RID[0].dwFlags := RIDEV_NOLEGACY;|38: RID[0].hwndTarget := Ctrl.Handle; |27: RID[1].usUsagePage := 1;|27: RID[1].usUsage := 2;|41: RID[1].dwFlags := RIDEV_INPUTSINK;|40: RID[1].hwndTarget := Ctrl.Handle; |58: RegisterRawInputDevices(@RID,2,SizeOf(RAWINPUTDEVICE));|5:end; |0:|76:function THiAsmClass.onMessage( var Msg: TMsg; var Rslt: Integer ): Boolean;|6:const |22: WM_INPUT = $00FF;|17:var RI:RAWINPUT;|12: s:UINT;|15: t,f:TData;|5:begin|30:if Msg.message = WM_INPUT then|14: begin |22: s:=SizeOf(RAWINPUT);|81: GetRawInputData(HRAWINPUT(Msg.lParam),RID_HEADER,@RI,s,SizeOf(RAWINPUTHEADER));|27: case Ri.Header.dwType of |20: RIM_TYPEKEYBOARD:|9: begin|83: GetRawInputData(HRAWINPUT(Msg.lParam),RID_INPUT,@RI,s,SizeOf(RAWINPUTHEADER));|114: if (key = RI.keyboard.vKey) and (mes = RI.keyboard.message) then _hi_OnEvent(onRepeat, RI.keyboard.vKey) else|33: case RI.keyboard.message of|58: WM_KEYDOWN:_hi_OnEvent(onKeyDown,RI.keyboard.vKey);|55: WM_KEYUP: _hi_OnEvent(onKeyUp,RI.keyboard.vKey);|10: end;|8: end;|18: RIM_TYPEMOUSE: |9: begin|83: GetRawInputData(HRAWINPUT(Msg.lParam),RID_INPUT,@RI,s,SizeOf(RAWINPUTHEADER));|32: _flags := ri.Mouse.usFlags;|45: _bflags := ri.Mouse.union.usButtonFlags;|30: mx := ri.mouse.lLastX; |29: mY := ri.mouse.lLastY; |30: _hi_OnEvent(onMouseEvent);|8: end;|7: end; |27: key := RI.keyboard.vKey;|30: mes := RI.keyboard.message;|4:end;|45:Result := _hi_OnMessage(OldMessage,Msg,Rslt);|4:end;|0:|24:procedure THiAsmClass.X;|5:begin|18: dtInteger(dt,mx);|5:end; |0:|24:procedure THiAsmClass.Y;|5:begin|18: dtInteger(dt,my);|5:end; |0:|28:procedure THiAsmClass.Flags;|5:begin|22: dtInteger(dt,_flags);|5:end; |0:|29:procedure THiAsmClass.BFlags;|5:begin|23: dtInteger(dt,_bflags);|5:end; |0:|4:end.|
link(onKeyDown,7930936:doWork1,[])
link(onKeyUp,7930936:doWork2,[])
link(onRepeat,7930936:doWork3,[])
link(onMouseEvent,393041:doBits,[(359,300)(359,352)(324,352)(324,405)])
link(Control,3921136:PHandle,[])
}
Add(ChanelToIndex,7930936,427,273)
{
Count=3
Point(Data)
link(onIndex,7108844:doGetString,[(467,279)(467,314)])
}
Add(StrList,7108844,476,266)
{
Strings=#14:Нажата клавиша|15:Опущена клавиша|20:Удерживается клавиша|
Point(doGetString)
Point(onGetString)
link(onGetString,3750159:doString,[])
}
Add(FormatStr,3750159,525,273)
{
link(onFString,7567543:doWork2,[])
link(Str2,7930936:Data,[(538,261)(568,261)(568,330)(433,330)])
}
Add(ListBox,15090687,595,273)
{
Left=50
Top=60
Width=130
Height=200
Align=5
AddType=1
}
Add(IntToBits,393041,336,399)
{
ZeroBits=1
link(Value,8770334:BFlags,[])
link(onBit1,14212637:doWork1,[])
link(onBit2,14212637:doWork2,[])
link(onBit3,14212637:doWork3,[])
link(onBit4,14212637:doWork4,[])
}
Add(ChanelToIndex,14212637,385,399)
{
Count=4
link(onIndex,1227553:doGetString,[])
}
Add(StrList,1227553,483,357)
{
Strings=#24:Нажата левая кнопка мыши|26:Отпущена левая кнопка мыши|25:Нажата правая кнопка мыши|27:Отпущена правая кнопка мыши|
Point(doGetString)
Point(onGetString)
link(onGetString,7108463:doWork2,[])
}
Add(HubEx,7567543,574,273)
{
link(onEvent,15090687:doAdd,[])
}
Add(HubEx,7108463,574,364)
{
Angle=3
link(onEvent,7567543:doWork3,[])
}

карма: 1

1
файлы: 2win732bitrawinput.png [14.4KB] [1024], rawinputmodule.7z [1.8KB] [303]
Голосовали:login
Ответов: 3349
Рейтинг: 233
#27: 2011-06-21 03:21:40 ЛС | профиль | цитата
1nd1g0, На x64 и правда не работает.
карма: 1

0
Ответов: 3889
Рейтинг: 362
#28: 2011-06-21 09:46:09 ЛС | профиль | цитата
Ivann, вернее, что-то работает, но криво, что-то не то с размерностью данных что ли. Жаль не сообразил сразу с повышенными правами запустить. Опрос устройств-то он делает, и делает нормально. А вот в 32-хбитной Windows Tablet PC 2005 (клон XP SP3 только с системой рукописного ввода) устройства опрашивает очень странно - вместо имён - палочки. Сообщения нажатий ловит нормально.

У меня на x64 при движениях мыши (не нажатиях, а движениях) уже принимаются нули статуса мышиных кнопок, "кнопка отпущена", хотя её никто и не нажимал. И регулярно "зажата клавиша" с каким-нибудь гигантским сканкодом. У кого-то по-другому проявляются проблемы, кто ещё попробовал?
карма: 1

0
Ответов: 578
Рейтинг: 14
#29: 2011-06-21 10:38:13 ЛС | профиль | цитата
Ivann, сохранил RInput.pas в ...DelphiCode, но при компиляции hiasm мне пишет
Crogram FilesHiAsmElementsdelphicodeRInput.pas(1) Fatal: Line too long (more than 1023 characters)
карма: 0

0
Ответов: 3889
Рейтинг: 362
#30: 2011-06-21 16:37:29 ЛС | профиль | цитата
GanjaKyp, Откуда брали юнит? Если копировали из сообщения на первой странице, то попробуйте из моего архива в сообщении выше (20 Jun 2011 23:18)
------------ Дoбавленo в 16.37:
Ivann, продолжаю разбираться с проблемным Raw Input на WOW64 дебаггером и дизассемблером и могу сказать, что частично я оказался прав в своих предположениях. Как минимум на NT6.x x64, структура данных, формируемая системой по вызову GetRawInputBuffer выравнивается не под 32, а под 64 бита не зависимо от того, какой разрядности и в какой среде работает приложение . Похоже, одни и те же индусы занимались всем набором функций Raw Input И это при том, что в комментариях к единственной альтернативе, не требующей dll и не вызывающей негативную реакцию антивирусов - Low Level Keyboard Hook они же пишут
MSDN писал(а):
In most cases where the application needs to use low level hooks, it should monitor raw input instead. This is because raw input can asynchronously monitor mouse and keyboard messages that are targeted for other threads more effectively than low level hooks can. For more information on raw input, see Raw Input.

То есть "Большинству приложений, которые работают с хуками настоятельно рекомендуется перейти на Raw Input, т.к. RI ловит чужие клавиши эффективнее LL. Идите и почитайте про RI". И это - правда, механизм LL хуков устроен так, что при определённых условиях нажатия на клавиши и кнопки мыши остаются незарегистрированными либо частично (До Windows 7), либо полностью (начиная с Windows 7 ядро оставляет за собой право снимать LL хук без уведомления приложения, его поставившего, в результате оно может ждать сообщений вечно).

На форумах Microsoft видел как минимум два багрепорта про ошибку с размерностью данных под x64, но никто до сих пор ничего не исправил (NT6.x SP1)
карма: 1

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)