⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 headsetctl.cpp

📁 CE下串口复用程序
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

#include <windows.h>
#include <commctrl.h>
#include "resource.h"
#include "utils.h"
#include "btaudiogw.h"

#define WM_HS_ANSWERED	(WM_USER + 105)
#define WM_HS_NOANSWER	(WM_USER + 106)


void OnStartHeadset(HWND hwndDlg);
void OnStopHeadset(HWND hwndDlg);


// Global data
HINSTANCE 	g_hAudioGW;
BOOL		g_fActiveConnection;
DWORD		g_dwSpkVolCache = -1;
DWORD		g_dwMicVolCache = -1;


// Audio gateway functions
PFN_BthInitializeAudioGateway		g_pfnInitAG;
PFN_BthUninitializeAudioGateway		g_pfnUninitAG;
PFN_BthCreateHeadsetConnection		g_pfnCreateHeadsetConnection;
PFN_BthCloseHeadsetConnection		g_pfnCloseHeadsetConnection;
PFN_BthRingHeadset					g_pfnRingHeadset;
PFN_BthStopRingingHeadset			g_pfnStopRingingHeadset;
PFN_BthSetHeadsetEvents				g_pfnSetHeadsetEvents;
PFN_BthSetHeadsetSpkVolume			g_pfnSetSpkVolume;
PFN_BthGetHeadsetSpkVolume			g_pfnGetSpkVolume;
PFN_BthSetHeadsetMicVolume			g_pfnSetMicVolume;
PFN_BthGetHeadsetMicVolume			g_pfnGetMicVolume;

// Audio gateway events
HANDLE	g_hHSCloseEvent;
HANDLE	g_hHSSpkVolEvent;
HANDLE	g_hHSMicVolEvent;



// Load the audio gateway dll and get proc addresses
DWORD LoadAudioGW(void)
{
	DWORD dwRetVal = ERROR_SUCCESS;
	
	g_hAudioGW = LoadLibrary(_T("btaudiogw.dll"));
	if (! g_hAudioGW) {
		OutputMessage(_T("BTHeadset: ***********************************\r\nBTAUDIOGW: ERROR: Could not load btaudiogw.dll!\r\nBTAUDIOGW: ***********************************"));
		dwRetVal = GetLastError();
		goto exit;
	}

	g_pfnInitAG = (PFN_BthInitializeAudioGateway) GetProcAddress(g_hAudioGW, _T("BthInitializeAudioGateway"));
	g_pfnUninitAG = (PFN_BthUninitializeAudioGateway) GetProcAddress(g_hAudioGW, _T("BthUninitializeAudioGateway"));
	g_pfnCreateHeadsetConnection = (PFN_BthCreateHeadsetConnection) GetProcAddress(g_hAudioGW, _T("BthCreateHeadsetConnection"));
	g_pfnCloseHeadsetConnection = (PFN_BthCloseHeadsetConnection) GetProcAddress(g_hAudioGW, _T("BthCloseHeadsetConnection"));
	g_pfnRingHeadset = (PFN_BthRingHeadset) GetProcAddress(g_hAudioGW, _T("BthRingHeadset"));
	g_pfnStopRingingHeadset = (PFN_BthStopRingingHeadset) GetProcAddress(g_hAudioGW, _T("BthStopRingingHeadset"));
	g_pfnSetHeadsetEvents = (PFN_BthSetHeadsetEvents) GetProcAddress(g_hAudioGW, _T("BthSetHeadsetEvents"));
	g_pfnSetSpkVolume = (PFN_BthSetHeadsetSpkVolume) GetProcAddress(g_hAudioGW, _T("BthSetHeadsetSpkVolume"));
	g_pfnGetSpkVolume = (PFN_BthGetHeadsetSpkVolume) GetProcAddress(g_hAudioGW, _T("BthGetHeadsetSpkVolume"));
	g_pfnSetMicVolume = (PFN_BthSetHeadsetMicVolume) GetProcAddress(g_hAudioGW, _T("BthSetHeadsetMicVolume"));
	g_pfnGetMicVolume = (PFN_BthGetHeadsetMicVolume) GetProcAddress(g_hAudioGW, _T("BthGetHeadsetMicVolume"));
	
	if ((! g_pfnInitAG) || (! g_pfnUninitAG) || (! g_pfnCreateHeadsetConnection) || (! g_pfnCreateHeadsetConnection) || (! g_pfnRingHeadset) || 
		(! g_pfnStopRingingHeadset) || (! g_pfnSetHeadsetEvents) || (! g_pfnSetSpkVolume) || (! g_pfnGetSpkVolume) || 
		(! g_pfnSetMicVolume) || (! g_pfnGetMicVolume)) {
		dwRetVal = GetLastError();
		OutputMessage(_T("BTHeadset: Error getting proc address of one or more Audio Gateway functions: %d"), dwRetVal);
		goto exit;
	}

	dwRetVal = g_pfnInitAG();
	if (dwRetVal != ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Error initializing Audio Gateway"));
		goto exit;
	}

	g_hHSCloseEvent 	= CreateEvent(NULL, FALSE, FALSE, NULL);
	g_hHSSpkVolEvent	= CreateEvent(NULL, FALSE, FALSE, NULL);
	g_hHSMicVolEvent	= CreateEvent(NULL, FALSE, FALSE, NULL);
	if ((! g_hHSCloseEvent) || (! g_hHSCloseEvent) || (! g_hHSCloseEvent)) {
		dwRetVal = GetLastError();
		OutputMessage(_T("BTHeadset: Error creating headset events: %d"), dwRetVal);
		g_pfnUninitAG();
		goto exit;
	}
	
	dwRetVal = g_pfnSetHeadsetEvents(g_hHSCloseEvent, g_hHSSpkVolEvent, g_hHSMicVolEvent);
	if (dwRetVal != ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Error setting headset events in Audio Gateway: %d"), GetLastError());
		g_pfnUninitAG();
		goto exit;
	}

exit:
	if (dwRetVal != ERROR_SUCCESS) {
		if (g_hAudioGW) {			
			FreeLibrary(g_hAudioGW);
		}
		if (! g_hHSCloseEvent) {
			CloseHandle(g_hHSCloseEvent);
		}
		if (! g_hHSSpkVolEvent) {
			CloseHandle(g_hHSSpkVolEvent);
		}
		if (! g_hHSMicVolEvent) {
			CloseHandle(g_hHSMicVolEvent);
		}
	}
	
	return dwRetVal;
}



// Unload the audio gateway dll
void UnloadAudioGW(void)
{
	if (g_pfnSetHeadsetEvents(NULL, NULL, NULL) != ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Error unregistering headset events"));
	}

	if (g_pfnUninitAG() != ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Error uninitializing audio gateway"));
	}
	
	FreeLibrary(g_hAudioGW);
	g_hAudioGW = NULL;
}



// Called when main dialog is initialized
void OnInitDialog(HWND hwndDlg)
{
	HWND hWndSpkVol;
	HWND hWndMicVol;
	
	hWndSpkVol = GetDlgItem(hwndDlg, IDC_SPKVOL);
	hWndMicVol = GetDlgItem(hwndDlg, IDC_MICVOL);

	if ((! hWndSpkVol) || (! hWndMicVol)) {
		OutputMessage(_T("BTHeadset: Error - Could not get trackbar controls: %d"), GetLastError());
		goto exit;
	}

	// Set range for volume on trackbars
	SendMessage(hWndSpkVol, TBM_SETRANGE, FALSE, MAKELONG(0, 15));
	SendMessage(hWndMicVol, TBM_SETRANGE, FALSE, MAKELONG(0, 15));

exit:
	return;
}



// Thread which calls the headset and wait for a response
DWORD WINAPI CallHeadsetThread(LPVOID pv)
{
	HWND hwndDlg = (HWND) pv;
	
	if (g_pfnRingHeadset() == ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Started headset"));
		PostMessage(hwndDlg, WM_HS_ANSWERED, 0, 0);
	}
	else {
		OutputMessage(_T("BTHeadset: Error starting headset."));
		PostMessage(hwndDlg, WM_HS_NOANSWER, 0, 0);
		MessageBox(hwndDlg, 
			_T("An error occured trying to call the headset device."), 
			_T("Audio Gateway"), 
			MB_ICONEXCLAMATION | MB_OK);

		OnStopHeadset(hwndDlg); // Close the connection		
	}

	SetCursor(LoadCursor(NULL, IDC_ARROW));
	return 0;
}



// Update the status message
DWORD UpdateStatusMessage(HWND hwndDlg, TCHAR* szMessage)
{
	DWORD dwRetVal = ERROR_SUCCESS;
	HWND hwndStatus;

	hwndStatus = GetDlgItem(hwndDlg, IDC_STATUS);
	if (! hwndStatus) {
		OutputMessage(_T("BTHeadset: Error - Could not update status message"));
		dwRetVal = GetLastError();
		goto exit;
	}

	SetWindowText(hwndStatus, szMessage);

exit:
	return dwRetVal;
}



// Headset Button was pressed to close ACL connection.
void OnHeadsetClose(HWND hwndDlg)
{
	HWND hwndStartStop = GetDlgItem(hwndDlg, IDC_STARTSTOP);
	g_fActiveConnection = FALSE;
	SetWindowText(hwndStartStop, _T("Start"));
	UpdateStatusMessage(hwndDlg, _T("Not Connected"));
}



// Update the speaker volume with audio gateway
DWORD UpdateSpeakerVolume(HWND hwndDlg)
{
	DWORD 	dwRetVal = ERROR_SUCCESS;
	HWND	hwndSpkVol;

	dwRetVal = g_pfnGetSpkVolume((USHORT*)&g_dwSpkVolCache);
	if (dwRetVal != ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Error updating speaker volume: %d"), dwRetVal);
		goto exit;
	}

	hwndSpkVol = GetDlgItem(hwndDlg, IDC_SPKVOL);
	SendMessage(hwndSpkVol, TBM_SETPOS, TRUE, 15 - g_dwSpkVolCache);

exit:
	return dwRetVal;
}



// Update the mic volume with audio gateway
DWORD UpdateMicVolume(HWND hwndDlg)
{
	DWORD 	dwRetVal = ERROR_SUCCESS;
	HWND	hwndMicVol;

	dwRetVal = g_pfnGetMicVolume((USHORT*)&g_dwMicVolCache);
	if (dwRetVal != ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Error updating mic volume: %d"), dwRetVal);
		goto exit;
	}

	hwndMicVol = GetDlgItem(hwndDlg, IDC_MICVOL);
	SendMessage(hwndMicVol, TBM_SETPOS, TRUE, 15 - g_dwMicVolCache);

exit:
	return dwRetVal;
}



// Speaker volume was adjusted on device
void OnSpeakerVolume(HWND hwndDlg)
{
	HWND 	hwndSpkVol;
	DWORD 	dwPos = 0;

	hwndSpkVol = GetDlgItem(hwndDlg, IDC_SPKVOL);
	dwPos = 15 - SendMessage(hwndSpkVol, TBM_GETPOS, 0, 0);	
	if(dwPos != g_dwSpkVolCache) {
		if (g_pfnSetSpkVolume((USHORT)(dwPos)) != ERROR_SUCCESS) {
			OutputMessage(_T("Error setting speaker volume: %d"), GetLastError());
		}
		else {
			g_dwSpkVolCache = dwPos;
		}
	}
}



// Mic Volume was adjusted on device
void OnMicVolume(HWND hwndDlg)
{
	HWND 	hwndMicVol;
	DWORD 	dwPos = 0;

	hwndMicVol = GetDlgItem(hwndDlg, IDC_MICVOL);
	dwPos = 15 - SendMessage(hwndMicVol, TBM_GETPOS, 0, 0);
	if (dwPos != g_dwMicVolCache) {
		if (g_pfnSetMicVolume((USHORT)(dwPos)) != ERROR_SUCCESS) {
			OutputMessage(_T("Error setting mic volume: %d"), GetLastError());
		}
		else {
			g_dwMicVolCache = dwPos;
		}
	}
}



// User has clicked Start
void OnStartHeadset(HWND hwndDlg)
{
	DWORD 	dwRetVal;
	HWND	hwndStartStop;

	hwndStartStop = GetDlgItem(hwndDlg, IDC_STARTSTOP);

	SetCursor(LoadCursor(NULL, IDC_WAIT));
	SetWindowText(hwndStartStop, _T("Starting..."));

	// Establish SCO Connection
	dwRetVal = g_pfnCreateHeadsetConnection(NULL);
	if (dwRetVal == ERROR_SUCCESS) {
		DWORD dwVol = 0;
		if (g_pfnGetSpkVolume((USHORT*)&dwVol) == ERROR_SUCCESS) {
			HWND hWndSpk = GetDlgItem(hwndDlg, IDC_SPKVOL);
			SendMessage(hWndSpk, TBM_SETPOS, TRUE, (15 - dwVol));
		}
		if (g_pfnGetMicVolume((USHORT*)&dwVol) == ERROR_SUCCESS) {
			HWND hWndMic = GetDlgItem(hwndDlg, IDC_MICVOL);
			SendMessage(hWndMic, TBM_SETPOS, TRUE, (15 - dwVol));
		}

		UpdateStatusMessage(hwndDlg, _T("Calling headset..."));

		HANDLE hThread = CreateThread(NULL, 0, CallHeadsetThread, (LPVOID)hwndDlg, 0, NULL);
		if (! hThread) {
			dwRetVal = GetLastError();
			OutputMessage(_T("BTHeadset: Error creating CallHeadsetThread: %d"), dwRetVal);
		}
	}
	
	if (dwRetVal == ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: ACL connection created successfully"));
		SetWindowText(hwndStartStop, _T("Stop"));
		g_fActiveConnection = TRUE;
	}
	else {
		SetCursor(LoadCursor(NULL, IDC_ARROW));
		SetWindowText(hwndStartStop, _T("Start"));
		MessageBox(hwndDlg, 
			_T("An error occured trying to connect with the headset device."), 
			_T("Audio Gateway"), 
			MB_ICONEXCLAMATION | MB_OK);
	}
}



// User has clicked Stop
void OnStopHeadset(HWND hwndDlg)
{
	DWORD 	dwRetVal;
	HWND	hwndStartStop;

	hwndStartStop = GetDlgItem(hwndDlg, IDC_STARTSTOP);
	
	SetCursor(LoadCursor(NULL, IDC_WAIT));
	SetWindowText(hwndStartStop, _T("Stopping..."));

	// Close SCO Connection
	dwRetVal = g_pfnCloseHeadsetConnection();
	SetCursor(LoadCursor(NULL, IDC_ARROW));
	
	if (dwRetVal == ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: ACL connection closed successfully"));
		SetWindowText(hwndStartStop, _T("Start"));
		g_fActiveConnection = FALSE;
		UpdateStatusMessage(hwndDlg, _T("Not Connected"));
	}
	else {
		SetWindowText(hwndStartStop, _T("Stop"));
		MessageBox(hwndDlg, 
			_T("An error occured trying to disconnect with the headset device."), 
			_T("Audio Gateway"),
			MB_ICONEXCLAMATION | MB_OK);
	}
}



// Callback function for main dialog box messages
BOOL CALLBACK MainDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	NMHDR* pnmh;
	
	switch (uMsg) {
		case WM_INITDIALOG:
			OnInitDialog(hwndDlg);
			break;

		case WM_HS_ANSWERED:
			UpdateStatusMessage(hwndDlg, _T("Connected to headset"));
			break;
			
		case WM_HS_NOANSWER:
			UpdateStatusMessage(hwndDlg, _T("No answer from headset"));
			break;
			
		case WM_NOTIFY:
			pnmh = (NMHDR*) lParam;
			if (pnmh->idFrom == IDC_SPKVOL) {
				OnSpeakerVolume(hwndDlg);
			}
			else if (pnmh->idFrom == IDC_MICVOL) {
				OnMicVolume(hwndDlg);
			}
			break;
	
		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				case IDC_STARTSTOP:
					if (g_fActiveConnection) {
						OnStopHeadset(hwndDlg);
					}
					else {
						OnStartHeadset(hwndDlg);
					}
					break;
			}
			break;

		case WM_CLOSE:
			PostQuitMessage(0);
			break;
	}
	
	return FALSE;
}
	


// Application entry point
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
	DWORD	dwRetVal;
	BOOL	fAGLoaded = FALSE;
	MSG		msg;
	HWND 	hwndDlg; 
	HANDLE	hEvents[3];

	InitCommonControls();

	dwRetVal = LoadAudioGW();
	if (dwRetVal != ERROR_SUCCESS) {
		OutputMessage(_T("BTHeadset: Failed to load Audio Gateway"));
		goto exit;
	}

	fAGLoaded = TRUE;

	hwndDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_HEADSET), NULL, MainDialogProc);
	if (! hwndDlg) {
		OutputMessage(_T("BTHeadset: Failed to create main window: 0x%08x"), GetLastError());
		goto exit;
	}

	hEvents[0] = g_hHSCloseEvent;
	hEvents[1] = g_hHSSpkVolEvent;
	hEvents[2] = g_hHSMicVolEvent;

	while (1) {
		while (PeekMessage(&msg, hwndDlg, 0, 0, PM_REMOVE)) {
			// If we got a quit, let's exit
			if (msg.message == WM_QUIT) {
                goto exit;
			}
			
			TranslateMessage(&msg);		
			DispatchMessage(&msg);
		}

		// Check if an event fired.
		dwRetVal = MsgWaitForMultipleObjects(3, hEvents, FALSE, INFINITE, QS_ALLINPUT);
		if (dwRetVal == WAIT_OBJECT_0) {
			OnHeadsetClose(hwndDlg);
		}
		else if (dwRetVal == WAIT_OBJECT_0 + 1) {
			UpdateSpeakerVolume(hwndDlg);
		}
		else if (dwRetVal == WAIT_OBJECT_0 + 2) {
			UpdateMicVolume(hwndDlg);
		}
		else if (dwRetVal == 0xFFFFFFFF) {
			OutputMessage(_T("MsgWaitForMultipleObjects failed with error %d"), GetLastError());
		}
	}

exit:	
	if (fAGLoaded) {
		UnloadAudioGW();
	}
	
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -