本想用游戏手柄玩模拟器游戏的,可惜
游戏手柄在本机上可以使用,然而在虚拟机中无法使用(本机为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
在我的宿主机上运行此软件,然后在虚拟机上运行游戏且设置键盘操作的对应键位,因为对手柄操作将产生相应的键盘操作,所以就可以用手柄玩游戏了。
小问题:由于手柄操作映射到键盘操作的方式,导致操作有一点点的变异。。。