teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

7

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

2019/11/19 17:07

投稿

Tatsuk
Tatsuk

スコア11

title CHANGED
@@ -1,1 +1,1 @@
1
- DirectInput コンソールでフィードバック機能付きジョイスティック情報取得したい
1
+ DirectInput コンソールアプリSetCooperativeLevel排他制御設定行いたい
body CHANGED
@@ -1,17 +1,15 @@
1
1
  ### 前提・実現したいこと
2
2
  環境:64bit版windows10,VC++2019,DirectX SDK(June 2010)を利用
3
+ コンソールアプリ上でフォースフィードバックを利用したいため、コンソールアプリでの排他制御セット
3
- 最終的にDirectInputでコマンドプロント上にジョイスティックのデータを表示しながら、ボタンを押すことでフォースフィードバックを行うプログラムを作ることを目標に設定。
4
+ g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_BACKGROUND)
4
- まずDirectInputの練習もかねて、1秒ごとにコマンドプロント上にジョイスティックから情報を取得できていれば
5
- 「取得成功」
6
- 表示するプログラムを作成したいです。
5
+ 行いたいです。
7
6
  ### 発生している問題・エラーメッセージ
8
7
 
9
8
  ```
9
+ 下記のコードからDISCL_EXCLUSIVEの部分をDISCL_NONEXCLUSIVEとするか、排他制御設定自体を削除すると問題なくフォースフィードバック機能の有り無しに関わらず動作します。しかし、排他制御設定を行うと
10
10
  ”Acquireに失敗”
11
- と表示され、入力の開始が実行できない状態です。
11
+ と表示され、入力の開始が実行できない状態です。実際数値的にも取得できませんでした。
12
- モードの設定
13
- (hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)
14
- のEXCLUSIVEをNONWXCLUSIVE変更することでジョイスティックの情報は取得可能ですが、最終的にフォスフィードバックを行いので、どうにかし排他設定にしたいです。
12
+ コンソルアプリで排他制御を行う方法を知ってればお手数とは思ますが教え頂けると幸いです。
15
13
  ```
16
14
 
17
15
  ```c++
@@ -31,7 +29,7 @@
31
29
  #include <dxerr.h>
32
30
 
33
31
 
34
- #define SAFE_RELEASE(x) {if(x){(x)->Release();x=NULL;}}
32
+ #define SAFE_RELEASE(x) {if(x){(x)->Release();x=NULL;}}
35
33
 
36
34
  // 必要なライブラリをリンクする
37
35
  #pragma comment( lib, "dinput8.lib" )
@@ -43,10 +41,10 @@
43
41
 
44
42
  // DirectInputの変数
45
43
  LPDIRECTINPUT8 g_pDInput = NULL;
46
- LPDIRECTINPUTDEVICE8 g_pDIDevice = NULL; // DirectInputデバイス
44
+ LPDIRECTINPUTDEVICE8 g_pDIDevice = NULL; // DirectInputデバイス
47
- LPDIRECTINPUTEFFECT g_pDIEffect = NULL; // エフェクト
45
+ LPDIRECTINPUTEFFECT g_pDIEffect = NULL; // エフェクト
48
- DIDEVCAPS g_diDevCaps; // ジョイスティックの能力
46
+ DIDEVCAPS g_diDevCaps; // ジョイスティックの能力
49
- #define DIDEVICE_BUFFERSIZE 1000 // デバイスに設定するバッファ・サイズ
47
+ #define DIDEVICE_BUFFERSIZE 1000 // デバイスに設定するバッファ・サイズ
50
48
 
51
49
 
52
50
  BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext);
@@ -55,7 +53,7 @@
55
53
  int main()
56
54
  {
57
55
  DIJOYSTATE2 dijs; //この構造体にデータを取得する
58
- HINSTANCE hInstApp = GetModuleHandle(NULL); //インスタンス・ハンドル
56
+ HINSTANCE hInstApp = GetModuleHandle(NULL); //インスタンス・ハンドル
59
57
  HWND hWlg = GetConsoleWindow(); //ウインドウハンドル
60
58
  HRESULT hr;
61
59
 
@@ -69,7 +67,7 @@
69
67
  }
70
68
 
71
69
  // ジョイスティックの列挙
72
- hr = g_pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_FORCEFEEDBACK | DIEDFL_ATTACHEDONLY);
70
+ hr = g_pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL,DIEDFL_ATTACHEDONLY);
73
71
  if (FAILED(hr) || g_pDIDevice == NULL) {
74
72
  printf("デバイスオブジェクト作成に失敗\n");
75
73
  g_pDInput->Release();
@@ -77,7 +75,7 @@
77
75
  }
78
76
 
79
77
  // データ形式を設定
80
- hr=g_pDIDevice->SetDataFormat(&c_dfDIJoystick2);
78
+ hr = g_pDIDevice->SetDataFormat(&c_dfDIJoystick2);
81
79
  if (FAILED(hr)) {
82
80
  printf("入力データ形式のセット失敗\n");
83
81
  g_pDIDevice->Release();
@@ -85,33 +83,20 @@
85
83
  }
86
84
 
87
85
  //モードを設定(フォアグラウンド&排他モード)
88
- hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
86
+ hr = g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
89
87
  if (FAILED(hr))
90
88
  {
91
89
  printf("排他制御のセット失敗\n");
92
90
  g_pDIDevice->Release();
93
91
  return -1;
94
92
  }
95
- // 自動センタリングを無効にする
93
+
96
- DIPROPDWORD DIPropAutoCenter;
97
- DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter);
98
- DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
99
- DIPropAutoCenter.diph.dwObj = 0;
100
- DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
101
- DIPropAutoCenter.dwData = DIPROPAUTOCENTER_OFF;
102
- hr = g_pDIDevice->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
103
- if (FAILED(hr))
104
- {
105
- printf("自動センタリングの設定に失敗\n");
106
- g_pDIDevice->Release();
107
- return -1;
108
- }
109
94
  //コールバック関数を使って各軸のモードを設定
110
95
  hr = g_pDIDevice->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS);
111
96
  if (FAILED(hr))
112
97
  {
113
98
  printf("軸モードの設定に失敗\n");
114
- g_pDIDevice->Release();
99
+ g_pDIDevice->Release();
115
100
  return -1;
116
101
  }
117
102
  // 軸モードを設定(絶対値モードに設定。デフォルトなので必ずしも設定は必要ない)
@@ -125,7 +110,7 @@
125
110
  if (FAILED(hr))
126
111
  {
127
112
  printf("軸モードの設定に失敗\n");
128
- g_pDIDevice->Release();
113
+ g_pDIDevice->Release();
129
114
  return -1;
130
115
  }
131
116
  // バッファリング・データを取得するため、バッファ・サイズを設定
@@ -134,7 +119,7 @@
134
119
  if (FAILED(hr))
135
120
  {
136
121
  printf("バッファ・サイズの設定に失敗\n");
137
- g_pDIDevice->Release();
122
+ g_pDIDevice->Release();
138
123
  return -1;
139
124
  }
140
125
 
@@ -144,7 +129,7 @@
144
129
  if (FAILED(hr))
145
130
  {
146
131
  printf("Acquireに失敗\n");
147
- g_pDIDevice->Release();
132
+ g_pDIDevice->Release();
148
133
  return -1;
149
134
  }
150
135
  // ポーリング
@@ -152,32 +137,35 @@
152
137
  if (FAILED(hr))
153
138
  {
154
139
  printf("pollに失敗\n");
155
- g_pDIDevice->Release();
140
+ g_pDIDevice->Release();
156
-          return -1;
141
+ return -1;
157
142
 
158
143
  }
159
144
 
160
145
  int i;
161
-
146
+
162
147
  for (i = 0; i <= 10; i++)
163
148
  {
164
-
149
+
165
150
  hr = g_pDIDevice->GetDeviceState(sizeof(DIJOYSTATE2), &dijs);
166
- if (SUCCEEDED(hr))
151
+ if (SUCCEEDED(hr))
167
152
  {
153
+ printf("[X=%d Y=%d Z=%d][Rx=%d Ry=%d Rz=%d][Slider1=%d Slider2=%d]\n",
168
- printf("取得成功!");
154
+ dijs.lX, dijs.lY, dijs.lZ,
169
-
155
+ dijs.lRx, dijs.lRy, dijs.lRz,
156
+ dijs.rglSlider[0], dijs.rglSlider[1]);
157
+
170
158
  }
171
159
  else
172
160
  {
173
161
  // 失敗なら再開させてもう一度取得
174
162
  g_pDIDevice->Acquire();
175
- g_pDIDevice->Poll();
163
+ g_pDIDevice->Poll();
176
164
  g_pDIDevice->GetDeviceState(sizeof(DIJOYSTATE2), &dijs);
177
165
  printf("取得失敗!\n");
178
166
  }
179
-
167
+
180
- Sleep(1000);
168
+ Sleep(1000);
181
169
  }
182
170
 
183
171
  g_pDIDevice->Unacquire();
@@ -235,8 +223,6 @@
235
223
  ```
236
224
 
237
225
  ###試したこと
238
- モードの設定(hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)を除くことで成功しました。
239
- しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
240
226
  原因は
241
227
  HRESULT IDirectInputDevice8::SetCooperativeLevel(
242
228
  HWND hwnd
@@ -247,11 +233,12 @@
247
233
  HWND hWlg = GetDesktopWindow();
248
234
  また今回opencvと組み合わせるので
249
235
  HWND hWlg = (HWND)cvGetWindowHandle(windowName);
250
- も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。
236
+ も試してみましたが、こちらも入力制御ができませんでした。
251
237
  ### 補足情報(FW/ツールのバージョンなど)
252
238
 
253
239
  参考にしたもの
254
240
  http://www.kohgakusha.co.jp/support/sdx9xpv7/index.html
255
241
  のサンプルプログラム4
256
- 利用したジョイスティック
242
+ 利用したジョイスティック・ゲームパッド
257
- Cyborg Evo Force Joystick(フォースフィードバック機能あり)
243
+ Cyborg Evo Force Joystick(フォースフィードバック機能あり)
244
+ BSGP1204BK(フォースフィードバック機能なし)

6

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

2019/11/19 17:07

投稿

Tatsuk
Tatsuk

スコア11

title CHANGED
@@ -1,1 +1,1 @@
1
- DirectInput 入力開始(Acquire())が失敗てしまう。
1
+ DirectInput コンソールでフィードバック機能付きジョイスティックの情報を取得たい
body CHANGED
@@ -8,7 +8,10 @@
8
8
 
9
9
  ```
10
10
  ”Acquireに失敗”
11
+ と表示され、入力の開始が実行できない状態です。
12
+ モードの設定
13
+ (hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)
11
- と表示され、入力開始が実行できない状態でンターフェイスの取得・デバイスの作成および設定が成功るのに、入力の開始できな理由を探し当てることが出来なかっ為、こちら質問させ頂きました。
14
+ EXCLUSIVEをNONWXCLUSIVE変更ることでジョイスティック情報は取得可能ですが、最終的にフォースフィードバックを行いたいの、どうにかし排他設定にしたいです
12
15
  ```
13
16
 
14
17
  ```c++
@@ -234,19 +237,17 @@
234
237
  ###試したこと
235
238
  モードの設定(hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)を除くことで成功しました。
236
239
  しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
237
- 追記
240
+ 原因は
238
- 間違っていたら申し訳ありませんが原因は
239
241
  HRESULT IDirectInputDevice8::SetCooperativeLevel(
240
242
  HWND hwnd
241
243
  DWORD dwFlags
242
244
  );
243
245
  の最初の引数として必要なHWNDの部分に対応可能なハンドルをGetConsoleWindow()では取得できないせいではないかと考えています。
244
- 追記
245
246
  HWND hWlg = GetForegroundWindow();
246
247
  HWND hWlg = GetDesktopWindow();
247
248
  また今回opencvと組み合わせるので
248
249
  HWND hWlg = (HWND)cvGetWindowHandle(windowName);
249
- も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。。。
250
+ も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。
250
251
  ### 補足情報(FW/ツールのバージョンなど)
251
252
 
252
253
  参考にしたもの

5

誤字

2019/11/18 13:45

投稿

Tatsuk
Tatsuk

スコア11

title CHANGED
File without changes
body CHANGED
@@ -236,7 +236,7 @@
236
236
  しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
237
237
  追記
238
238
  間違っていたら申し訳ありませんが原因は
239
- HRESULT IDrectInputDevice8::SetcooperativeLevel(
239
+ HRESULT IDirectInputDevice8::SetCooperativeLevel(
240
240
  HWND hwnd
241
241
  DWORD dwFlags
242
242
  );

4

追記

2019/11/18 12:51

投稿

Tatsuk
Tatsuk

スコア11

title CHANGED
File without changes
body CHANGED
@@ -244,6 +244,8 @@
244
244
  追記
245
245
  HWND hWlg = GetForegroundWindow();
246
246
  HWND hWlg = GetDesktopWindow();
247
+ また今回opencvと組み合わせるので
248
+ HWND hWlg = (HWND)cvGetWindowHandle(windowName);
247
249
  も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。。。
248
250
  ### 補足情報(FW/ツールのバージョンなど)
249
251
 

3

追記

2019/11/18 12:33

投稿

Tatsuk
Tatsuk

スコア11

title CHANGED
File without changes
body CHANGED
@@ -241,9 +241,10 @@
241
241
  DWORD dwFlags
242
242
  );
243
243
  の最初の引数として必要なHWNDの部分に対応可能なハンドルをGetConsoleWindow()では取得できないせいではないかと考えています。
244
-
244
+ 追記
245
-
245
+ HWND hWlg = GetForegroundWindow();
246
-
246
+ HWND hWlg = GetDesktopWindow();
247
+ も試してみましたが、こちらも入力制御ができませんでした。コンソールアプリでは排他制御のセットは不可能なのでしょうか。。。
247
248
  ### 補足情報(FW/ツールのバージョンなど)
248
249
 
249
250
  参考にしたもの

2

問題の進展

2019/11/18 11:50

投稿

Tatsuk
Tatsuk

スコア11

title CHANGED
File without changes
body CHANGED
@@ -234,6 +234,13 @@
234
234
  ###試したこと
235
235
  モードの設定(hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)を除くことで成功しました。
236
236
  しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
237
+ 追記
238
+ 間違っていたら申し訳ありませんが原因は
239
+ HRESULT IDrectInputDevice8::SetcooperativeLevel(
240
+ HWND hwnd
241
+ DWORD dwFlags
242
+ );
243
+ の最初の引数として必要なHWNDの部分に対応可能なハンドルをGetConsoleWindow()では取得できないせいではないかと考えています。
237
244
 
238
245
 
239
246
 

1

問題が進展した

2019/11/18 11:03

投稿

Tatsuk
Tatsuk

スコア11

title CHANGED
File without changes
body CHANGED
@@ -231,6 +231,9 @@
231
231
 
232
232
  ```
233
233
 
234
+ ###試したこと
235
+ モードの設定(hr=g_pDIDevice->SetCooperativeLevel(hWlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND);)を除くことで成功しました。
236
+ しかし、排他制御のセットをしないとフォースフィードバックが利用できないのでなんとかセットを行いたいです。
234
237
 
235
238
 
236
239