MFC学习笔记 — 看小白如何实现音乐播放器(USB-HID 声卡 wav播放)

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

XX  作       者:文化人

XX  联系方式:(或进群:471144274

XX  版权声明:原创文章,欢迎评论和转载~转载时能告诉我一声就最好了

XX  要说的话:作者水平有限,难免有不足之处,恳请指正!

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

1、USB设备的枚举和读写:

参考链接1:USB_HID通信上位机程序VC6.0(真正类似呀呀USB工具的源代码).rar-C++代码类资源-CSDN下载

参考链接2:《圈圈教你玩USB》HID上位机和下位机实例源码_圈圈教你玩usb光盘-嵌入式文档类资源-CSDN下载

我把代码中PVN改为了usagepage,因为PVN会有多个设备,而usagepage可以确保只有一个;

获得usagepage需要添加如下代码:

hDevHandle=CreateFile(MyDevPathName, 
			NULL, 
			FILE_SHARE_READ|FILE_SHARE_WRITE, 
			NULL,OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,
			NULL);
						
//获取设备的属性并保存在DevAttributes结构体中
Result=HidD_GetAttributes(hDevHandle, &DevAttributes);
//关闭刚刚打开的设备
CloseHandle(hDevHandle);
//如果获取成功,则将属性中的VID、PID以及设备版本号与我们需要的
//进行比较,如果都一致的话,则说明它就是我们要找的设备。
if(MyVid == DevAttributes.VendorID)
{
	if(MyPid == DevAttributes.ProductID)
	{
		//这里进行读写访问打开设备
		
		if(!HidD_GetPreparsedData(hWriteHandle, &PreparsedData))
		{
			CloseHandle(hWriteHandle);
			return FALSE;
		}
		if(!HidP_GetCaps(PreparsedData, &Capabilities))
		{
			CloseHandle(hWriteHandle);
			return FALSE;
		}
		if(Capabilities.UsagePage == 0xffa0)
		{
			MyDevFound = TRUE;
		}
	}
}

如果以上的链接中,写数据失败的话,建议改用下面的写接口:

BOOL CUsbDlg::OnBUTTONSend(UCHAR send_buf[64]) 
{
	CString DevicePath;
	BOOL Result;
	UINT LastError;

	unsigned long numBytesReturned;
	DevicePath=temp;
	HANDLE hCom = CreateFile (
		DevicePath,
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING, 0,
		NULL);
	if (hCom == INVALID_HANDLE_VALUE)
	{}
	DataInSending=TRUE;
	Result = WriteFile(hCom, send_buf, 19, &numBytesReturned, NULL);
	//如果函数返回失败,则可能是真的失败,也可能是IO挂起了
	if(Result==FALSE)
	{
		//获取最后错误代码
		LastError=GetLastError();
		//看是否是真的IO挂起
		if((LastError==ERROR_IO_PENDING)||(LastError==ERROR_SUCCESS))
		{
			return TRUE;
		}
		//否则,是函数调用时发生错误,显示错误代码
		else
		{
			DataInSending=FALSE;
			AddToInfOut("发送失败,错误代码:"+itos(LastError));
			//如果最后错误为1,说明该设备不支持该函数。
			if(LastError==1)
			{
				AddToInfOut("该设备不支持WriteFile函数。", FALSE);
			}
			return FALSE;
		}
	}
	//否则,函数返回成功
	else
	{
		DataInSending=FALSE;
		return TRUE;
	}
	return TRUE;
}

2、声卡选择:windows代码设置默认音频输出设备_kevin的博客-CSDN博客

作者的代码是排除了默认声卡,选择新的声卡,但若是有两个新的声卡呢?

我去掉了判断默认音频设备的代码,把红色框内的代码修改为如下:

setlocale(LC_ALL,"");//此句必须要加上
char mbBuffer[256] = {0};
size_t  count;
count = wcstombs(mbBuffer, friendlyName.pwszVal, 256);// 转换并返回多字节字符串的长度
if(strstr(mbBuffer, "Usb Dongle"))
	SetDefaultAudioPlaybackDevice(wstrID);

3、播放音乐:

参考链接1:C++ 播放音频文件_weixinhum-CSDN博客_c++ 播放mp3

参考链接2:VC程序播放音乐必备---mciSendString用法_IT民工-CSDN博客

添加如下代码,界面上加一个编辑框,实现动态选择wav文件:

char buf[256];
sprintf(buf, _T("open %s.wav alias wave"), get_wav_filename_from_edit);
mciSendString(buf, NULL, 0, NULL);//alias后面为设备名称
mciSendString(_T("play wave wait"), NULL, 0, NULL);//wait表示播放完毕之后才返回,最好加上去
mciSendString(_T("close wave"), NULL, 0, NULL);

注意:只有使用生成的.exe才能播放音乐,VS里调试时是播放不成功的;

4、编译可能会遇到一些错误,其中一类错误的原因:

       “error LNK2019: 无法解析的外部符号”的几种可能原因_沈春旭的博客-CSDN博客_lnk2019无法解析的外部符号

5、HID使用的库文件在这里,用到的头文件如下,:

extern "C" {
#include "hidsdi.h"
#include "setupapi.h"
}
#include <afxwin.h>
#include "Common.h"
#include <wchar.h>
#include <locale.h>
#include "Mmdeviceapi.h"
#include "PolicyConfig.h"
#include "Propidl.h"
#include "Functiondiscoverykeys_devpkey.h"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文化人Sugar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值