{"id":547,"date":"2010-08-01T19:54:06","date_gmt":"2010-08-01T18:54:06","guid":{"rendered":"http:\/\/netrix.org.pl\/?p=547"},"modified":"2011-02-11T23:59:21","modified_gmt":"2011-02-11T22:59:21","slug":"raw-input","status":"publish","type":"post","link":"https:\/\/netrix.org.pl\/index.php\/2010\/08\/01\/raw-input\/","title":{"rendered":"RAW Input"},"content":{"rendered":"<p>Tym razem b\u0119dzie zn\u00f3w co\u015b zwi\u0105zanego z systemem Windows i programowaniem gier, czyli obs\u0142uga myszy za pomoc\u0105 RAW Input. Jest to jeden z trzech popularnych sposob\u00f3w obs\u0142ugi tych urz\u0105dze\u0144. Pozosta\u0142ymi s\u0105 komunikaty procedury okna oraz DirectInput, z tym \u017ce ten ostatni jest niezalecany i ju\u017c nie jest wspierany przez Microsoft na rzecz w\u0142a\u015bnie RAW Input. Jednak dlaczego nie te dwa?<\/p>\n<p>Komunikaty procedury okna nie s\u0105 tak naprawd\u0119 takie z\u0142e, co wi\u0119cej bardzo dobrze nadaj\u0105 si\u0119 do ma\u0142ych gier casualowych, najlepiej tych odpalanych w oknie, poniewa\u017c warto\u015bciami otrzymywanymi od systemu (w przypadku myszy) jest pozycja kursora, a pozycja jest poprawiana tak, aby znalaz\u0142 si\u0119 on w miejscu w kt\u00f3rym u\u017cytkownik si\u0119 tego spodziewa. Niestety dane otrzymywane w ten spos\u00f3b nie s\u0105 dok\u0142adne wi\u0119c w bardziej wymagaj\u0105cych grach mog\u0105 okaza\u0107 si\u0119 nieprzydatne.<br \/>\nDirectInput jest natomiast sposobem na uzyskanie dok\u0142adniejszych danych, jednak zasada jego dzia\u0142ania opiera si\u0119 na utworzeniu dodatkowego w\u0105tku, podpi\u0119cia si\u0119 do wskazanego okna i odczytywaniu danych bezpo\u015brednio ze sterownika, czyli surowych danych (RAW). Najprawdopodobniej jest to przyczyn\u0105 braku wsparcia dla tej metody, dodatkowo niekt\u00f3re antywirusy mog\u0105 ostrzega\u0107 \u017ce aplikacja kt\u00f3r\u0105 napisali\u015bmy jest keyloggerem.<\/p>\n<p>RAW Input umo\u017cliwia aplikacji uzyskanie surowych danych bezpo\u015brednio ze sterownika. Zasada dzia\u0142ania opiera si\u0119 tutaj, tak samo jak w pierwszej metodzie, na komunikatach procedury okna. R\u00f3\u017cnica polega na tym, \u017ce ch\u0119\u0107 otrzymywania tych danych nale\u017cy wcze\u015bniej w systemie zarejestrowa\u0107. Jest to p\u00f3ki co najlepsza metoda uzyskiwania dok\u0142adnych danych z myszy, poniewa\u017c dostarcza informacje na temat przesuni\u0119\u0107, a nie pozycji kursora. Otrzymywanie danych z klawiatury r\u00f3wnie\u017c jest mo\u017cliwe, ale w tym przypadku dok\u0142adno\u015b\u0107 nie ma sensu.<\/p>\n<p>Do rejestracji urz\u0105dze\u0144, kt\u00f3rych dane chcieliby\u015bmy otrzymywa\u0107 t\u0105 metod\u0105, s\u0142u\u017cy funkcja:<br \/>\n<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms645600%28VS.85%29.aspx\"> <\/a><\/p>\n<pre lang=\"cpp\"><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms645600%28VS.85%29.aspx\">BOOL WINAPI RegisterRawInputDevices(\r\n  __in  PCRAWINPUTDEVICE pRawInputDevices,\r\n  __in  UINT uiNumDevices,\r\n  __in  UINT cbSize\r\n);\r\n<\/a><\/pre>\n<p>Pierwszym parametrem tej funkcji jest tablica obiekt\u00f3w struktury <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms645565(v=VS.85).aspx\">RAWINPUTDEVICE<\/a>, kt\u00f3ra opisuje rejestrowane urz\u0105dzenie. Pozosta\u0142e parametry to ilo\u015b\u0107 urz\u0105dze\u0144 i rozmiar struktury, czyli <strong>sizeof(RAWINPUTDEVICE)<\/strong>.<\/p>\n<p>Poni\u017cszy przyk\u0142ad pokazuje rejestracj\u0119 myszy:<\/p>\n<pre lang=\"cpp\">RAWINPUTDEVICE rawStructure;\r\nrawStructure.usUsagePage = 1;                            \/\/ Typ urz\u0105dzenia (w tym przypadku GENERIC)\r\nrawStructure.hwndTarget = m_hWnd;                    \/\/ Uchwyt okna\r\nrawStructure.usUsage = 2;                                   \/\/ Rodzaj urz\u0105dzenia (2 - mysz)\r\nrawStructure.dwFlags = RIDEV_NOLEGACY;        \/\/ Wi\u0119cej info w opisie struktury\r\n\r\nif(!RegisterRawInputDevices(&amp;rawStructure, 1, sizeof(RAWINPUTDEVICE)))\r\n{\r\n    \/\/ Obs\u0142uga b\u0142\u0119du\r\n}\r\n<\/pre>\n<p>Warto\u015bci <strong>usUsage<\/strong> i <strong>usUsagePage<\/strong> mo\u017cna znale\u017a\u0107 w <a href=\"http:\/\/www.usb.org\/developers\/devclass_docs\/Hut1_12.pdf\"><strong>tym<\/strong><\/a> dokumencie.<\/p>\n<p>Je\u015bli rejestracja urz\u0105dzenia si\u0119 powiedzie, to aplikacja przestanie otrzymywa\u0107 standardowe komunikaty zwi\u0105zane z tym urz\u0105dzeniem, a zacznie otrzymywa\u0107 komunikaty WM_INPUT z danymi RAW tego urz\u0105dzenia.<br \/>\nDane mo\u017cna otrzymywa\u0107 na dwa sposoby: pojedynczo, bezpo\u015brednio w trakcie obs\u0142ugi komunikatu lub zbuforowane. Poni\u017cej podam przyk\u0142ad na standardow\u0105 obs\u0142ug\u0119 komunikatu WM_INPUT, wi\u0119cej info na temat tej i drugiej metody mo\u017cna znale\u017a\u0107 na <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms645546.aspx\"><strong>tej<\/strong><\/a> stronie.<\/p>\n<pre lang=\"cpp\">LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)\r\n{\r\n     switch(msg)\r\n     {\r\n     case WM_INPUT:\r\n          {\r\n               RAWINPUT riStruct;\r\n               DWORD dwSize = sizeof(RAWINPUT);\r\n\r\n               if(GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &amp;riStruct, &amp;dwSize, sizeof(RAWINPUTHEADER)) == (UINT)-1)\r\n               {\r\n                    \/\/ Obs\u0142uga b\u0142\u0119du\r\n               }\r\n\r\n               if(riStruct.header.dwType == RIM_TYPEMOUSE)\r\n               {\r\n                    riStruct.data.mouse.lLastX;     \/\/ Przesuniecie X\r\n                    riStruct.data.mouse.lLastY;     \/\/ Przesuniecie Y\r\n\r\n                    riStruct.data.mouse.ulButtons;     \/\/ Przyciski myszy\r\n\r\n                    riStruct.data.mouse.usButtonData;     \/\/ Rolka myszy\r\n               }\r\n          }\r\n          break;\r\n     }\r\n}\r\n<\/pre>\n<p>Dziwi\u0107 mo\u017ce to, \u017ce funkcja przyjmuje wska\u017anik na zmienn\u0105 do rozmiaru struktury RAWINPUT. Jest to spowodowane tym, \u017ce r\u00f3\u017cne urz\u0105dzenia maj\u0105 r\u00f3\u017cne struktury i podanie niew\u0142a\u015bciwego rozmiaru skutkuje b\u0142\u0119dem oraz wpisaniem wymaganego rozmiaru pod podanym adresem.<\/p>\n<p>Wyrejestrowanie urz\u0105dzenia nast\u0119puje po wywo\u0142aniu funkcji <strong>RegisterRawInputDevices<\/strong> podaj\u0105c jako w flag\u0119 w przekazywanej strukturze <strong>RIDEV_REMOVE<\/strong>.<\/p>\n<p>Og\u00f3lnie rzecz bior\u0105c RAW Input jest najlepszym sposobem na otrzymanie dok\u0142adnych danych z urz\u0105dze\u0144 wej\u015bciowych. Obs\u0142uga klawiatury jest troch\u0119 bardziej skomplikowana, a szczerze m\u00f3wi\u0105c nie widz\u0119 sensu korzystania z tego sposobu. Lepiej pozosta\u0107 przy komunikatach. Osobi\u015bcie uwa\u017cam, \u017ce odpytywanie o stan inputu jest lepsze ni\u017c odpowiadanie na komunikaty, poniewa\u017c aplikacja jest wtedy bardziej przewidywalna.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tym razem b\u0119dzie zn\u00f3w co\u015b zwi\u0105zanego z systemem Windows i programowaniem gier, czyli obs\u0142uga myszy za pomoc\u0105 RAW Input. Jest to jeden z trzech popularnych sposob\u00f3w obs\u0142ugi tych urz\u0105dze\u0144. Pozosta\u0142ymi s\u0105 komunikaty procedury okna oraz DirectInput, z tym \u017ce ten ostatni jest niezalecany i ju\u017c nie jest wspierany przez Microsoft na rzecz w\u0142a\u015bnie RAW Input. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[179,180,117],"_links":{"self":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts\/547"}],"collection":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/comments?post=547"}],"version-history":[{"count":30,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts\/547\/revisions"}],"predecessor-version":[{"id":780,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/posts\/547\/revisions\/780"}],"wp:attachment":[{"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/media?parent=547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/categories?post=547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/netrix.org.pl\/index.php\/wp-json\/wp\/v2\/tags?post=547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}