回答編集履歴

2

主目的はマウスだったのを取り違えていた

2023/08/13 01:32

投稿

KOZ6.0
KOZ6.0

スコア2644

test CHANGED
@@ -1,12 +1,12 @@
1
- Raw Input API を使うとハードウエアでキーを押されたか、ソフトウエアでキーが押されたかを判別できるようです。
1
+ Raw Input API を使うとハードウエアで操作されたか、ソフトウエアで操作されたかを判別できるようです。
2
2
 
3
3
  RegisterRawInputDevices API でウインドウを登録すると、WM_INPUT メッセージがウインドウに飛んでくるので GetRawInputData API で LPARAM から情報を取り出します。
4
4
 
5
5
  取り出した RAWINPUTHEADER 構造体の hDevice メンバにデバイスハンドルが入ってくるのですが、ソフトウエアから入力された場合は、ゼロになっています。
6
6
 
7
- Python はわからないので C# Windows Forms アプリケーションのコードを載せておきます。
7
+ Python はわからないので C# Windows Forms アプリケーションのコードを載せておきます。(キーボードとマウスボタンを検出)
8
-
8
+
9
- あくまでキーボードの状態が変更されたタイミング(リピートを含む)が分かるだけなので、現在押されているかどうかは、キーごとに状態を管理してください。
9
+ あくまで変更されたタイミングが分かるだけなので、現在押されているかどうかは、状態を管理してください。
10
10
 
11
11
  ```csharp
12
12
  using System;
@@ -120,11 +120,63 @@
120
120
  public int ExtraInformation;
121
121
  }
122
122
 
123
+ [Flags()]
124
+ private enum RawMouseButtons : short
125
+ {
126
+ None = 0,
127
+ LeftDown = 0x0001,
128
+ LeftUp = 0x0002,
129
+ RightDown = 0x0004,
130
+ RightUp = 0x0008,
131
+ MiddleDown = 0x0010,
132
+ MiddleUp = 0x0020,
133
+ Button4Down = 0x0040,
134
+ Button4Up = 0x0080,
135
+ Button5Down = 0x0100,
136
+ Button5Up = 0x0200,
137
+ MouseWheel = 0x0400
138
+ }
139
+
140
+ [Flags()]
141
+ public enum RawMouseFlags : short
142
+ {
143
+ MoveRelative = 0,
144
+ MoveAbsolute = 1,
145
+ VirtualDesktop = 2,
146
+ AttributesChanged = 4
147
+ }
148
+
149
+ [StructLayout(LayoutKind.Explicit)]
150
+ private struct RowMouseData
151
+ {
152
+ [FieldOffset(0)]
153
+ public int Buttons;
154
+ [FieldOffset(2)]
155
+ public short ButtonData;
156
+ [FieldOffset(0)]
157
+ public RawMouseButtons ButtonFlags;
158
+ }
159
+
123
160
  [StructLayout(LayoutKind.Sequential)]
161
+ private struct RAWMOUSE
162
+ {
163
+ public RawMouseFlags Flags;
164
+ public RowMouseData Data;
165
+ public int RawButtons;
166
+ public int LastX;
167
+ public int LastY;
168
+ public int ExtraInformation;
169
+ }
170
+
171
+ [StructLayout(LayoutKind.Explicit)]
124
172
  private struct RAWINPUT
125
173
  {
174
+ [FieldOffset(0)]
126
175
  public RAWINPUTHEADER Header;
176
+ [FieldOffset(16)]
127
177
  public RAWKEYBOARD Keyboard;
178
+ [FieldOffset(16)]
179
+ public RAWMOUSE Mouse;
128
180
  }
129
181
 
130
182
  [DllImport("user32.dll")]
@@ -150,11 +202,18 @@
150
202
  protected override void OnHandleCreated(EventArgs e)
151
203
  {
152
204
  base.OnHandleCreated(e);
205
+
153
- RAWINPUTDEVICE[] rawInputDevices = new RAWINPUTDEVICE[1];
206
+ RAWINPUTDEVICE[] rawInputDevices = new RAWINPUTDEVICE[2];
207
+
154
208
  rawInputDevices[0].usUsagePage = HIDUsagePage.Generic;
155
209
  rawInputDevices[0].usUsage = HIDUsage.Keyboard;
156
- rawInputDevices[0].dwFlags = RawInputDeviceFlags.InputSink | RawInputDeviceFlags.NoLegacy;
210
+ rawInputDevices[0].dwFlags = RawInputDeviceFlags.InputSink;
157
211
  rawInputDevices[0].hwndTarget = Handle;
212
+
213
+ rawInputDevices[1].usUsagePage = HIDUsagePage.Generic;
214
+ rawInputDevices[1].usUsage = HIDUsage.Mouse;
215
+ rawInputDevices[1].dwFlags = RawInputDeviceFlags.InputSink;
216
+ rawInputDevices[1].hwndTarget = Handle;
158
217
 
159
218
  var result = RegisterRawInputDevices(rawInputDevices,
160
219
  rawInputDevices.Length,
@@ -179,24 +238,52 @@
179
238
  if (GetRawInputData(m.LParam, RawInputCommand.Input, buffer, ref dwSize,
180
239
  Marshal.SizeOf(typeof(RAWINPUTHEADER))) == dwSize)
181
240
  {
182
- RAWINPUTHEADER header = Marshal.PtrToStructure<RAWINPUTHEADER>(buffer);
241
+ RAWINPUT raw = Marshal.PtrToStructure<RAWINPUT>(buffer);
183
- if (header.dwType == RawInputType.Keyboard)
242
+ if (raw.Header.hDevice == IntPtr.Zero)
184
243
  {
244
+ Debug.WriteLine("ソフトウエアだよ!");
245
+ }
246
+ else
247
+ {
185
- if (header.hDevice == IntPtr.Zero)
248
+ switch (raw.Header.dwType)
186
249
  {
250
+ case RawInputType.Keyboard:
251
+ if (raw.Keyboard.Flags.HasFlag(RawKeyboardFlags.Break))
252
+ {
187
- Debug.WriteLine("ソフトウエアだよ!");
253
+ Debug.WriteLine($"キーが離されました: {(Keys)raw.Keyboard.VKey}");
188
- }
254
+ }
189
- else
255
+ else
190
- {
256
+ {
191
- RAWINPUT raw = Marshal.PtrToStructure<RAWINPUT>(buffer);
257
+ Debug.WriteLine($"キーが押されました: {(Keys)raw.Keyboard.VKey}");
258
+ }
259
+ break;
260
+
261
+ case RawInputType.Mouse:
192
- if (raw.Keyboard.Flags.HasFlag(RawKeyboardFlags.Break))
262
+ if (raw.Mouse.Data.ButtonFlags.HasFlag(RawMouseButtons.LeftDown))
193
- {
263
+ {
194
- Debug.WriteLine($"キーされました: {(Keys)raw.Keyboard.VKey}");
264
+ Debug.WriteLine($"左ボタンされました");
195
- }
265
+ }
196
- else
266
+ if (raw.Mouse.Data.ButtonFlags.HasFlag(RawMouseButtons.LeftUp))
197
- {
267
+ {
198
- Debug.WriteLine($"キーされました: {(Keys)raw.Keyboard.VKey}");
268
+ Debug.WriteLine($"左ボタンされました");
199
- }
269
+ }
270
+ if (raw.Mouse.Data.ButtonFlags.HasFlag(RawMouseButtons.RightDown))
271
+ {
272
+ Debug.WriteLine($"右ボタンが押されました");
273
+ }
274
+ if (raw.Mouse.Data.ButtonFlags.HasFlag(RawMouseButtons.RightUp))
275
+ {
276
+ Debug.WriteLine($"右ボタンが離されました");
277
+ }
278
+ if (raw.Mouse.Data.ButtonFlags.HasFlag(RawMouseButtons.MiddleDown))
279
+ {
280
+ Debug.WriteLine($"中ボタンが押されました");
281
+ }
282
+ if (raw.Mouse.Data.ButtonFlags.HasFlag(RawMouseButtons.MiddleUp))
283
+ {
284
+ Debug.WriteLine($"中ボタンが離されました");
285
+ }
286
+ break;
200
287
  }
201
288
  }
202
289
  }
@@ -211,5 +298,3 @@
211
298
  }
212
299
  ```
213
300
 
214
-
215
-

1

RawKeyboardFlags の判定が誤っていた

2023/08/13 00:02

投稿

KOZ6.0
KOZ6.0

スコア2644

test CHANGED
@@ -17,47 +17,107 @@
17
17
 
18
18
  public partial class Form1 : Form
19
19
  {
20
- private const int RID_INPUT = 0x10000003;
21
- private const int RIM_TYPEKEYBOARD = 1;
22
- private const int RIDEV_INPUTSINK = 0x00000100;
23
- private const int RIDEV_NOLEGACY = 0x00000030;
24
20
  private const int WM_INPUT = 0x00FF;
25
21
 
22
+ private enum HIDUsagePage : short
23
+ {
24
+ Undefined = 0x00,
25
+ Generic = 0x01,
26
+ Simulation = 0x02,
27
+ VR = 0x03,
28
+ Sport = 0x04,
29
+ Game = 0x05,
30
+ Keyboard = 0x07,
31
+ LED = 0x08,
32
+ Button = 0x09,
33
+ Ordinal = 0x0A,
34
+ Telephony = 0x0B,
35
+ Consumer = 0x0C,
36
+ Digitizer = 0x0D,
37
+ PID = 0x0F,
38
+ Unicode = 0x10,
39
+ AlphaNumeric = 0x14,
40
+ Medical = 0x40,
41
+ MonitorPage0 = 0x80,
42
+ MonitorPage1 = 0x81,
43
+ MonitorPage2 = 0x82,
44
+ MonitorPage3 = 0x83,
45
+ PowerPage0 = 0x84,
46
+ PowerPage1 = 0x85,
47
+ PowerPage2 = 0x86,
48
+ PowerPage3 = 0x87,
49
+ BarCode = 0x8C,
50
+ Scale = 0x8D,
51
+ MSR = 0x8E
52
+ }
53
+
54
+ private enum HIDUsage : short
55
+ {
56
+ Pointer = 0x01,
57
+ Mouse = 0x02,
58
+ Joystick = 0x04,
59
+ Gamepad = 0x05,
60
+ Keyboard = 0x06,
61
+ Keypad = 0x07,
62
+ }
63
+
64
+ [Flags()]
65
+ public enum RawInputDeviceFlags
66
+ {
67
+ None = 0,
68
+ Remove = 0x00000001,
69
+ Exclude = 0x00000010,
70
+ PageOnly = 0x00000020,
71
+ NoLegacy = 0x00000030,
72
+ InputSink = 0x00000100,
73
+ CaptureMouse = 0x00000200,
74
+ NoHotKeys = 0x00000200,
75
+ AppKeys = 0x00000400
76
+ }
77
+
26
78
  [StructLayout(LayoutKind.Sequential)]
27
79
  private struct RAWINPUTDEVICE
28
80
  {
29
- public ushort usUsagePage;
81
+ public HIDUsagePage usUsagePage;
30
- public ushort usUsage;
82
+ public HIDUsage usUsage;
31
- public int dwFlags;
83
+ public RawInputDeviceFlags dwFlags;
32
84
  public IntPtr hwndTarget;
33
85
  }
34
86
 
87
+ private enum RawInputType
88
+ {
89
+ Mouse = 0,
90
+ Keyboard = 1,
91
+ Hid = 2
92
+ }
93
+
35
94
  [StructLayout(LayoutKind.Sequential)]
36
95
  private struct RAWINPUTHEADER
37
96
  {
38
- public uint dwType;
97
+ public RawInputType dwType;
39
- public uint dwSize;
98
+ public int dwSize;
40
99
  public IntPtr hDevice;
41
100
  public IntPtr wParam;
42
101
  }
43
102
 
103
+ [Flags]
44
- private enum RawKeyboardFlahs : ushort
104
+ private enum RawKeyboardFlags : short
45
- {
105
+ {
46
- RI_KEY_MAKE = 0,
106
+ Make = 0,
47
- RI_KEY_BREAK = 1,
107
+ Break = 1,
48
- RI_KEY_E0 = 2,
108
+ E0 = 2,
49
- RI_KEY_E1 = 4,
109
+ E1 = 4,
50
110
  }
51
111
 
52
112
  [StructLayout(LayoutKind.Sequential)]
53
113
  private struct RAWKEYBOARD
54
114
  {
55
- public ushort MakeCode;
115
+ public short MakeCode;
56
- public RawKeyboardFlahs Flags;
116
+ public RawKeyboardFlags Flags;
57
- public ushort Reserved;
117
+ public short Reserved;
58
- public ushort VKey;
118
+ public short VKey;
59
- public uint Message;
119
+ public int Message;
60
- public uint ExtraInformation;
120
+ public int ExtraInformation;
61
121
  }
62
122
 
63
123
  [StructLayout(LayoutKind.Sequential)]
@@ -69,12 +129,18 @@
69
129
 
70
130
  [DllImport("user32.dll")]
71
131
  private static extern bool RegisterRawInputDevices(
72
- RAWINPUTDEVICE[] pRawInputDevices, uint uiNumDevices, uint cbSize);
132
+ RAWINPUTDEVICE[] pRawInputDevices, int uiNumDevices, int cbSize);
133
+
134
+ private enum RawInputCommand
135
+ {
136
+ Header = 0x10000005,
137
+ Input = 0x10000003,
138
+ }
73
139
 
74
140
  [DllImport("user32.dll")]
75
- private static extern uint GetRawInputData(
141
+ private static extern int GetRawInputData(
76
- IntPtr hRawInput, uint uiCommand, IntPtr pData,
142
+ IntPtr hRawInput, RawInputCommand uiCommand, IntPtr pData,
77
- ref uint pcbSize, uint cbSizeHeader);
143
+ ref int pcbSize, int cbSizeHeader);
78
144
 
79
145
  public Form1()
80
146
  {
@@ -85,14 +151,14 @@
85
151
  {
86
152
  base.OnHandleCreated(e);
87
153
  RAWINPUTDEVICE[] rawInputDevices = new RAWINPUTDEVICE[1];
88
- rawInputDevices[0].usUsagePage = 0x01; // Generic desktop controls
154
+ rawInputDevices[0].usUsagePage = HIDUsagePage.Generic;
89
- rawInputDevices[0].usUsage = 0x06; // Keyboard
155
+ rawInputDevices[0].usUsage = HIDUsage.Keyboard;
90
- rawInputDevices[0].dwFlags = RIDEV_INPUTSINK | RIDEV_NOLEGACY;
156
+ rawInputDevices[0].dwFlags = RawInputDeviceFlags.InputSink | RawInputDeviceFlags.NoLegacy;
91
157
  rawInputDevices[0].hwndTarget = Handle;
92
158
 
93
159
  var result = RegisterRawInputDevices(rawInputDevices,
94
- (uint)rawInputDevices.Length,
160
+ rawInputDevices.Length,
95
- (uint)Marshal.SizeOf(typeof(RAWINPUTDEVICE)));
161
+ Marshal.SizeOf(typeof(RAWINPUTDEVICE)));
96
162
  if (!result)
97
163
  {
98
164
  throw new Win32Exception();
@@ -103,33 +169,33 @@
103
169
  {
104
170
  if (m.Msg == WM_INPUT)
105
171
  {
106
- uint dwSize = 0;
172
+ int dwSize = 0;
107
- GetRawInputData(m.LParam, RID_INPUT, IntPtr.Zero, ref dwSize,
173
+ GetRawInputData(m.LParam, RawInputCommand.Input, IntPtr.Zero, ref dwSize,
108
- (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER)));
174
+ Marshal.SizeOf(typeof(RAWINPUTHEADER)));
109
-
175
+
110
- IntPtr buffer = Marshal.AllocHGlobal((int)dwSize);
176
+ IntPtr buffer = Marshal.AllocHGlobal(dwSize);
111
177
  try
112
178
  {
113
- if (GetRawInputData(m.LParam, RID_INPUT, buffer, ref dwSize,
179
+ if (GetRawInputData(m.LParam, RawInputCommand.Input, buffer, ref dwSize,
114
- (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) == dwSize)
180
+ Marshal.SizeOf(typeof(RAWINPUTHEADER))) == dwSize)
115
181
  {
116
- RAWINPUT raw = Marshal.PtrToStructure<RAWINPUT>(buffer);
182
+ RAWINPUTHEADER header = Marshal.PtrToStructure<RAWINPUTHEADER>(buffer);
117
- if (raw.Header.dwType == RIM_TYPEKEYBOARD)
183
+ if (header.dwType == RawInputType.Keyboard)
118
184
  {
119
- if (raw.Header.hDevice == IntPtr.Zero)
185
+ if (header.hDevice == IntPtr.Zero)
120
186
  {
121
187
  Debug.WriteLine("ソフトウエアだよ!");
122
188
  }
123
189
  else
124
190
  {
191
+ RAWINPUT raw = Marshal.PtrToStructure<RAWINPUT>(buffer);
125
- switch(raw.Keyboard.Flags)
192
+ if (raw.Keyboard.Flags.HasFlag(RawKeyboardFlags.Break))
126
193
  {
127
- case RawKeyboardFlahs.RI_KEY_MAKE:
194
+ Debug.WriteLine($"キーが離されました: {(Keys)raw.Keyboard.VKey}");
195
+ }
196
+ else
197
+ {
128
- Debug.WriteLine($"キーが押されました: {(Keys)raw.Keyboard.VKey}");
198
+ Debug.WriteLine($"キーが押されました: {(Keys)raw.Keyboard.VKey}");
129
- break;
130
- case RawKeyboardFlahs.RI_KEY_BREAK:
131
- Debug.WriteLine($"キーが離されました: {(Keys)raw.Keyboard.VKey}");
132
- break;
133
199
  }
134
200
  }
135
201
  }
@@ -145,3 +211,5 @@
145
211
  }
146
212
  ```
147
213
 
214
+
215
+