質問編集履歴

7

問題点が分かったので、そこに焦点を当てました

2019/11/19 17:07

投稿

Tatsuk
Tatsuk

スコア11

test CHANGED
@@ -1 +1 @@
1
- DirectInput コンソールでフィードバック機能付きジョイスティック情報取得したい
1
+ DirectInput コンソールアプリSetCooperativeLevel排他制御設定行いたい
test CHANGED
@@ -2,13 +2,11 @@
2
2
 
3
3
  環境:64bit版windows10,VC++2019,DirectX SDK(June 2010)を利用
4
4
 
5
+ コンソールアプリ上でフォースフィードバックを利用したいため、コンソールアプリでの排他制御セット
6
+
5
- 最終的にDirectInputでコマンドプロント上にジョイスティックのデータを表示しながら、ボタンを押すことでフォースフィードバックを行うプログラムを作ることを目標に設定。
7
+ g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_BACKGROUND)
6
-
7
- まずDirectInputの練習もかねて、1秒ごとにコマンドプロント上にジョイスティックから情報を取得できていれば
8
+
8
-
9
- 「取得成功」
10
-
11
- 表示するプログラムを作成したいです。
9
+ 行いたいです。
12
10
 
13
11
  ### 発生している問題・エラーメッセージ
14
12
 
@@ -16,15 +14,13 @@
16
14
 
17
15
  ```
18
16
 
17
+ 下記のコードからDISCL_EXCLUSIVEの部分をDISCL_NONEXCLUSIVEとするか、排他制御設定自体を削除すると問題なくフォースフィードバック機能の有り無しに関わらず動作します。しかし、排他制御設定を行うと
18
+
19
19
  ”Acquireに失敗”
20
20
 
21
- と表示され、入力の開始が実行できない状態です。
21
+ と表示され、入力の開始が実行できない状態です。実際数値的にも取得できませんでした。
22
-
23
- モードの設定
22
+
24
-
25
- (hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)
26
-
27
- のEXCLUSIVENONWXCLUSIVE変更するこでジョイスティックの情報取得可能ですが、最終的にフォースフィードバックを行いたいので、どうにかし排他設定にしたいです。
23
+ コンソールアプリで排他制御行う方法を知っていればお手数とは思いますが教え頂けると幸いです。
28
24
 
29
25
  ```
30
26
 
@@ -64,7 +60,7 @@
64
60
 
65
61
 
66
62
 
67
- #define SAFE_RELEASE(x) {if(x){(x)->Release();x=NULL;}}
63
+ #define SAFE_RELEASE(x) {if(x){(x)->Release();x=NULL;}}
68
64
 
69
65
 
70
66
 
@@ -88,13 +84,13 @@
88
84
 
89
85
  LPDIRECTINPUT8 g_pDInput = NULL;
90
86
 
91
- LPDIRECTINPUTDEVICE8 g_pDIDevice = NULL; // DirectInputデバイス
87
+ LPDIRECTINPUTDEVICE8 g_pDIDevice = NULL; // DirectInputデバイス
92
-
88
+
93
- LPDIRECTINPUTEFFECT g_pDIEffect = NULL; // エフェクト
89
+ LPDIRECTINPUTEFFECT g_pDIEffect = NULL; // エフェクト
94
-
90
+
95
- DIDEVCAPS g_diDevCaps; // ジョイスティックの能力
91
+ DIDEVCAPS g_diDevCaps; // ジョイスティックの能力
96
-
92
+
97
- #define DIDEVICE_BUFFERSIZE 1000 // デバイスに設定するバッファ・サイズ
93
+ #define DIDEVICE_BUFFERSIZE 1000 // デバイスに設定するバッファ・サイズ
98
94
 
99
95
 
100
96
 
@@ -112,7 +108,7 @@
112
108
 
113
109
  DIJOYSTATE2 dijs; //この構造体にデータを取得する
114
110
 
115
- HINSTANCE hInstApp = GetModuleHandle(NULL); //インスタンス・ハンドル
111
+ HINSTANCE hInstApp = GetModuleHandle(NULL); //インスタンス・ハンドル
116
112
 
117
113
  HWND hWlg = GetConsoleWindow(); //ウインドウハンドル
118
114
 
@@ -140,7 +136,7 @@
140
136
 
141
137
  // ジョイスティックの列挙
142
138
 
143
- hr = g_pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_FORCEFEEDBACK | DIEDFL_ATTACHEDONLY);
139
+ hr = g_pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL,DIEDFL_ATTACHEDONLY);
144
140
 
145
141
  if (FAILED(hr) || g_pDIDevice == NULL) {
146
142
 
@@ -156,7 +152,7 @@
156
152
 
157
153
  // データ形式を設定
158
154
 
159
- hr=g_pDIDevice->SetDataFormat(&c_dfDIJoystick2);
155
+ hr = g_pDIDevice->SetDataFormat(&c_dfDIJoystick2);
160
156
 
161
157
  if (FAILED(hr)) {
162
158
 
@@ -172,7 +168,7 @@
172
168
 
173
169
  //モードを設定(フォアグラウンド&排他モード)
174
170
 
175
- hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
171
+ hr = g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
176
172
 
177
173
  if (FAILED(hr))
178
174
 
@@ -186,33 +182,7 @@
186
182
 
187
183
  }
188
184
 
189
- // 自動センタリングを無効にする
185
+
190
-
191
- DIPROPDWORD DIPropAutoCenter;
192
-
193
- DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter);
194
-
195
- DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
196
-
197
- DIPropAutoCenter.diph.dwObj = 0;
198
-
199
- DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
200
-
201
- DIPropAutoCenter.dwData = DIPROPAUTOCENTER_OFF;
202
-
203
- hr = g_pDIDevice->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
204
-
205
- if (FAILED(hr))
206
-
207
- {
208
-
209
- printf("自動センタリングの設定に失敗\n");
210
-
211
- g_pDIDevice->Release();
212
-
213
- return -1;
214
-
215
- }
216
186
 
217
187
  //コールバック関数を使って各軸のモードを設定
218
188
 
@@ -224,7 +194,7 @@
224
194
 
225
195
  printf("軸モードの設定に失敗\n");
226
196
 
227
- g_pDIDevice->Release();
197
+ g_pDIDevice->Release();
228
198
 
229
199
  return -1;
230
200
 
@@ -252,7 +222,7 @@
252
222
 
253
223
  printf("軸モードの設定に失敗\n");
254
224
 
255
- g_pDIDevice->Release();
225
+ g_pDIDevice->Release();
256
226
 
257
227
  return -1;
258
228
 
@@ -270,7 +240,7 @@
270
240
 
271
241
  printf("バッファ・サイズの設定に失敗\n");
272
242
 
273
- g_pDIDevice->Release();
243
+ g_pDIDevice->Release();
274
244
 
275
245
  return -1;
276
246
 
@@ -290,7 +260,7 @@
290
260
 
291
261
  printf("Acquireに失敗\n");
292
262
 
293
- g_pDIDevice->Release();
263
+ g_pDIDevice->Release();
294
264
 
295
265
  return -1;
296
266
 
@@ -306,9 +276,9 @@
306
276
 
307
277
  printf("pollに失敗\n");
308
278
 
309
- g_pDIDevice->Release();
279
+ g_pDIDevice->Release();
310
-
280
+
311
-          return -1;
281
+ return -1;
312
282
 
313
283
 
314
284
 
@@ -318,23 +288,29 @@
318
288
 
319
289
  int i;
320
290
 
321
-
291
+
322
292
 
323
293
  for (i = 0; i <= 10; i++)
324
294
 
325
295
  {
326
296
 
327
-
297
+
328
298
 
329
299
  hr = g_pDIDevice->GetDeviceState(sizeof(DIJOYSTATE2), &dijs);
330
300
 
331
- if (SUCCEEDED(hr))
301
+ if (SUCCEEDED(hr))
332
302
 
333
303
  {
334
304
 
305
+ printf("[X=%d Y=%d Z=%d][Rx=%d Ry=%d Rz=%d][Slider1=%d Slider2=%d]\n",
306
+
335
- printf("取得成功!");
307
+ dijs.lX, dijs.lY, dijs.lZ,
308
+
336
-
309
+ dijs.lRx, dijs.lRy, dijs.lRz,
310
+
337
-
311
+ dijs.rglSlider[0], dijs.rglSlider[1]);
312
+
313
+
338
314
 
339
315
  }
340
316
 
@@ -346,7 +322,7 @@
346
322
 
347
323
  g_pDIDevice->Acquire();
348
324
 
349
- g_pDIDevice->Poll();
325
+ g_pDIDevice->Poll();
350
326
 
351
327
  g_pDIDevice->GetDeviceState(sizeof(DIJOYSTATE2), &dijs);
352
328
 
@@ -354,9 +330,9 @@
354
330
 
355
331
  }
356
332
 
357
-
358
-
333
+
334
+
359
- Sleep(1000);
335
+ Sleep(1000);
360
336
 
361
337
  }
362
338
 
@@ -472,10 +448,6 @@
472
448
 
473
449
  ###試したこと
474
450
 
475
- モードの設定(hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)を除くことで成功しました。
476
-
477
- しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
478
-
479
451
  原因は
480
452
 
481
453
  HRESULT IDirectInputDevice8::SetCooperativeLevel(
@@ -496,7 +468,7 @@
496
468
 
497
469
  HWND hWlg = (HWND)cvGetWindowHandle(windowName);
498
470
 
499
- も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。
471
+ も試してみましたが、こちらも入力制御ができませんでした。
500
472
 
501
473
  ### 補足情報(FW/ツールのバージョンなど)
502
474
 
@@ -508,6 +480,8 @@
508
480
 
509
481
  のサンプルプログラム4
510
482
 
511
- 利用したジョイスティック
483
+ 利用したジョイスティック・ゲームパッド
512
484
 
513
485
  Cyborg Evo Force Joystick(フォースフィードバック機能あり)
486
+
487
+ BSGP1204BK(フォースフィードバック機能なし)

6

回答来ないので全体的に変更

2019/11/19 17:07

投稿

Tatsuk
Tatsuk

スコア11

test CHANGED
@@ -1 +1 @@
1
- DirectInput 入力開始(Acquire())が失敗てしまう。
1
+ DirectInput コンソールでフィードバック機能付きジョイスティックの情報を取得たい
test CHANGED
@@ -18,7 +18,13 @@
18
18
 
19
19
  ”Acquireに失敗”
20
20
 
21
+ と表示され、入力の開始が実行できない状態です。
22
+
23
+ モードの設定
24
+
25
+ (hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)
26
+
21
- 表示され、入力の開始が実行きない状態です。ンターフェイスの取得・デバイスの作成および設定成功するの、入力の開始が実できな理由を探し当てることが出来なかっこちらで質問させ頂きました。
27
+ のEXCLUSIVEをNONWXCLUSIVE変更することでジョイスティック情報は取得可能です、最終的フォースフィードバックを行いたいのでどうにかし排他設定にしたいです
22
28
 
23
29
  ```
24
30
 
@@ -470,9 +476,7 @@
470
476
 
471
477
  しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
472
478
 
473
- 追記
479
+ 原因は
474
-
475
- 間違っていたら申し訳ありませんが原因は
476
480
 
477
481
  HRESULT IDirectInputDevice8::SetCooperativeLevel(
478
482
 
@@ -484,8 +488,6 @@
484
488
 
485
489
  の最初の引数として必要なHWNDの部分に対応可能なハンドルをGetConsoleWindow()では取得できないせいではないかと考えています。
486
490
 
487
- 追記
488
-
489
491
  HWND hWlg = GetForegroundWindow();
490
492
 
491
493
  HWND hWlg = GetDesktopWindow();
@@ -494,7 +496,7 @@
494
496
 
495
497
  HWND hWlg = (HWND)cvGetWindowHandle(windowName);
496
498
 
497
- も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。。。
499
+ も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。
498
500
 
499
501
  ### 補足情報(FW/ツールのバージョンなど)
500
502
 

5

誤字

2019/11/18 13:45

投稿

Tatsuk
Tatsuk

スコア11

test CHANGED
File without changes
test CHANGED
@@ -474,7 +474,7 @@
474
474
 
475
475
  間違っていたら申し訳ありませんが原因は
476
476
 
477
- HRESULT IDrectInputDevice8::SetcooperativeLevel(
477
+ HRESULT IDirectInputDevice8::SetCooperativeLevel(
478
478
 
479
479
  HWND hwnd
480
480
 

4

追記

2019/11/18 12:51

投稿

Tatsuk
Tatsuk

スコア11

test CHANGED
File without changes
test CHANGED
@@ -490,6 +490,10 @@
490
490
 
491
491
  HWND hWlg = GetDesktopWindow();
492
492
 
493
+ また今回opencvと組み合わせるので
494
+
495
+ HWND hWlg = (HWND)cvGetWindowHandle(windowName);
496
+
493
497
  も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。。。
494
498
 
495
499
  ### 補足情報(FW/ツールのバージョンなど)

3

追記

2019/11/18 12:33

投稿

Tatsuk
Tatsuk

スコア11

test CHANGED
File without changes
test CHANGED
@@ -484,11 +484,13 @@
484
484
 
485
485
  の最初の引数として必要なHWNDの部分に対応可能なハンドルをGetConsoleWindow()では取得できないせいではないかと考えています。
486
486
 
487
-
487
+ 追記
488
+
488
-
489
+ HWND hWlg = GetForegroundWindow();
490
+
489
-
491
+ HWND hWlg = GetDesktopWindow();
492
+
490
-
493
+ も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。。。
491
-
492
494
 
493
495
  ### 補足情報(FW/ツールのバージョンなど)
494
496
 

2

問題の進展

2019/11/18 11:50

投稿

Tatsuk
Tatsuk

スコア11

test CHANGED
File without changes
test CHANGED
@@ -470,6 +470,20 @@
470
470
 
471
471
  しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
472
472
 
473
+ 追記
474
+
475
+ 間違っていたら申し訳ありませんが原因は
476
+
477
+ HRESULT IDrectInputDevice8::SetcooperativeLevel(
478
+
479
+ HWND hwnd
480
+
481
+ DWORD dwFlags
482
+
483
+ );
484
+
485
+ の最初の引数として必要なHWNDの部分に対応可能なハンドルをGetConsoleWindow()では取得できないせいではないかと考えています。
486
+
473
487
 
474
488
 
475
489
 

1

問題が進展した

2019/11/18 11:03

投稿

Tatsuk
Tatsuk

スコア11

test CHANGED
File without changes
test CHANGED
@@ -464,6 +464,12 @@
464
464
 
465
465
 
466
466
 
467
+ ###試したこと
468
+
469
+ モードの設定(hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)を除くことで成功しました。
470
+
471
+ しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
472
+
467
473
 
468
474
 
469
475