完全是一篇DEMO级别,入门级别的编程文章
参考资料:
http://tieba.baidu.com/p/278512011
http://www.cnblogs.com/kingthy/archive/2009/03/25/1421838.html
http://www.cnblogs.com/kingthy/archive/2009/03/28/1424055.html
鉴于以上资料可能会被删除,这里做一些总结:
VB6实现代码:
搜索了以下好像吧内没有人贴关于手柄编程的文章,我贴一个XP+VB6.0+usb手柄测试通过
==========================
Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As Long, pji As JOYINFOEX) As Long
Declare Function joyReleaseCapture Lib "winmm.dll" (ByVal id As Long) As Long
Declare Function joySetCapture Lib "winmm.dll" (ByVal hwnd As Long, ByVal uID As Long, ByVal uPeriod As Long, ByVal bChanged As Long) As Long
' think they are all necessary though.
Public Const JOYSTICKID1 = 0
Public Const JOYSTICKID2 = 1
Public Const JOY_POVCENTERED = -1
Public Const JOY_POVFORWARD = 0
Public Const JOY_POVRIGHT = 9000
Public Const JOY_POVLEFT = 27000
Public Const JOY_RETURNX = &H1&
Public Const JOY_RETURNY = &H2&
Public Const JOY_RETURNZ = &H4&
Public Const JOY_RETURNR = &H8&
Public Const JOY_RETURNU = &H10
Public Const JOY_RETURNV = &H20
Public Const JOY_RETURNPOV = &H40&
Public Const JOY_RETURNBUTTONS = &H80&
Public Const JOY_RETURNRAWDATA = &H100&
Public Const JOY_RETURNPOVCTS = &H200&
Public Const JOY_RETURNCENTERED = &H400&
Public Const JOY_USEDEADZONE = &H800&
Public Const JOY_RETURNALL = (JOY_RETURNX Or JOY_RETURNY Or JOY_RETURNZ Or JOY_RETURNR Or JOY_RETURNU Or JOY_RETURNV Or JOY_RETURNPOV Or JOY_RETURNBUTTONS)
Public Const JOY_CAL_READALWAYS = &H10000
Public Const JOY_CAL_READRONLY = &H2000000
Public Const JOY_CAL_READ3 = &H40000
Public Const JOY_CAL_READ4 = &H80000
Public Const JOY_CAL_READXONLY = &H100000
Public Const JOY_CAL_READYONLY = &H200000
Public Const JOY_CAL_READ5 = &H400000
Public Const JOY_CAL_READ6 = &H800000
Public Const JOY_CAL_READZONLY = &H1000000
Public Const JOY_CAL_READUONLY = &H4000000
Public Const JOY_CAL_READVONLY = &H8000000
Type JOYINFOEX
dwSize As Long ' size of structure
dwFlags As Long ' flags to indicate what to return
dwXpos As Long ' x position
dwYpos As Long ' y position
dwZpos As Long ' z position
dwRpos As Long ' rudder/4th axis position
dwUpos As Long ' 5th axis position
dwVpos As Long ' 6th axis position
dwButtons As Long ' button states
dwButtonNumber As Long ' current button number pressed
dwPOV As Long ' point of view state
dwReserved1 As Long ' reserved for communication between winmm driver
dwReserved2 As Long ' reserved for future expansion
End Type
===============================================
以上是模块
以下是主程序:其中要放上一个shape控件和一个timer,用手柄控制shape左右移动
Dim myJoy As JOYINFOEX
Private Sub Form_Load()
Dim r&
Dim hwnd&
Static TheX As Long
Static TheY As Long
' Tell form to receive joystick functions.
r& = joySetCapture(hwnd, JOYSTICKID1, 1, 0)
r& = joyReleaseCapture(JOYSTICKID1)
' Get joystick position coordinates and fill in the TheX and TheY
' variables.
r& = joyGetPosEx(JOYSTICKID1, myJoy)
TheX = myJoy.dwXpos
TheY = myJoy.dwYpos
End Sub
Private Sub Timer1_Timer()
Dim bc As Integer
Cls
bc = 100
myJoy.dwSize = 64
myJoy.dwFlags = JOY_RETURNALL
' Cls
' Get the joystick coordinates.
r& = joyGetPosEx(JOYSTICKID1, myJoy)
If r = 0 Then
xx = myJoy.dwXpos 'As Long ' x position
yy = myJoy.dwYpos 'As Long ' y position
' 6th axis position
bb = myJoy.dwButtons ' As Long ' button states
nn = myJoy.dwButtonNumber ' As Long ' current button number pressed
If yy = 0 Then
Print "游戏柄1的向上键"
Shape1.Move Shape1.Left, Shape1.Top - bc
ElseIf yy = 65535 Then
Print "游戏柄1的向下键"
Shape1.Move Shape1.Left, Shape1.Top + bc
End If
If xx = 0 Then
Print "游戏柄1的向左键"
Shape1.Move Shape1.Left - bc, Shape1.Top
ElseIf xx = 65535 Then
Print "游戏柄1的向右键"
Shape1.Move Shape1.Left + bc, Shape1.Top
End If
For i = 0 To 9
temp = (bb And 2 ^ i) / (2 ^ i)
If temp = 1 Then
Print "游戏柄1的" & i + 1 & "号键"
End If
temp = 0
Next i
temp = 0
If nn > 0 Then
Print "一共按下了" & nn & "个键"
End If
End If
End Sub
代码简洁通俗易懂,相信学过VB的人都能看得懂
本文结合后两篇文章做了VB.NET语言的版本:
Imports System.Runtime.InteropServices
Public Class JoyDemoFrm
Public Const JOY_RETURNBUTTONS = &H80&
Structure JOYINFO
Dim wXpos As Integer
Dim wYpos As Integer
Dim zYpos As Integer
Dim wButtons As Integer
End Structure
Structure JOYINFOEX
Dim dwSize As Integer 'size of structure
Dim dwFlags As Integer ' flags to indicate what to return
Dim wXpos As Integer ' x position
Dim wYpos As Integer ' y position
Dim wZpos As Integer ' z position
Dim wRpos As Integer ' rudder/4th axis position
Dim wUpos As Integer ' 5th axis position
Dim wVpos As Integer ' 6th axis position
Dim wButtons As Integer ' button states
Dim wButtonNumber As Integer ' current button number pressed
Dim dwPOV As Integer ' point of view state
Dim dwReserved1 As Integer ' reserved for communication between winmm driver
Dim dwReserved2 As Integer ' reserved for future expansion
End Structure
Private Declare Function joyGetPos Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef jInfo As JOYINFO) As Integer
Private Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef jInfo As JOYINFOEX) As Integer
Private Sub JoyDemoFrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim infoJEx As JOYINFOEX
With infoJEx
.dwSize = Marshal.SizeOf(GetType(JOYINFOEX))
.dwFlags = CInt(JOY_RETURNBUTTONS)
End With
Dim result As Integer = joyGetPosEx(Me.IsDisposed, infoJEx) '返回JOYERR_NOERROR(值为0)
'MsgBox(res)
If result = 0 Then
'获取成功,输出原始数据
JoyInfoTXT.Text = "dwSize=" & infoJEx.dwSize & vbCrLf
JoyInfoTXT.Text &= "dwFlags=" & infoJEx.dwFlags & vbCrLf
JoyInfoTXT.Text &= "dwXpos =" & infoJEx.wXpos & vbCrLf
JoyInfoTXT.Text &= "dwYpos =" & infoJEx.wYpos & vbCrLf
JoyInfoTXT.Text &= "dwZpos =" & infoJEx.wZpos & vbCrLf
JoyInfoTXT.Text &= "dwRpos=" & infoJEx.wRpos & vbCrLf
JoyInfoTXT.Text &= "dwUpos=" & infoJEx.wUpos & vbCrLf
JoyInfoTXT.Text &= "dwVpos=" & infoJEx.wVpos & vbCrLf
JoyInfoTXT.Text &= "dwButton=" & infoJEx.wButtons & vbCrLf
JoyInfoTXT.Text &= "dwBNumber=" & infoJEx.wButtonNumber & vbCrLf
JoyInfoTXT.Text &= "dwPOV=" & infoJEx.dwPOV & vbCrLf
JoyInfoTXT.Text &= "dwRsved1=" & infoJEx.dwReserved1 & vbCrLf
JoyInfoTXT.Text &= "dwRsved2=" & infoJEx.dwReserved2 & vbCrLf
'输出功能数据
CurBtn.Text = ""
If infoJEx.wXpos = 0 Then '输出左右按键状态
CurBtn.Text = "左键被按下" & vbCrLf
ElseIf infoJEx.wXpos = 65535 Then
CurBtn.Text = "右键被按下" & vbCrLf
End If
If infoJEx.wYpos = 0 Then '输出上下按键状态
CurBtn.Text &= "上键被按下" & vbCrLf
ElseIf infoJEx.wYpos = 65535 Then
CurBtn.Text &= "下键被按下" & vbCrLf
End If
'输出数字键
Dim i As Integer
For i = 0 To 9 '按位输出
If (infoJEx.wButtons And 2 ^ i) = 0 Then
Else
CurBtn.Text &= "数字键" & i + 1 & "被按下" & vbCrLf
End If
Next
'输出遥感状态
'左摇杆
If (infoJEx.wButtons And 2 ^ 10) Then
CurBtn.Text &= "左摇杆被按下" & vbCrLf
End If
'右遥感
If (infoJEx.wButtons And 2 ^ 11) Then
CurBtn.Text &= "右摇杆被按下" & vbCrLf
End If
If infoJEx.wZpos < 32511 Then '位移量
CurBtn.Text &= "右摇杆状态:" & vbCrLf & " 偏左精度值:" & 32511 - infoJEx.wZpos & vbCrLf
ElseIf infoJEx.wZpos > 32511 Then
CurBtn.Text &= "右摇杆状态:" & vbCrLf & " 偏右精度值:" & infoJEx.wZpos - 32511 & vbCrLf
Else
End If
If infoJEx.wRpos < 32511 Then '位移量
CurBtn.Text &= "右摇杆状态:" & vbCrLf & " 偏上精度值:" & 32511 - infoJEx.wRpos & vbCrLf
ElseIf infoJEx.wRpos > 32511 Then
CurBtn.Text &= "右摇杆状态:" & vbCrLf & " 偏下精度值:" & infoJEx.wRpos - 32511 & vbCrLf
Else
End If
Else
'获取失败,输出错误
MsgBox("请确定插上了手柄并且正确安装了驱动")
End
End If
End Sub
End Class
结合后两篇文章对代码中的要点做下总结:
1、此处采用主动方式进行编程,被动方式需要处理冗余的消息包
2、JOYINFO对应joyGetPos方法,获取的参数不全,推荐使用joyGetPosEX函数
3、必须先初始化JOYINFOEX结构实例,并要设置dwSize参数的值,也即是JOYINFOEX结构体所占用的内存空间大小(其值可通过Marshal.SizeOf求得)
4、而如果要取得游戏设备的其它参数,则还必须要设置dwFlags参数的值!否则只能获取坐标值(dwXPos)。如对游戏手柄来说我们需要获取其它按钮的状态,则设置dwFlags的值为JOY_RETURNBUTTONS,用于指示我们需要返回所有按钮的状态。
置于需要进行力反馈编程,据说需要采用DI的方式,而不是API的方式,难道极品中有些版本不支持力反馈也是这个原因?