admin管理员组

文章数量:1558098

文章目录

    • 1.关键函数
      • 1.1 joySetCapture
      • 1.2 joyReleaseCapture
    • 2.游戏窗口消息
    • 3.简单案例
    • 4.作者答疑

  在 WINDOWS 下编程控制游戏手柄比较主流的技术是用 DirectInput。如果不需要复杂的控制功能,也可以直接使用 WIN API (multimedia joystick API)。来完成简单控制。在 windows 系统中,最多可以同时监控两个游戏手柄,每个游戏手柄最多可以有四个控制键。在程序中既可以直接读取游戏手柄的位置信息和按键状态,也可以通过监控相应的系统消息的方式来获得游戏手柄的信息。多数时候我们在程序中都采用接收游戏手柄消息的方式,因为这种方式不需要定时轮询游戏手柄的状态。游戏手柄相关的函数都封装在 Winmm.dll 中。相应的头文件是 mmsystem.h, 链接时需要链接 WINMM.lib。源代码如下所示:

#include <mmsystem.h>
#pragma comment(lib, "WINMM.lib")

1.关键函数

1.1 joySetCapture

  joySetCapture函数通过将消息发送到指定窗口来捕获游戏杆。函数结构如下:

MMRESULT joySetCapture(
  HWND hwnd,//处理窗口以接收操纵杆消息。
  UINT uJoyID,//要捕获的操纵杆的标识符。uJoyID的有效值范围从零 (JOYSTICKID1) 到 15。
  UINT uPeriod,//轮询频率,以毫秒为单位。
  BOOL fChanged//更改位置标志。将此参数指定为TRUE以仅在位置更改的值大于操纵杆移动阈值时发送消息。否则,将以uPeriod中指定的轮询频率发送消息。
);

  返回值:如果成功或以下错误值之一,则返回 JOYERR_NOERROR。

返回码描述
MMSYSERR_NODRIVER操纵杆驱动程序不存在。
MMSYSERR_INVALPARAM无效的操纵杆 ID 或 hwnd 为NULL。
JOYERR_NOCANDO无法捕获操纵杆输入,因为所需的服务(例如 Windows 计时器)不可用。
JOYERR_UNPLUGGED指定的操纵杆未连接到系统。
JOYERR_PARMS无效的操纵杆 ID 或 hwnd 为NULL。

  部分范例代码,如下所示:

UINT result =::joySetCapture(CDialog::m_hWnd, JOYSTICKID1, 0, FALSE);
if(result == JOYERR_NOCANDO)
{
    MessageBeep(MB_ICONEXCLAMATION);
    MessageBox("不能捕获游戏杆", NULL, MB_OK | MB_ICONEXCLAMATION);
    return -1;
}
if(result == JOYERR_UNPLUGGED)
{
    MessageBeep(MB_ICONEXCLAMATION);
    MessageBox("游戏杆未与系统连接", NULL, MB_OK | MB_ICONEXCLAMATION);
    return -1;
}

1.2 joyReleaseCapture

  joyReleaseCapture函数释放指定捕获的操纵杆。函数结构如下:

MMRESULT joyReleaseCapture(
   UINT uJoyID//要释放的操纵杆的标识符。uJoyID的有效值范围从零 (JOYSTICKID1) 到 15。
);

  返回值:如果成功或以下错误值之一,则返回 JOYERR_NOERROR。

返回码描述
MMSYSERR_NODRIVER操纵杆驱动程序不存在。
MMSYSERR_INVALIDPARAM指定的操纵杆设备标识符uJoyID无效。
JOYERR_PARMS指定的操纵杆设备标识符uJoyID无效。

  部分范例代码,如下所示:

joyReleaseCapture(JOYSTICKID1);

2.游戏窗口消息

  在Win32中,支持窗口消息有三个MM_JOY1BUTTONDOWN、MM_JOY1MOVE、MM_JOY1BUTTONUP、MM_JOY2BUTTONDOWN、MM_JOY2MOVE和MM_JOY2BUTTONUP。通过这六个消息来接受两个手柄。

3.简单案例

  下面在MFC的消息函数中,展示如何接受游戏消息:

LRESULT CMyjoystickDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case MM_JOY1BUTTONDOWN :
        if (wParam & JOY_BUTTON1)
        {
            MessageBeep(MB_ICONQUESTION);
            SetDlgItemText(IDC_BUTTON1, "按下");
        }
        if (wParam & JOY_BUTTON2)
        {
            MessageBeep(MB_ICONEXCLAMATION);
            SetDlgItemText(IDC_BUTTON2, "按下");
            m_btn2.SetCheck(BST_CHECKED);
        }
        if (wParam & JOY_BUTTON3)
        {
            SetDlgItemText(IDC_BUTTON3, "按下");
        }
        if (wParam & JOY_BUTTON4)
        {
            SetDlgItemText(IDC_BUTTON4, "按下");
        }
    case MM_JOY1MOVE :
        WORD x, y;
        POINT pt;
        //UpdateData(TRUE);
        //获取当前屏幕光标位置
        GetCursorPos(&pt);
        //游戏杆在当前系统中的位置坐标范围从0 65535。位置表示范围从0-31
        if (!m_Absolute)
        {
            x = LOWORD(lParam) / 2048;
            y = HIWORD(lParam) / 2048;
            //如果游戏杆在中心位置的左边,移动光标到左边。反之亦然
            if(x <= 12)
            {
                pt.x = pt.x + x - 15;
                SetDlgItemText(IDC_BUTTON5, "Button 2:");
            }
            else if(x >= 20)
                pt.x = pt.x + x - 15;
            //如果游戏杆在中心位置的下边,移动光标到下边。反之亦然
            if(y <= 12)
                pt.y = pt.y + y - 15;
            else if(y >= 20)
                pt.y = pt.y + y - 15;
        }
        else
        {
            CDC *pDC = GetDC();
            x = LOWORD(lParam);
            y = HIWORD(lParam);
            pt.x = (pDC->GetDeviceCaps(HORZRES) * x) / 65536;
            pt.y = (pDC->GetDeviceCaps(VERTRES) * y) / 65536;
            ReleaseDC(pDC);
        }
        /* Set the new cursor position.*/
        SetCursorPos(pt.x, pt.y);
        break;
    case MM_JOY1BUTTONUP :
        SetDlgItemText(IDC_BUTTON1, "1");
        SetDlgItemText(IDC_BUTTON2, "2");
        SetDlgItemText(IDC_BUTTON3, "3");
        SetDlgItemText(IDC_BUTTON4, "4");
        break;
    }
    return CDialog::WindowProc(message, wParam, lParam);
}

4.作者答疑


  代码长度过长,如需全部项目或有疑问,请留言。

提示: 作者知了-联系方式1
提示: 作者知了-联系方式2

本文标签: 按键窗口方向游戏手柄Xbox