MFC學習筆記 — 看小白如何實現音樂播放器(USB-HID 音效卡 wav播放)
阿新 • • 發佈:2019-02-02
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX 作 者:ZHS(文化人)
XX 聯絡方式:文章末尾Chat快問(或進群:471144274)
XX 要說的話:作者水平有限,難免有不足之處,懇請指正!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1、USB裝置的列舉和讀寫:
我把程式碼中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; }
作者的程式碼是排除了預設音效卡,選擇新的音效卡,但若是有兩個新的音效卡呢?
我去掉了判斷預設音訊裝置的程式碼,把紅色框內的程式碼修改為如下:
setlocale(LC_ALL,"");//此句必須要加上
char mbBuffer[256] = {0};
size_t count;
count = wcstombs(mbBuffer, friendlyName.pwszVal, 256);// 轉換並返回多位元組字串的長度
if(strstr(mbBuffer, "Usb Dongle"))
SetDefaultAudioPlaybackDevice(wstrID);
3、播放音樂:
新增如下程式碼,介面上加一個編輯框,實現動態選擇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、編譯可能會遇到一些錯誤,其中一類錯誤的原因:
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"