Windows蓝牙开发参考

Home / C++ MrLee 2021-4-22 2384

以下代码为网上搜集材料。

(这个网站是微软官网上给出的关于蓝牙API函数)每个函数都看过,差点不多33个函数。但是具体的用法,官网上没有给出相关的例程,而且在实际的操作过程中,有函数被弃用,后面还有结构体的使用,返回值都有说明。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa362928(v=vs.85).aspx

以下代码为3种方法搜索蓝牙设备

#include "StdAfx.h"
#include "BlueTooth.h"
 
CBlueTooth::CBlueTooth(void)
{
	m_Ary_RemoteBthDevInfo.SetSize ( 0, 10*sizeof(BLUETOOTH_DEVICE_INFO) );
	m_Ary_LocalRadioInfo.SetSize ( 0, 10*sizeof(t_LocalRadioInfo) );
}
 
CBlueTooth::~CBlueTooth(void)
{
	RemoveAll_RemoteBthDevInfo ();
	RemoveAllLocalRadio ();
}
 
//
// 用 Socket 函数搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
//
int CBlueTooth::WSAScanNearbyBthDev ()
{
	m_Ary_RemoteBthDevInfo.RemoveAll ();
 
	WSAQUERYSET wsaq;
	HANDLE hLookup;
	union
	{
		CHAR buf[5000];
		double __unused; // ensure proper alignment
	};
 
	LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
	DWORD dwSize = sizeof(buf);
	BOOL bHaveName;
	ZeroMemory(&wsaq, sizeof(wsaq));
	wsaq.dwSize = sizeof(wsaq);
	wsaq.dwNameSpace = NS_BTH;
	wsaq.lpcsaBuffer = NULL;
	if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup))
	{
		TRACE ( _T("WSALookupServiceBegin failed\n") );
		return -1;
	}
 
	ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
	pwsaResults->dwSize = sizeof(WSAQUERYSET);
	pwsaResults->dwNameSpace = NS_BTH;
	pwsaResults->lpBlob = NULL;
	while (ERROR_SUCCESS == WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
	{
		ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
		BTH_ADDR b = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
		bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
		t_RemoteBthDevInfo RemoteBthDevInfo;
		if ( bHaveName )
		{
			StringCchPrintf ( RemoteBthDevInfo.szName, sizeof(RemoteBthDevInfo.szName), _T("%s"), 
				pwsaResults->lpszServiceInstanceName );
		}
		RemoteBthDevInfo.Address.ullLong = b;
 
		TRACE (L"%s ( %04x%08x )\n", RemoteBthDevInfo.szName, GET_NAP(b), GET_SAP(b) );
		m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
	}
	WSALookupServiceEnd(hLookup);
 
	return (int)m_Ary_RemoteBthDevInfo.GetSize();
}
 
BOOL AUTHENTICATION_CALLBACK (LPVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice)
{
	t_AUTHENTICATION_CALLBACK_Para *pAUTHENTICATION_CALLBACK_Para = (t_AUTHENTICATION_CALLBACK_Para*)pvParam;
	if ( pAUTHENTICATION_CALLBACK_Para )
	{
		pDevice->fAuthenticated = TRUE;
		DWORD result = BluetoothUpdateDeviceRecord ( pDevice );
		ASSERT ( result == ERROR_SUCCESS );
		result = BluetoothSendAuthenticationResponse ( pAUTHENTICATION_CALLBACK_Para->hRadio, pDevice, AUTHENTICATION_PASSKEY );
		if ( result == ERROR_SUCCESS )
			return TRUE;
	}
	return FALSE;
}
 
//
// 用蓝牙 APIs 搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
//
int CBlueTooth::ScanNearbyBthDev (
		HANDLE hRadio,
		BOOL fReturnAuthenticated/* = TRUE*/,
		BOOL fReturnRemembered/* = TRUE*/,
		BOOL fReturnUnknown/* = TRUE*/,
		BOOL fReturnConnected/* = TRUE*/,
		BOOL fIssueInquiry/* = FALSE*/,
		UCHAR cTimeoutMultiplier/* = 30*/
	)
{
	RemoveAll_RemoteBthDevInfo ();
	CWaitCursor WaitCursor;
 
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp;
	HBLUETOOTH_DEVICE_FIND hbf;
	ZeroMemory(&bdsp, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
 
	bdsp.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
	bdsp.hRadio = hRadio;
	bdsp.fReturnAuthenticated = fReturnAuthenticated;
	bdsp.fReturnRemembered = fReturnRemembered;
	bdsp.fReturnUnknown = fReturnUnknown;
	bdsp.fReturnConnected = fReturnConnected;
	bdsp.fIssueInquiry = fIssueInquiry;
	bdsp.cTimeoutMultiplier = cTimeoutMultiplier;
 
	hbf = BluetoothFindFirstDevice(&bdsp, &bdi);
	if (hbf == NULL) return -1;
 
	while(true)
	{
		TRACE ( _T("%s ( %s )\n"), bdi.szName, FormatBthAddress(bdi.Address.rgBytes) );
		t_RemoteBthDevInfo RemoteBthDevInfo;
		RemoteBthDevInfo.hRadio = hRadio;
		RemoteBthDevInfo.Address.ullLong = bdi.Address.ullLong;
		_snwprintf_s ( RemoteBthDevInfo.szName, LENGTH(RemoteBthDevInfo.szName), _T("%s"), bdi.szName );
		// 枚举服务
		EnumerateInstalledServices ( RemoteBthDevInfo );
		// 注册配对回调函数
		RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para = new t_AUTHENTICATION_CALLBACK_Para;
		if ( RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para )
		{
			RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para->lpBlueTooth = this;
			RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para->hRadio = hRadio;
		}
		BluetoothRegisterForAuthentication ( &bdi, &RemoteBthDevInfo.hRegHandle, AUTHENTICATION_CALLBACK, RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para );
 
		m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
		if ( !BluetoothFindNextDevice(hbf, &bdi) )
			break;
	}
	BluetoothFindDeviceClose(hbf);
 
	return (int)m_Ary_RemoteBthDevInfo.GetSize();
}
 
//
// 用向导手工搜索附近的蓝牙设备并建立连接,得到设备的详细信息,成功时返回设备数
//
int CBlueTooth::ScanNearbyBthDev_Wizard (
		HWND	hwndParent,
		HANDLE	hRadio,
		LPWSTR  pszInfo/*=NULL*/,						//  IN  If not NULL, sets the "information" text
		BOOL    fForceAuthentication/*=FALSE*/,			//  IN  If TRUE, authenication will be forced before returning
		BOOL    fShowAuthenticated/*=FALSE*/,			//  IN  If TRUE, authenticated devices will be shown in the picker
		BOOL    fShowRemembered/*=TRUE*/,				//  IN  If TRUE, remembered devices will be shown in the picker
		BOOL    fShowUnknown/*=TRUE*/,					//  IN  If TRUE, unknown devices that are not authenticated or "remember" will be shown.
		BOOL    fAddNewDeviceWizard/*=TRUE*/,			//  IN  If TRUE, invokes the add new device wizard.
		BOOL    fSkipServicesPage/*=FALSE*/,			//  IN  If TRUE, skips the "Services" page in the wizard.
		PFN_DEVICE_CALLBACK pfnDeviceCallback/*=NULL*/,	//  IN  If non-NULL, a callback that will be called for each device. If the
														//      the callback returns TRUE, the item will be added. If the callback is
														//      is FALSE, the item will not be shown.
		LPVOID  pvParam/*=NULL*/						//  IN  Parameter to be passed to pfnDeviceCallback as the pvParam.
	)
{
	RemoveAll_RemoteBthDevInfo ();
	BLUETOOTH_SELECT_DEVICE_PARAMS btsdp = { sizeof(btsdp) };
 
	btsdp.hwndParent = hwndParent;
	btsdp.pszInfo = pszInfo;
	btsdp.fForceAuthentication = fForceAuthentication;
	btsdp.fShowAuthenticated = fShowAuthenticated;
	btsdp.fShowRemembered = fShowRemembered;
	btsdp.fShowUnknown = fShowUnknown;
	btsdp.fAddNewDeviceWizard = fAddNewDeviceWizard;
	btsdp.fSkipServicesPage = fSkipServicesPage;
	btsdp.pfnDeviceCallback = pfnDeviceCallback;
	btsdp.pvParam = pvParam;
 
	BOOL b = BluetoothSelectDevices( &btsdp );
	if ( b )
	{
		BLUETOOTH_DEVICE_INFO *pbtdi = btsdp.pDevices;
		for ( ULONG cDevice = 0; cDevice < btsdp.cNumDevices; cDevice ++ )
		{
			if ( pbtdi->fAuthenticated || pbtdi->fRemembered )
			{
				t_RemoteBthDevInfo RemoteBthDevInfo;
				RemoteBthDevInfo.hRadio = hRadio;
				RemoteBthDevInfo.Address = pbtdi->Address;
				_snwprintf_s ( RemoteBthDevInfo.szName, LENGTH(RemoteBthDevInfo.szName), _T("%s"), pbtdi->szName );
				EnumerateInstalledServices ( RemoteBthDevInfo );
				m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
			}
			pbtdi = (BLUETOOTH_DEVICE_INFO *) ((LPBYTE)pbtdi + pbtdi->dwSize);
		}
		BluetoothSelectDevicesFree( &btsdp );
	}
 
	return (int)m_Ary_RemoteBthDevInfo.GetSize();
}
 
//
// 根据远程蓝牙设备的地址获取详细信息
//
BOOL CBlueTooth::BluetoothGetDeviceInfo ( IN t_RemoteBthDevInfo& RemoteBthDevInfo, OUT BLUETOOTH_DEVICE_INFO *pbtdi )
{
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	bdi.Address.ullLong = RemoteBthDevInfo.Address.ullLong;
	if ( ERROR_SUCCESS != ::BluetoothGetDeviceInfo ( RemoteBthDevInfo.hRadio, &bdi ) )
		return FALSE;
	if ( pbtdi ) memcpy ( pbtdi, &bdi, sizeof(BLUETOOTH_DEVICE_INFO) );
	return TRUE;
}
 
BOOL CBlueTooth::BluetoothSetServiceState ( HANDLE hRadio, BLUETOOTH_DEVICE_INFO &bdi, GUID guidService, DWORD dwServiceFlags )
{
	DWORD result = ::BluetoothSetServiceState(hRadio, &bdi, &guidService, dwServiceFlags);
	if ( ERROR_SUCCESS != result && ERROR_SERVICE_DOES_NOT_EXIST != result )
	{
		TRACE ( _T("BluetoothSetServiceState failed : %s\n"), hwFormatMessage (result) );
		return FALSE;
	}
	return TRUE;
}
 
// 枚举已安装的服务
int CBlueTooth::EnumerateInstalledServices( t_RemoteBthDevInfo& RemoteBthDevInfo )
{
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return -1;
 
	BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, SerialPortServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
	BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, LANAccessUsingPPPServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
	BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, DialupNetworkingServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
 
	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return -1;
	DWORD numServices = LENGTH(RemoteBthDevInfo.guidServices);	
	DWORD result = BluetoothEnumerateInstalledServices(RemoteBthDevInfo.hRadio,&bdi, &numServices, RemoteBthDevInfo.guidServices);
	if ( ERROR_SUCCESS == result ) return numServices;
	return -1;
}
 
// 显示序号为 nIndex 的蓝牙设备属性框
BOOL CBlueTooth::ShowPropertySheet(int nIndex, HWND hwdParent/*=NULL*/)
{
	if ( nIndex < 0 || nIndex >=m_Ary_RemoteBthDevInfo.GetSize() )
		return FALSE;
 
	t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt ( nIndex );
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return FALSE;
 
	return BluetoothDisplayDeviceProperties ( hwdParent, &bdi );
}
 
// 请求与远程蓝牙设备配对
BOOL CBlueTooth::RequestAuthenticateDevice(int nIndex, HWND hwdParent/*=NULL*/, DWORD *presult/*=NULL*/)
{
	if ( nIndex < 0 || nIndex >=m_Ary_RemoteBthDevInfo.GetSize() )
		return FALSE;
 
	t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt ( nIndex );
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return FALSE;
 
	if ( bdi.fAuthenticated ) return TRUE;	// 已经配对了
	bdi.fAuthenticated = TRUE;
	VERIFY ( ERROR_SUCCESS == BluetoothUpdateDeviceRecord ( &bdi ) );
	DWORD result = BluetoothAuthenticateDevice ( hwdParent, RemoteBthDevInfo.hRadio, &bdi, AUTHENTICATION_PASSKEY, (ULONG)wcslen(AUTHENTICATION_PASSKEY) );
	if ( presult ) *presult = result;
	if ( result == ERROR_SUCCESS ) return TRUE;
 
	return FALSE;
}
 
CString CBlueTooth::FormatBthAddress(BYTE *BthAddress)
{
	ASSERT ( BthAddress );
	BLUETOOTH_ADDRESS Address;
	ASSERT_ADDRESS ( BthAddress, LENGTH(Address.rgBytes)*sizeof(TCHAR) );
	CString csBthAddress;
	for ( int i=0; i<LENGTH(Address.rgBytes); i++ )
	{
		CString csNode;
		csNode.Format ( _T("%.2x"), BthAddress[LENGTH(Address.rgBytes)-i-1] );
		if ( !csBthAddress.IsEmpty() ) csBthAddress += ":";
		csBthAddress += csNode;
	}
	return csBthAddress;
}
 
// 枚举本地蓝牙设备,返回本地蓝牙设备数
int CBlueTooth::EnumerateLocalRadios(void)
{
	m_Ary_LocalRadioInfo.RemoveAll ();
 
	HANDLE hRadio = NULL;
	BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) };
 
	HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio );
	if ( NULL != hFind )
	{
		do
		{
			if ( hRadio )
			{
				t_LocalRadioInfo LocalRadioInfo;
				LocalRadioInfo.hRadio = hRadio;
				if ( ERROR_SUCCESS == BluetoothGetRadioInfo ( hRadio, &LocalRadioInfo.RadioInfo ) )
				{
					// 千万注意:以下代码让蓝牙虚拟传出串口能正常工作,我是花了一个通宵的时间才找到这个原因的。
					if (FALSE == BluetoothEnableDiscovery(hRadio, TRUE))
					{
						TRACE(_T("%s\n"), hwFormatMessage(GetLastError()));
					}
					if (FALSE == BluetoothEnableIncomingConnections(hRadio, TRUE))
					{
						TRACE(_T("%s\n"), hwFormatMessage(GetLastError()));
					}
 
					m_Ary_LocalRadioInfo.Add ( LocalRadioInfo );
				}
			}
 
		} while( BluetoothFindNextRadio( hFind, &hRadio ) );
		BluetoothFindRadioClose( hFind );
		return (int)m_Ary_LocalRadioInfo.GetSize ();
	}
 
	return 0;
}
 
void CBlueTooth::RemoveAllLocalRadio(void)
{
	for ( int i=0; i<m_Ary_LocalRadioInfo.GetSize(); i++ )
	{
		t_LocalRadioInfo &LocalRadioInfo = m_Ary_LocalRadioInfo.GetAt(i);
		if ( LocalRadioInfo.hRadio )
			CloseHandle ( LocalRadioInfo.hRadio );
	}
	m_Ary_LocalRadioInfo.RemoveAll ();
}
 
void CBlueTooth::RemoveAll_RemoteBthDevInfo(void)
{
	for ( int i=0; i<m_Ary_RemoteBthDevInfo.GetSize(); i++ )
	{
		t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt(i);
		if ( RemoteBthDevInfo.hRegHandle )
			BluetoothUnregisterAuthentication ( RemoteBthDevInfo.hRegHandle );
 
		if ( RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para )
			delete RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para;
 
	}
	m_Ary_RemoteBthDevInfo.RemoveAll ();
}
 
int CBlueTooth::Test(void)
{
	
	return 0;
}

以下工具类包含上述其中一种搜索方法,但是提供通讯封装

GGBlueTooth.h

#pragma once
// for WSALookupServiceBegin() WSALookupServiceNext etc.
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <ws2bth.h>
// for BluetoothFindFirstDevice() BluetoothFindNextDevice() etc.
#include <bthsdpdef.h>
#include <BluetoothAPIs.h>
#pragma comment ( lib, "Irprops.lib")
#ifndef BTH_ADDR
typedef ULONGLONG BTH_ADDR;
#endif
#ifndef SAFE_DELETE
#define SAFE_DELETE(pObj) {if(pObj) delete pObj; pObj = NULL;}
#endif
#ifndef SAFE_DELETERG
#define SAFE_DELETERG(pObj) {if(pObj) delete [] pObj; pObj = NULL;}
#endif
#define RECEIVE_OVER_COMMAND	0x00001000
typedef struct _tag_BthDev_Info
{
	BTH_ADDR btAddr;
	TCHAR szAddr[32];
	TCHAR szName[128];
	_tag_BthDev_Info()
	{
		memset(this, 0, sizeof(this));
	}
}
BTHDEV_INFO;
class CGGBlueTooth
{
public:
	CGGBlueTooth();
	~CGGBlueTooth();
	BOOL StartSearchBthDev(IN DWORD dwControlFlags);
	BOOL GetNextBthDev(
		IN OUT BTHDEV_INFO *pcBthDevInfo,
		IN DWORD dwControlFlags = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE
	);
	BOOL EndSearchBthDev();
	//Socket Api
	BOOL Create(int af = AF_BTH, int type = SOCK_STREAM, int protocol = BTHPROTO_RFCOMM);
	BOOL Close();
	//If no error occurs, this function returns zero. If an error occurs, it returns SOCKET_ERROR
	int Bind(BTH_ADDR sktAddr = 0, ULONG port = BT_PORT_ANY);
	int Listen(IN int backlog);
	int GetSockName(BTH_ADDR *psktAddr, ULONG *port);
	int SetBthService(TCHAR *lpServiceName);
	int Accept(CGGBlueTooth *pcBth);
	int Connect(BTH_ADDR sktAddr, ULONG port, int nMSecond = -1);
	int Send(LPVOID lpData, int len, int flags = 0);
	int Recv(LPVOID lpData, int len, int flags = 0);
	int SendAll(LPVOID lpData, int len, int flags = 0);
	int RecvAll(LPVOID lpData, int len, int flags = 0);
private:
	void HexMac2String(BTH_ADDR dw64Addr, TCHAR *pstrMac);
private:
	HANDLE m_hLookup;
	SOCKET m_hSocket;
	SOCKADDR_BTH m_sktAddr;
};

GGBlueTooth.cpp

#include "pch.h"
#include "GGBlueTooth.h"
CGGBlueTooth::CGGBlueTooth()
	: m_hLookup(NULL)
	, m_hSocket(NULL)
{
	memset(&m_sktAddr, 0, sizeof(m_sktAddr));
	//初始化网络
	WSADATA wsd;
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)MsgBoxA("WSAStartup Error Code:%d", WSAGetLastError());
}
CGGBlueTooth::~CGGBlueTooth()
{
	EndSearchBthDev();
	Close();
	WSACleanup();
}
void CGGBlueTooth::HexMac2String(BTH_ADDR dw64Addr, TCHAR *pstrMac)
{
	BYTE *pbAddr = (BYTE*)&dw64Addr;
	_stprintf_s(pstrMac, 64, _T("%02X:%02X:%02X:%02X:%02X:%02X"), pbAddr[5], pbAddr[4], pbAddr[3],
		pbAddr[2], pbAddr[1], pbAddr[0]);
}
BOOL CGGBlueTooth::StartSearchBthDev(IN DWORD dwControlFlags)
{
	WSAQUERYSET wsaq;
	ZeroMemory(&wsaq, sizeof(wsaq));
	wsaq.dwSize = sizeof(wsaq);
	wsaq.dwNameSpace = NS_BTH;
	wsaq.lpcsaBuffer = NULL;
	DWORD flags = LUP_RETURN_NAME | LUP_CONTAINERS | LUP_RETURN_ADDR | LUP_FLUSHCACHE | LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE;
	if (ERROR_SUCCESS != WSALookupServiceBegin(&wsaq, LUP_CONTAINERS, &m_hLookup))
	{
		MsgBoxA("WSALookupServiceBegin failed %d\r\n", GetLastError());
		return FALSE;
	}
	return TRUE;
}
//用 Socket 函数搜索附近的蓝牙设备,成功时返回设备数,否则返回 - 1
BOOL CGGBlueTooth::GetNextBthDev(
	IN OUT BTHDEV_INFO *pcBthDevInfo,
	IN DWORD dwControlFlags /* = LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_FLUSHCACHE*/
)
{
	if (!m_hLookup || !pcBthDevInfo)
	{
		return FALSE;
	}
	memset(pcBthDevInfo->szAddr, 0, sizeof(pcBthDevInfo->szAddr));
	memset(pcBthDevInfo->szName, 0, sizeof(pcBthDevInfo->szName));
	union
	{
		CHAR buf[5000];
		double __unused; // ensure proper alignment
	};
	LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET)buf;
	DWORD dwSize = sizeof(buf);
	int nResult;
	ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
	pwsaResults->dwSize = sizeof(WSAQUERYSET);
	pwsaResults->dwNameSpace = NS_BTH;
	pwsaResults->lpBlob = NULL;
	nResult = WSALookupServiceNext(m_hLookup, dwControlFlags, &dwSize, pwsaResults);
	if (nResult == ERROR_SUCCESS)
	{
		pcBthDevInfo->btAddr = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
		BOOL bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
		if (bHaveName)
		{
			HexMac2String(pcBthDevInfo->btAddr, pcBthDevInfo->szAddr);
			_tcscpy_s(pcBthDevInfo->szName, pwsaResults->lpszServiceInstanceName);
		}
		return TRUE;
	}
	return FALSE;
}
BOOL CGGBlueTooth::EndSearchBthDev()
{
	if (m_hLookup)
	{
		WSALookupServiceEnd(m_hLookup);
		m_hLookup = NULL;
		return TRUE;
	}
	return FALSE;
}
///===============================
BOOL CGGBlueTooth::Create(int af/* = AF_BTH*/, int type/* = SOCK_STREAM*/, int protocol/* = BTHPROTO_RFCOMM*/)
{
	if (m_hSocket)
	{
		return FALSE;
	}
	m_hSocket = socket(af, type, protocol);
	m_sktAddr.addressFamily = af;
	m_sktAddr.serviceClassId = GUID_NULL;
	return m_hSocket == INVALID_SOCKET ? FALSE : TRUE;
}
BOOL CGGBlueTooth::Close()
{
	if (m_hSocket)
	{
		closesocket(m_hSocket);
		return TRUE;
	}
	return FALSE;
}
int CGGBlueTooth::Bind(BTH_ADDR sktAddr/* = 0*/, ULONG port/* = BT_PORT_ANY*/)
{
	m_sktAddr.btAddr = sktAddr;
	m_sktAddr.port = port;
	return bind(m_hSocket, (SOCKADDR *)&m_sktAddr, sizeof(m_sktAddr));
}
int CGGBlueTooth::Listen(IN int backlog)
{
	return listen(m_hSocket, backlog);
}
int CGGBlueTooth::GetSockName(BTH_ADDR *psktAddr, ULONG *port)
{
	int nLen = sizeof(m_sktAddr);
	int nResult = getsockname(m_hSocket, (SOCKADDR *)&m_sktAddr, &nLen);
	if (nResult == 0)
	{
		*psktAddr = m_sktAddr.btAddr;
		*port = m_sktAddr.port;
	}
	return nResult;
}
GUID OBEXFileTransferServiceClass_UUID_EX = { 0x00001106, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
int CGGBlueTooth::SetBthService(TCHAR * lpServiceName)
{
	CSADDR_INFO sockInfo;
	sockInfo.iProtocol = BTHPROTO_RFCOMM;
	sockInfo.iSocketType = SOCK_STREAM;
	sockInfo.LocalAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr;
	sockInfo.LocalAddr.iSockaddrLength = sizeof(m_sktAddr);
	sockInfo.RemoteAddr.lpSockaddr = (SOCKADDR *)&m_sktAddr;
	sockInfo.RemoteAddr.iSockaddrLength = sizeof(m_sktAddr);
	WSAQUERYSET svcInfo = { 0 };
	svcInfo.dwSize = sizeof(svcInfo);
	svcInfo.dwNameSpace = NS_BTH;
	svcInfo.lpszServiceInstanceName = lpServiceName;
	svcInfo.lpServiceClassId = &OBEXFileTransferServiceClass_UUID_EX;
	svcInfo.dwNumberOfCsAddrs = 1;
	svcInfo.lpcsaBuffer = &sockInfo;
	return WSASetService(&svcInfo, RNRSERVICE_REGISTER, 0);
}
int CGGBlueTooth::Accept(CGGBlueTooth *pcBth)
{
	SOCKADDR_BTH ca;
	int size = sizeof(ca);
	pcBth->m_hSocket = accept(m_hSocket, (SOCKADDR *)&ca, &size);
	pcBth->m_sktAddr = ca;
	return pcBth->m_hSocket == INVALID_SOCKET ? SOCKET_ERROR : 0;
}
int CGGBlueTooth::Connect(BTH_ADDR sktAddr, ULONG port, int nMSecond/* = -1*/)
{
	SOCKADDR_BTH sa = { 0 };
	sa.addressFamily = AF_BTH;
	sa.btAddr = sktAddr;
	sa.port = port;
	if (nMSecond == -1)
	{
		return connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH));
	}
	ULONG non_blocking = 1;
	ULONG blocking = 0;
	int nResult = ioctlsocket(m_hSocket, FIONBIO, &non_blocking);
	if (nResult == SOCKET_ERROR)
	{
		return nResult;
	}
	nResult = SOCKET_ERROR;
	if (connect(m_hSocket, (LPSOCKADDR)&sa, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR)
	{
		struct timeval tv;
		fd_set writefds;
		// 设置连接超时时间
		tv.tv_sec = nMSecond / 1000; // 秒数
		tv.tv_usec = nMSecond % 1000; // 毫秒
		FD_ZERO(&writefds);
		FD_SET(m_hSocket, &writefds);
		nResult = select((int)m_hSocket + 1, NULL, &writefds, NULL, &tv);
		if (nResult > 0)
		{
			if (FD_ISSET(m_hSocket, &writefds))
			{
				int error = 0;
				int len = sizeof(error);
				//下面的一句一定要,主要针对防火墙 
				if (!(getsockopt(m_hSocket, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0 || error != 0))
				{
					nResult = 0;
				}
			}
		}
		else if (nResult == 0)
		{
			nResult = -2;
		}
	}
	if (ioctlsocket(m_hSocket, FIONBIO, &blocking) == SOCKET_ERROR)
	{
		nResult = SOCKET_ERROR;
	}
	return nResult;
}
int CGGBlueTooth::Send(LPVOID lpData, int len, int flags/* = 0*/)
{
	return send(m_hSocket, (char *)lpData, len, flags);
}
int CGGBlueTooth::Recv(LPVOID lpData, int len, int flags/* = 0*/)
{
	return recv(m_hSocket, (char *)lpData, len, flags);
}
int CGGBlueTooth::SendAll(LPVOID lpData, int len, int flags/* = 0*/)
{
	int nCount = send(m_hSocket, (char *)lpData, len, flags);
	if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
	{
		return SOCKET_ERROR;
	}
	int nCommand = 0;
	nCount = recv(m_hSocket, (char *)&nCommand, 4, flags);
	if (nCount != 4 || nCommand != RECEIVE_OVER_COMMAND)
	{
		return SOCKET_ERROR;
	}
	return ERROR_SUCCESS;
}
int CGGBlueTooth::RecvAll(LPVOID lpData, int len, int flags/* = 0*/)
{
	int nCount = -1, nCurRecv = 0, nMaxRead = 32 * 1024;
	while (nCurRecv < len)
	{
		if (len - nCurRecv < nMaxRead)
		{
			nMaxRead = len - nCurRecv;
		}
		nCount = recv(m_hSocket, (char *)lpData + nCurRecv, nMaxRead, flags);
		if (nCount == SOCKET_ERROR)
		{
			if (WSAGetLastError() == WSAEWOULDBLOCK)
			{
				Sleep(1);
				continue;
			}
			else
			{
				return SOCKET_ERROR;
			}
		}
		nCurRecv += nCount;
	}
	int nCommand = RECEIVE_OVER_COMMAND;
	nCount = send(m_hSocket, (char *)&nCommand, 4, flags);
	if (nCount == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
	{
		return SOCKET_ERROR;
	}
	return ERROR_SUCCESS;
}

window 下蓝牙开发文章摘录

需要先包含几个头文件

#include <afxsock.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
#pragma comment(lib,"Irprops.lib")
#include <string>
using namespace std;
ULONGLONG g_ulRemoteAddr = 0;
WCHAR strGUID[]=L"00001101-0000-1000-8000-00805f9b34fb";
CString g_strRecv = _T("");
SOCKET g_socketClient = INVALID_SOCKET;
CString g_strBthName=_T("");
BOOL g_bWaitRecvData=TRUE;
// CBlueToothTestDlg dialog
CBlueToothTestDlg::CBlueToothTestDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CBlueToothTestDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_bTestFinish = TRUE;
}
void CBlueToothTestDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT_SHOW, m_editShow);
    DDX_Control(pDX, IDC_EDIT_INPUT, m_editInput);
    DDX_Control(pDX, IDC_BUTTON_SEND, m_btnSend);
    DDX_Control(pDX, IDC_BTN_OPEN, m_btnOpen);
    DDX_Control(pDX, IDC_BTN_CLOSE, m_btnClose);
    DDX_Control(pDX, IDC_CHECK_REPEATSEND, m_CheckRepeat);
}
BEGIN_MESSAGE_MAP(CBlueToothTestDlg, CDialog)
    //}}AFX_MSG_MAP
    ON_BN_CLICKED(IDC_BUTTON_SEND, &CBlueToothTestDlg::OnBnClickedButtonSend)
    ON_MESSAGE(WM_BLUETOOTH_MSG, &CBlueToothTestDlg::OnBlueToothMsg)
    ON_BN_CLICKED(IDC_BTN_OPEN, &CBlueToothTestDlg::OnBnClickedBtnOpen)
    ON_BN_CLICKED(IDC_BTN_CLOSE, &CBlueToothTestDlg::OnBnClickedBtnClose)
    ON_WM_TIMER()
END_MESSAGE_MAP()
// CBlueToothTestDlg message handlers
CString string2CString(string strSrc)
{
    CString strTarge = _T("");
    TCHAR *pTemp = new TCHAR[strSrc.size() + 1];
    if (NULL == pTemp)
    {
        return strTarge;
    }
    MultiByteToWideChar(0,
        0,
        strSrc.c_str(),
        -1,
        pTemp,
        strSrc.size() + 1
        );   
    strTarge = pTemp;
    if (NULL != pTemp)  
    {
        delete []pTemp;
        pTemp = NULL; 
    }
    return strTarge;
}
CString TranslateErrorCode ( DWORD dwErrorCode )
{
    CString csError;
    LPVOID pv;
    FormatMessage (
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dwErrorCode,
        MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
        (LPTSTR)&pv,
        0,
        NULL);
    if(pv)
    {
        csError = (LPCTSTR)pv;
        LocalFree ( pv );
    }
    CString strCode = _T("");
    strCode.Format(_T("%ld"),dwErrorCode);
    csError = strCode + _T(" : ") + csError;
    return csError;
}
int GetGUID(WCHAR *psz, GUID *pGUID)
{
    int data1, data2, data3;
    int data4[8];
    if (11 ==  swscanf(psz, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
        &data1, &data2, &data3,
        &data4[0], &data4[1], &data4[2], &data4[3], 
        &data4[4], &data4[5], &data4[6], &data4[7])) {
            pGUID->Data1 = data1;
            pGUID->Data2 = data2 & 0xffff;
            pGUID->Data3 = data3 & 0xffff;
            for (int i = 0 ; i < 8 ; ++i)
                pGUID->Data4[i] = data4[i] & 0xff;
            return 0;
    }
    return -1;
}
int ReadBthSeqFile(CString strTempName)//读取序列号文件数据
{
    strTempName = _T("bluetoothName.txt");
    CStdioFile tempFile;
    BOOL bRet = tempFile.Open(strTempName, CFile::modeReadWrite);
    if (!bRet)
    {        
        return -1;
    }
    CString strReadLine=_T("");
    int tempLength = 0;
    while (1)
    {
        tempFile.ReadString(strReadLine);
        tempLength += strReadLine.GetLength()+1;
        if (strReadLine.GetLength() == 0)
            break;
        //AfxMessageBox(strReadLine);
        g_strBthName = strReadLine;
    }
    tempFile.Close();
    return 0;
}
int FindTargetBlueTooth()
{
    int iFindRet = 0;
    WSAQUERYSET wsaq;
    HANDLE      hLookup =   NULL;
    union
    {
        CHAR buf[5000];
        double __unused; // ensure proper alignment
    };
    LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
    DWORD dwSize = sizeof(buf);
    memset(&wsaq,0,sizeof(wsaq));
    wsaq.dwSize = sizeof(wsaq);
    wsaq.dwNameSpace = NS_BTH;
    wsaq.lpcsaBuffer = NULL;
    if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup))
    {
        return 0;
    }
    ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
    pwsaResults->dwSize = sizeof(WSAQUERYSET);
    pwsaResults->dwNameSpace = NS_BTH;
    pwsaResults->lpBlob = NULL;
    BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
    while (ERROR_SUCCESS == WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
    {
//      ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
        ULONGLONG ulAddr =   ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
        CString strName  =   pwsaResults->lpszServiceInstanceName;
        if(strName == /*_T("HWAPP")*/g_strBthName)
        {
            g_ulRemoteAddr = ulAddr;
            //获取其它信息
            memset(&bdi,0,sizeof(BLUETOOTH_DEVICE_INFO));
            bdi.Address.ullLong = ulAddr;
            bdi.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);//important
            DWORD dwGetInfo = BluetoothGetDeviceInfo(NULL,&bdi);
            if(ERROR_SUCCESS == dwGetInfo)
            {
                //类型
                ULONG ulType = bdi.ulClassofDevice;//7936
                //被记住                
                BOOL bRemember = bdi.fRemembered;
                //已配对
                BOOL bPaired = bdi.fAuthenticated;
                //已连接
                BOOL bConnected = bdi.fConnected;
                if(bPaired)
                    iFindRet = 1;
                else
                    iFindRet = 2;
                break;
            }
            else
            {
                AfxMessageBox(TranslateErrorCode(dwGetInfo));
            }
        }
    }
    WSALookupServiceEnd(hLookup);
    return iFindRet;
}
UINT ScanBlueToothDeviceProc(LPVOID lpParam)
{
    int iScanRet = FindTargetBlueTooth();//0表示没有发现,1表示发现且配对,2表示发现但未配对
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;
    pDlg->PostMessage(WM_BLUETOOTH_MSG,1,iScanRet);
    return 0;
}
UINT RecvMsgProc(LPVOID lpParam)
{
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;
    char pbuf[MAX_MESSAGE_SIZE] = {0};
    while(1)
    {
        memset(pbuf,0,MAX_MESSAGE_SIZE);
        int cbBytesRecd = recv (g_socketClient, pbuf, MAX_MESSAGE_SIZE, 0);
        if (cbBytesRecd == SOCKET_ERROR) 
        {
            pDlg->PostMessage(WM_BLUETOOTH_MSG,2,0);
            return WSAGetLastError();
        }
        else if(cbBytesRecd > 0)
        {
            string sRecv = pbuf;
            g_strRecv = string2CString(sRecv);
            pDlg->PostMessage(WM_BLUETOOTH_MSG,2,1);
            g_bWaitRecvData = TRUE;
        }
    }
    return 0;
}
UINT ConnectDeviceProc(LPVOID lpParam)
{
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;
    g_socketClient = socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if (g_socketClient == INVALID_SOCKET) 
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,1);
        return 0;
    }
    GUID ServerGuid;
    if(GetGUID(strGUID, &ServerGuid))
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,2);
        g_socketClient = INVALID_SOCKET;
        return 0;
    }
    SOCKADDR_BTH sa;
    memset (&sa, 0, sizeof(sa));
    sa.addressFamily = AF_BTH;
    sa.port = 6001;
    sa.serviceClassId = ServerGuid;
    sa.btAddr = g_ulRemoteAddr;
    Sleep(200);
    int iConnect = 0 ;
    for (iConnect = 0 ; iConnect < 3 ; iConnect ++)//尝试连接3次
    {
        if (connect (g_socketClient, (SOCKADDR *)&sa, sizeof(sa)) == SOCKET_ERROR) 
        {
            DWORD dwError = GetLastError();
            if(dwError == WSAETIMEDOUT)
            {
                pDlg->PostMessage(WM_BLUETOOTH_MSG,4,iConnect);
                Sleep(200);
                continue;
            }
            g_socketClient = INVALID_SOCKET;
            AfxMessageBox(TranslateErrorCode(dwError));
            pDlg->PostMessage(WM_BLUETOOTH_MSG,3,3);//其他错误
            return 0;
        }
        else
            break;
    }
    if(iConnect == 3)//超时错误
    {
        g_socketClient = INVALID_SOCKET;
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,4);
    }
    else
        pDlg->PostMessage(WM_BLUETOOTH_MSG,3,0);
    return 0;
}
UINT TestConnectProc(LPVOID lpParam)
{
    CBlueToothTestDlg* pDlg = (CBlueToothTestDlg*)lpParam;
    int iFindBlueTooth = FindTargetBlueTooth();
    if(iFindBlueTooth != 1)
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,5);
        return 0;
    }
    SOCKET sock = socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if (sock == INVALID_SOCKET) 
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,1);
        return 0;
    }
    GUID ServerGuid;
    if(GetGUID(strGUID, &ServerGuid))
    {
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,2);
        return 0;
    }
    SOCKADDR_BTH sa;
    memset (&sa, 0, sizeof(sa));
    sa.addressFamily = AF_BTH;
    sa.port = 5001;
    sa.serviceClassId = ServerGuid;
    sa.btAddr = g_ulRemoteAddr;
    Sleep(200);
    int iConnect = 0 ;
    for (iConnect = 0 ; iConnect < 6 ; iConnect ++)//尝试连接6次
    {
        if (connect (sock, (SOCKADDR *)&sa, sizeof(sa)) == SOCKET_ERROR) 
        {
            DWORD dwError = GetLastError();
            if(dwError == WSAETIMEDOUT)
            {
                pDlg->PostMessage(WM_BLUETOOTH_MSG,6,iConnect);
                Sleep(200);
                continue;
            }
            AfxMessageBox(TranslateErrorCode(dwError));
            pDlg->PostMessage(WM_BLUETOOTH_MSG,5,3);//其他错误
            return 0;
        }
        else
            break;
    }
    if(iConnect == 6)//超时错误
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,4);
    else
    {
        closesocket(sock);
        pDlg->PostMessage(WM_BLUETOOTH_MSG,5,0);//能连接上
    }
    return 0;
}
BOOL CBlueToothTestDlg::OnInitDialog()
{
    ......
    // TODO: Add extra initialization here
    m_editInput.EnableWindow(FALSE);
    m_btnSend.EnableWindow(FALSE);
    m_btnOpen.EnableWindow(FALSE);
    m_btnClose.EnableWindow(FALSE);
    SetDlgItemText(IDC_STATIC_TIP,_T("正在检测蓝牙是否连接,请稍候..."));
//  SetTimer(8,5000,NULL);
    CString str=_T("");
    ReadBthSeqFile(str);
    AfxBeginThread(ScanBlueToothDeviceProc,this);
    return TRUE;  // return TRUE  unless you set the focus to a control
}
string CBlueToothTestDlg::CString2string(CString str)
{
    string strTarge = "";
    int nLength = str.GetLength();
    int nBytes = WideCharToMultiByte(0,0,str,nLength,NULL,0,NULL,NULL);
    char* VoicePath = new char[ nBytes + 1];
    memset(VoicePath,0,nLength + 1);
    WideCharToMultiByte(0, 0, str, nLength, VoicePath, nBytes, NULL, NULL); 
    VoicePath[nBytes] = 0;
    strTarge = VoicePath;
    return strTarge;
}
void CBlueToothTestDlg::OnBnClickedButtonSend()
{
    // TODO: Add your control notification handler code here
    CString strInput = _T("");
    GetDlgItemText(IDC_EDIT_INPUT,strInput);
    BYTE m_pucPackBuffer[] = {0xd1, 0xee, 0x16, 0x00, 0xe9, 0xff, 0xf7, 0x01, 0x09, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x43, 0x00, 0x00, 0x80, 0x3f, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x44, 0x60, 0x02};
    UINT uiIsCheck = m_CheckRepeat.GetState();
    if (uiIsCheck)///主要是用于测试蓝牙盒子的通讯能力
    {
        strInput=m_pucPackBuffer;
        while (1)
        {
            if (g_bWaitRecvData)
            {
                int iSend = send (g_socketClient, (const char *)m_pucPackBuffer, 31, 0);
                DWORD dwError = GetLastError();
                if((iSend == 31) && (dwError == 0))
                    AppendShowMsg(strInput, 1);
                else
                    AfxMessageBox(strInput+TranslateErrorCode(dwError));
                g_bWaitRecvData = FALSE;
            }
        }       
    }
    else
    {
        if(strInput.GetLength())
        {
            string strToSend = CString2string(strInput);
            int iSend = send (g_socketClient, strToSend.c_str(), strToSend.length(), 0);
            DWORD dwError = GetLastError();
            if((iSend == strInput.GetLength()) && (dwError == 0))
                AppendShowMsg(strInput,1);
            else
                AfxMessageBox(strInput+TranslateErrorCode(dwError));
        }
    }
}
LRESULT CBlueToothTestDlg::OnBlueToothMsg(WPARAM wParam,LPARAM lParam)
{
    int iMsgType = (int)wParam;
    int iMsgValue = (int)lParam;
    if(iMsgType == 1)//扫描蓝牙,结果0表示没有发现,1表示发现且配对,2表示发现但未配对
    {
        switch (iMsgValue)
        {
        case 0:
            SetDlgItemText(IDC_STATIC_TIP,_T("未发现目标蓝牙设备!"));            break;
        case 1:
            SetDlgItemText(IDC_STATIC_TIP,_T("已发现目标蓝牙设备,点击Connect按钮来连接蓝牙"));
            m_btnOpen.EnableWindow(TRUE);
            break;
        case 2:
            SetDlgItemText(IDC_STATIC_TIP,_T("已发现目标蓝牙设备,但未连接,请手动连接后再试"));           break;
        default:break;
        }   
    }
    else if(iMsgType == 2)//接收数据
    {
        if(iMsgValue == 0)
            SetDlgItemText(IDC_STATIC_TIP,_T("接收消息出错,接收线程退出,可能是连接已断开"));
        else if(iMsgValue == 1)
            AppendShowMsg(g_strRecv,2);
    }
    else if(iMsgType == 3)//连接蓝牙设备
    {
        switch (iMsgValue)
        {
        case 0:
            SetDlgItemText(IDC_STATIC_TIP,_T("初始化通信完成,现在可以收发数据"));
            SetDlgItemText(IDC_EDIT_INPUT,_T("FoxwellGT80"));
            m_editInput.EnableWindow(TRUE);
            m_btnSend.EnableWindow(TRUE);
            AfxBeginThread(RecvMsgProc,this);
            m_btnOpen.EnableWindow(FALSE);
            m_btnClose.EnableWindow(TRUE);
            break;
        case 1:
            SetDlgItemText(IDC_STATIC_TIP,_T("初始化套接字失败!"));         break;
        case 2:
            SetDlgItemText(IDC_STATIC_TIP,_T("获取GUID失败!"));         break;
        case 3:
            SetDlgItemText(IDC_STATIC_TIP,_T("连接目标蓝牙设备失败!"));           break;
        case 4:
            SetDlgItemText(IDC_STATIC_TIP,_T("连接目标蓝牙设备失败!")+TranslateErrorCode(WSAETIMEDOUT));          break;
        default:            break;
        }   
    }
    else if(iMsgType == 4)//超时重试提示
    {
        CString strTimeOut = _T("");
        strTimeOut.Format(_T("连接超时,重试中...%d"),iMsgValue+1);
        SetDlgItemText(IDC_STATIC_TIP,strTimeOut);
    }
    else if(iMsgType == 5)//测试连接蓝牙设备
    {
        m_bTestFinish = TRUE;
        CTime tm = CTime::GetCurrentTime();
        CString strTime = _T("");
        strTime.Format(_T("%.2d%.2d%.2d"),tm.GetHour(),tm.GetMinute(),tm.GetSecond());
        switch (iMsgValue)
        {
        case 0:
            SetWindowText(_T("蓝牙检测:已连接") + strTime);            break;
        case 1:
            SetWindowText(_T("蓝牙检测:初始化套接字失败") + strTime);           break;
        case 2:
            SetWindowText(_T("蓝牙检测:获取GUID失败!") + strTime);          break;
        case 3:
            SetWindowText(_T("蓝牙检测:其他错误!") + strTime);          break;
        case 4:
            SetWindowText(_T("蓝牙检测:连接超时,可能已断开") + strTime);         break;
        case 5:
            SetWindowText(_T("蓝牙检测:未连接") + strTime);            break;
        default:break;
        }           
    }
    else if(iMsgType == 6)//测试连接超时重试提示
    {
        CString strTimeOut = _T("");
        strTimeOut.Format(_T("蓝牙检测:重试中...%d"),iMsgValue+1);
        SetWindowText(strTimeOut);
    }
    return 0;
}
void CBlueToothTestDlg::AppendShowMsg(CString strNewMsg, int iType)
{
    if(iType == 1)
        strNewMsg = _T("Req: ") + strNewMsg;
    else if(iType == 2)
        strNewMsg = _T("Ans: ") + strNewMsg;
    else if(iType == 3)
        strNewMsg = _T("Sys: ") + strNewMsg;
    CString strHave = _T("");
    GetDlgItemText(IDC_EDIT_SHOW,strHave);
    if(strHave.GetLength())
        strHave = strHave + _T("\r\n") + strNewMsg;
    else
        strHave = strNewMsg;
    SetDlgItemText(IDC_EDIT_SHOW,strHave);
    m_editShow.PostMessage(WM_VSCROLL,SB_BOTTOM,0);
    if(iType == 2)//自动发送
    {
        CString strInput = strNewMsg;
        if(strInput.GetLength())
        {
            strInput = _T("FOXWELL_") + strInput;
            string strToSend = CString2string(strInput);
            int iSend = send (g_socketClient, strToSend.c_str(), strToSend.length(), 0);
            DWORD dwError = GetLastError();
            if((iSend == strInput.GetLength()) && (dwError == 0))
            {
                AppendShowMsg(strInput,1);
            }
            else
                AfxMessageBox(TranslateErrorCode(dwError));
        }
    }
}
/******************************************************************************\
获取字符串形式的蓝牙地址
蓝牙地址 BLUETOOTH_ADDRESS 定义如下
union
{
    BTH_ADDR ullLong;
    BYTE     rgBytes[6];
};
BTH_ADDR 是一个 64 位的整数
假定蓝牙地址为 12:34:56:78:9A:BC 则 ullLong 为 0x0000123456789ABC
rgBytes 的内容为 BC 9A 78 56 34 12
\******************************************************************************/
CString CBlueToothTestDlg::AddrToStr(const void*pAddr)
{
    CString sAddress;
    if(pAddr)
    {
        BLUETOOTH_ADDRESS Address;
        int         nBytes  =   sizeof(Address.rgBytes);
        TCHAR       szByte[8];
        const BYTE* pByte   =   (const BYTE*)pAddr + (nBytes - 1);
        for(int i = 0;i < nBytes;i++)
        {
            _stprintf(szByte,_T(":%02x"),*pByte--);
            sAddress   +=   i ? szByte : (szByte + 1);
        }
    }
    return sAddress;
}
void CBlueToothTestDlg::OnBnClickedBtnOpen()
{
    // TODO: Add your control notification handler code here
    SetDlgItemText(IDC_STATIC_TIP,_T("正在初始化通信,请稍候..."));
    AfxBeginThread(ConnectDeviceProc,this);
}
void CBlueToothTestDlg::OnBnClickedBtnClose()
{
    // TODO: Add your control notification handler code here
    m_btnOpen.EnableWindow(TRUE);
    m_btnClose.EnableWindow(FALSE);
    m_editInput.EnableWindow(FALSE);
    m_btnSend.EnableWindow(FALSE);
    closesocket(g_socketClient);
    g_socketClient = INVALID_SOCKET;
}
void CBlueToothTestDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    if(m_bTestFinish && (g_ulRemoteAddr != 0))
    {
        m_bTestFinish = FALSE;
        SetWindowText(_T("蓝牙检测:开始检测"));
        AfxBeginThread(TestConnectProc,this);
    }
    CDialog::OnTimer(nIDEvent);
}


本文链接:https://www.it72.com/12684.htm

推荐阅读
最新回复 (0)
返回