JoyToKey 游戲手柄輸入映射為鍵盤輸入
本想用游戲手柄玩模擬器游戲的,可惜
游戲手柄在本機上可以使用,然而在虛擬機中無法使用(本機為Win7,手柄為北通戰戟,虛擬機為VirtualBox4.0.12),
而我的模擬器游戲都裝在虛擬的WinXP中,因為我不放心這些模擬器呀。
于是:
1
/*
2
JoyToKey.cpp
3
4
Copyright (C) 2011, coreBugZJ, all rights reserved.
5
6
功能:
7
將游戲手柄操作映射為鍵盤按鍵操作。
8
9
原理:
10
接收手柄消息,然后產生相應鍵盤消息。
11
12
上 W
13
下 S
14
左 A
15
右 D
16
17
1 U
18
2 I
19
3 J
20
4 K
21
22
*/
23
24
25
#include <Windows.h>
26
#include <MMSystem.h>
27
28
29
#pragma comment( lib, "winmm.lib" )
30
31
32
TCHAR gClassName[] = TEXT("JoyToKey");
33
TCHAR gWndName[] = TEXT("JoyToKey -- coreBugZJ");
34
35
36
#define ID_TIMER 1
37
#define ELAPSE 50
38
39
40
VOID errorOut( HWND hWnd, TCHAR msg[], UINT msglen ) {
41
HDC hdc = ::GetDC( hWnd );
42
::TextOut( hdc, 50, 50, msg, msglen );
43
::ReleaseDC( hWnd, hdc );
44
}
45
46
#define MAKEKEY(k) do { \
47
::keybd_event( k, MapVirtualKey(k,0), 0, 0 ); \
48
::Sleep( 50 ); \
49
::keybd_event( k, MapVirtualKey(k,0), KEYEVENTF_KEYUP, 0 ); \
50
} while ( 0 )
51
52
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
53
static JOYINFO ji;
54
static UINT id = 0xFFFF;
55
static JOYCAPS jc;
56
static INT jxl, jxr, jyt, jyb, jxm, jym;
57
58
switch ( uMsg ) {
59
case WM_CREATE :
60
if ( 0 == ::joyGetNumDevs() ) {
61
::MessageBox( hWnd, TEXT("0 == ::joyGetNumDevs()\n\n請檢查手柄是否插好"), TEXT("Error"), MB_OK | MB_ICONERROR );
62
::SendMessage( hWnd, WM_DESTROY, 0, 0 );
63
return 0;
64
}
65
66
if ( JOYERR_UNPLUGGED == ::joyGetPos( JOYSTICKID1, &ji ) ) {
67
::MessageBox( hWnd, TEXT("JOYERR_UNPLUGGED == ::joyGetPos()\n\n請檢查手柄是否插好"), TEXT("Error"), MB_OK | MB_ICONERROR );
68
::SendMessage( hWnd, WM_DESTROY, 0, 0 );
69
return 0;
70
}
71
72
if ( JOYERR_NOERROR != ::joyGetDevCaps( JOYSTICKID1, &jc, sizeof(jc) ) ) {
73
::MessageBox( hWnd, TEXT("JOYERR_NOERROR != ::joyGetDevCaps()\n\n請檢查手柄是否插好"), TEXT("Error"), MB_OK | MB_ICONERROR );
74
::SendMessage( hWnd, WM_DESTROY, 0, 0 );
75
return 0;
76
}
77
78
id = JOYSTICKID1;
79
80
jxm = ( jc.wXmin + jc.wXmax ) / 2;
81
jxl = ( jc.wXmin + jxm ) / 2;
82
jxr = ( jc.wXmax + jxm ) / 2;
83
84
jym = ( jc.wYmin + jc.wYmax ) / 2;
85
jyt = ( jc.wYmin + jym ) / 2;
86
jyb = ( jc.wYmax + jym ) / 2;
87
88
::joySetCapture( hWnd, id, 0, FALSE );
89
90
::SetTimer( hWnd, ID_TIMER, ELAPSE, NULL );
91
92
return 0;
93
94
case WM_TIMER :
95
if ( JOYERR_NOERROR != ::joyGetPos( id, &ji ) ) {
96
return 0;
97
}
98
if ( ji.wXpos < jxl ) {
99
// 左
100
MAKEKEY('A');
101
errorOut( hWnd, TEXT("left "), 12 );
102
}
103
if ( ji.wXpos > jxr ) {
104
// 右
105
MAKEKEY('D');
106
errorOut( hWnd, TEXT("right "), 12 );
107
}
108
if ( ji.wYpos < jyt ) {
109
// 上
110
MAKEKEY('W');
111
errorOut( hWnd, TEXT("top "), 12 );
112
}
113
if ( ji.wYpos > jyb ) {
114
// 下
115
MAKEKEY('S');
116
errorOut( hWnd, TEXT("down "), 12 );
117
}
118
if ( ji.wButtons & JOY_BUTTON1 ) {
119
// 1
120
MAKEKEY('U');
121
errorOut( hWnd, TEXT("1 "), 12 );
122
}
123
if ( ji.wButtons & JOY_BUTTON2 ) {
124
// 2
125
MAKEKEY('I');
126
errorOut( hWnd, TEXT("2 "), 12 );
127
}
128
if ( ji.wButtons & JOY_BUTTON3 ) {
129
// 3
130
MAKEKEY('J');
131
errorOut( hWnd, TEXT("3 "), 12 );
132
}
133
if ( ji.wButtons & JOY_BUTTON4 ) {
134
// 4
135
MAKEKEY('K');
136
errorOut( hWnd, TEXT("4 "), 12 );
137
}
138
return 0;
139
140
case WM_DESTROY :
141
if ( JOYSTICKID1 == id ) {
142
::KillTimer( hWnd, ID_TIMER );
143
::joyReleaseCapture( id );
144
}
145
::PostQuitMessage( 0 );
146
return 0;
147
}
148
149
return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
150
}
151
152
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmd, INT nShow ) {
153
WNDCLASSEX wc;
154
HWND hWnd;
155
MSG msg;
156
157
wc.cbClsExtra = 0;
158
wc.cbSize = sizeof(wc);
159
wc.cbWndExtra = 0;
160
wc.hbrBackground = (HBRUSH)::GetStockObject( WHITE_BRUSH );
161
wc.hCursor = ::LoadCursor( NULL, IDC_ARROW );
162
wc.hIcon = ::LoadIcon( NULL, IDI_APPLICATION );
163
wc.hIconSm = ::LoadIcon( NULL, IDI_APPLICATION );
164
wc.hInstance = hInst;
165
wc.lpfnWndProc = WndProc;
166
wc.lpszClassName = gClassName;
167
wc.lpszMenuName = NULL;
168
wc.style = 0;
169
170
if ( 0 == ::RegisterClassEx( &wc ) ) {
171
::MessageBox( NULL, TEXT("RegisterClassEx Failed!"), TEXT("Error"), MB_OK | MB_ICONERROR );
172
return 0;
173
}
174
175
hWnd = ::CreateWindowEx( 0,
176
gClassName, gWndName,
177
WS_OVERLAPPEDWINDOW,
178
200, 200, 400, 100,
179
NULL, NULL,
180
hInst, NULL );
181
if ( NULL == hWnd ) {
182
::MessageBox( NULL, TEXT("CreateWindowEx Failed!"), TEXT("Error"), MB_OK | MB_ICONERROR );
183
return 0;
184
}
185
::ShowWindow( hWnd, nShow );
186
::UpdateWindow( hWnd );
187
188
while ( ::GetMessage( &msg, NULL, 0, 0 ) ) {
189
::TranslateMessage( &msg );
190
::DispatchMessage( &msg );
191
}
192
return msg.wParam;
193
}
194

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

在我的宿主機上運行此軟件,然后在虛擬機上運行游戲且設置鍵盤操作的對應鍵位,因為對手柄操作將產生相應的鍵盤操作,所以就可以用手柄玩游戲了。
小問題:由于手柄操作映射到鍵盤操作的方式,導致操作有一點點的變異。。。
posted on 2011-10-03 23:32 coreBugZJ 閱讀(4385) 評論(4) 編輯 收藏 引用 所屬分類: Windows 、娛樂