Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
EnumDevices.cpp
/* |
* File: EnumDevices.cpp |
* |
* Contains: Main Program. Displays a window which shows an enumeration of all Windows |
* DirectSound output devices. Buttons then allow user to choose an output device, |
* and play a movie through the selected output device. |
* |
* Version: 1.0 |
* |
* Created: 2/15/06 |
* |
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
* ("Apple") in consideration of your agreement to the following terms, and your |
* use, installation, modification or redistribution of this Apple software |
* constitutes acceptance of these terms. If you do not agree with these terms, |
* please do not use, install, modify or redistribute this Apple software. |
* |
* In consideration of your agreement to abide by the following terms, and subject |
* to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
* copyrights in this original Apple software (the "Apple Software"), to use, |
* reproduce, modify and redistribute the Apple Software, with or without |
* modifications, in source and/or binary forms; provided that if you redistribute |
* the Apple Software in its entirety and without modifications, you must retain |
* this notice and the following text and disclaimers in all such redistributions of |
* the Apple Software. Neither the name, trademarks, service marks or logos of |
* Apple Computer, Inc. may be used to endorse or promote products derived from the |
* Apple Software without specific prior written permission from Apple. Except as |
* expressly stated in this notice, no other rights or licenses, express or implied, |
* are granted by Apple herein, including but not limited to any patent rights that |
* may be infringed by your derivative works or by other works in which the Apple |
* Software may be incorporated. |
* |
* The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
* COMBINATION WITH YOUR PRODUCTS. |
* |
* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
* Copyright: Copyright © 2006 Apple Computer, Inc, All Rights Reserved |
*/ |
#include "EnumDevices.h" |
#include "QTCode.h" |
//----------------------------------------------------------------------------- |
// Function-prototypes |
//----------------------------------------------------------------------------- |
INT_PTR CALLBACK MainDialogProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ); |
HRESULT OnInitDialog( HWND hDlg ); |
INT_PTR CALLBACK DSoundEnumCallback( GUID* pGUID, TCHAR* strDesc, TCHAR* strDrvName, |
VOID* pContext ); |
HRESULT InitDirectSound( HWND hDlg ); |
HRESULT FreeDirectSound(); |
void CopySelectedSoundDeviceName( HWND hDlg, TCHAR *outCurrentSoundDeviceName); |
void CopySelectedSoundDeviceGUID( HWND hDlg, GUID* outCurrentSoundGUID); |
BOOL GetFile (TCHAR *theFileName); |
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } |
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } |
//----------------------------------------------------------------------------- |
// Global data |
//----------------------------------------------------------------------------- |
LPDIRECTSOUND g_pDS = NULL; |
Movie g_Movie = NULL; |
QTAudioContextRef g_QTAudioContextForDevice = NULL; |
boolean g_QT704Installed = false; |
static TCHAR g_MovieFileNamePath[MAX_PATH] = TEXT(""); |
static TCHAR g_MovieFileName[MAX_PATH] = TEXT(""); |
ComponentInstance g_MovieController = NULL; |
//----------------------------------------------------------------------------- |
// Name: WinMain() |
// Desc: Entry point for the application. Since we use a simple dialog for |
// user interaction we don't need to pump messages. |
//----------------------------------------------------------------------------- |
INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, |
INT nCmdShow ) |
{ |
// Initialize COM |
CoInitialize( NULL ); |
// Initialize QuickTime |
InitializeQTML(0); |
require(EnterMovies() == noErr, FAILQTINIT); |
g_QT704Installed = QT_QT704OrBetterInstalled(); |
g_Movie = NULL; |
// Display the main dialog box. |
DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDialogProc ); |
FAILQTINIT: |
// Release COM |
CoUninitialize(); |
return TRUE; |
} |
//----------------------------------------------------------------------------- |
// Name: MainDialogProc() |
// Desc: Handles dialog messages |
//----------------------------------------------------------------------------- |
INT_PTR CALLBACK MainDialogProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) |
{ |
HRESULT hr; |
static CFStringRef movieFilePathRef = NULL; |
static HANDLE movieFileHandle = NULL; |
// give the movie controller this message first |
if (g_MovieController) |
{ |
MSG myMsg = {0}; |
EventRecord myMacEvent; |
LONG myPoints = GetMessagePos(); |
myMsg.hwnd = hDlg; |
myMsg.message = msg; |
myMsg.wParam = wParam; |
myMsg.lParam = lParam; |
myMsg.time = GetMessageTime(); |
myMsg.pt.x = LOWORD(myPoints); |
myMsg.pt.y = HIWORD(myPoints); |
// translate a Windows event to a Mac event |
WinEventToMacEvent(&myMsg, &myMacEvent); |
// pass the Mac event to the movie controller, but only if the movie window isn't minimized |
if (!IsIconic(hDlg)) |
{ |
MCIsPlayerEvent(g_MovieController, (EventRecord *)&myMacEvent); |
} |
} |
switch( msg ) |
{ |
case WM_NOTIFY: |
break; |
case WM_CREATE: |
break; |
case WM_NULL: |
// we receive this message only to idle the movie |
if (g_MovieController) |
{ |
MCIdle(g_MovieController); |
} |
break; |
case WM_COMMAND: |
switch( LOWORD(wParam) ) |
{ |
case IDC_CREATE: |
// Init DirectSound |
if( SUCCEEDED( hr = InitDirectSound( hDlg ) ) ) |
{ |
MessageBox( hDlg, TEXT("DirectSound interface created successfully"), |
TEXT("EnumDevices"), MB_OK ); |
} |
else |
{ |
DXTRACE_ERR_MSGBOX( TEXT("InitDirectSound"), hr ); |
MessageBox( hDlg, TEXT("DirectSound interface creatation failed"), |
TEXT("EnumDevices"), MB_OK | MB_ICONERROR ); |
} |
break; |
case IDC_SETMOVIE: |
{ |
// get a movie file from the user |
TCHAR newMovieFileNamePath[MAX_PATH] = TEXT(""); |
BOOL gotAFile = GetFile((TCHAR *)&newMovieFileNamePath); |
if (gotAFile) |
{ |
// if we got a new file, suspend any currently playing movie |
if( g_MovieController ) |
{ |
MCDoAction(g_MovieController, mcActionSuspend, (void *)NULL); |
// dispose of the existing movie controller and movie resource |
DisposeMovieController(g_MovieController); |
DisposeMovie(g_Movie); |
} |
// copy movie path |
StringCchCopy( g_MovieFileNamePath, MAX_PATH, newMovieFileNamePath ); |
WCHAR* strLastSlash = wcsrchr( g_MovieFileNamePath, '\\' ); |
// copy movie file name |
StringCchCopy( g_MovieFileName, MAX_PATH, strLastSlash + 1 ); |
// create a new movie using the movie file path |
movieFilePathRef = CFStringCreateWithCharacters(kCFAllocatorDefault, |
g_MovieFileNamePath, |
MAX_PATH); |
require(movieFilePathRef != NULL, bail); |
OSStatus status = QT_CreateMovieWithProperties(movieFilePathRef, NULL, &g_Movie); |
// show the movie name in the dialog box |
SetDlgItemText( hDlg, IDC_MOVIENAME, g_MovieFileName ); |
// create a new movie controller for the movie |
Rect movieRect; |
GetMovieBox(g_Movie, &movieRect); |
g_MovieController = NewMovieController(g_Movie, &movieRect, mcNotVisible); |
bail: |
; |
} |
} |
break; |
// play button |
case IDC_BUTTON2: |
{ |
if (g_Movie) |
{ |
// First create a QuickTime Audio Context from either: |
// |
// - GUID (QT 7.0.4 or better only) |
// - Device Name |
if (g_QT704Installed ) |
{ |
// Use GUID |
GUID currentSoundDeviceGUID; |
CopySelectedSoundDeviceGUID( hDlg, ¤tSoundDeviceGUID); |
// Create audio context from GUID |
OSStatus status = QT_CreateAudioContextFromGUID(¤tSoundDeviceGUID, &g_QTAudioContextForDevice); |
} |
else |
{ |
// Use Device Name |
TCHAR currDeviceName[MAX_PATH]; |
CopySelectedSoundDeviceName( hDlg, (TCHAR *)&currDeviceName); |
// Create audio context from Device Name |
OSStatus status = QT_CreateAudioContextFromDeviceName((TCHAR *)&currDeviceName, &g_QTAudioContextForDevice); |
} |
// Set the QuickTime Audio Context for the current movie |
OSStatus status = SetMovieAudioContext(g_Movie, g_QTAudioContextForDevice); |
// Make a time record for the beginning of the movie |
TimeRecord currentTime; |
GetMovieTime(g_Movie, ¤tTime); |
currentTime.value.hi = 0; currentTime.value.lo = 0; |
// Set movie back to the beginning and play! |
MCDoAction(g_MovieController, mcActionGoToTime, (void *)¤tTime); |
MCDoAction(g_MovieController, mcActionPrerollAndPlay, (void *)GetMoviePreferredRate(g_Movie)); |
} |
} |
break; |
case IDC_SOUND_DEVICE_COMBO: |
if (HIWORD(wParam) == CBN_SELCHANGE) |
{ |
printf("CBN_SELCHANGE\n"); |
} |
break; |
case IDCANCEL: |
EndDialog( hDlg, IDCANCEL ); |
break; |
default: |
return FALSE; // Didn't handle message |
} |
break; |
case WM_INITDIALOG: |
if( FAILED( hr = OnInitDialog( hDlg ) ) ) |
{ |
DXTRACE_ERR_MSGBOX( TEXT("OnInitDialog"), hr ); |
MessageBox( hDlg, L"Error enumerating DirectSound devices. " |
L"Sample will now exit.", L"DirectSound Sample", |
MB_OK | MB_ICONERROR ); |
EndDialog( hDlg, IDABORT ); |
} |
// Associate a GrafPort with the native window |
CreatePortAssociation(hDlg, NULL, 0L); |
break; |
case WM_DESTROY: |
{ |
// Cleanup everything |
// Release DirectSound object |
FreeDirectSound(); |
// Remove GrafPort association for native window |
DestroyPortAssociation((CGrafPtr)GetNativeWindowPort(hDlg)); |
} |
break; |
default: |
return FALSE; // Didn't handle message |
} |
return TRUE; // Handled message |
} |
//----------------------------------------------------------------------------- |
// Name: OnInitDialog() |
// Desc: Initializes the dialogs (sets up UI controls, etc.) |
//----------------------------------------------------------------------------- |
HRESULT OnInitDialog( HWND hDlg ) |
{ |
HRESULT hr; |
// Enumerate the sound devices and place them in the combo box |
HWND hSoundDeviceCombo = GetDlgItem( hDlg, IDC_SOUND_DEVICE_COMBO ); |
if( FAILED( hr = DirectSoundEnumerate( (LPDSENUMCALLBACK)DSoundEnumCallback, |
(VOID*)hSoundDeviceCombo ) ) ) |
return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundEnumerate"), hr ); |
// Select the first device in the combo box |
SendMessage( hSoundDeviceCombo, CB_SETCURSEL, 0, 0 ); |
return S_OK; |
} |
//----------------------------------------------------------------------------- |
// Name: DSoundEnumCallback() |
// Desc: Enumeration callback called by DirectSoundEnumerate |
//----------------------------------------------------------------------------- |
INT_PTR CALLBACK DSoundEnumCallback( GUID* pGUID, TCHAR* strDesc, TCHAR* strDrvName, |
VOID* pContext ) |
{ |
static DWORD dwAudioDriverIndex = 0; |
static WORD guidArrayIndex = 0; |
// Note: The first device enumerated is always called the |
// Primary Sound Driver, and the lpGUID parameter of the |
// callback is NULL. This device represents the preferred |
// playback device set by the user in Control Panel. It is |
// enumerated separately to make it easy for the application |
// to add "Primary Sound Driver" to a list when presenting |
// the user with a choice of devices. The primary device is |
// also enumerated with its proper name and GUID. |
// For purposes of this example we will ignore Primary Sound |
// Driver, and only add the primary device when it is enumerated |
// with its proper name and GUID. |
if (!pGUID) |
return TRUE; |
size_t strDescLen = _tcslen(strDesc) * sizeof(TCHAR); |
dwAudioDriverIndex += strDescLen; |
// Now add driver name string to our popup control |
HWND hSoundDeviceCombo = (HWND)pContext; |
// Add the string to the combo box |
LRESULT result = SendMessage( hSoundDeviceCombo, CB_ADDSTRING, |
0, (LPARAM) (LPCTSTR) strDesc ); |
// Get the index of the string in the combo box |
INT nIndex = (INT)SendMessage( hSoundDeviceCombo, CB_FINDSTRING, |
0, (LPARAM) (LPCTSTR) strDesc ); |
// Save the GUID |
if (g_QT704Installed) |
{ |
SendMessage( hSoundDeviceCombo, CB_SETITEMDATA, |
nIndex, (LPARAM) pGUID ); |
++guidArrayIndex; |
} |
return TRUE; |
} |
//----------------------------------------------------------------------------- |
// Name: InitDirectSound() |
// Desc: Initilizes DirectSound |
//----------------------------------------------------------------------------- |
HRESULT InitDirectSound( HWND hDlg ) |
{ |
HRESULT hr; |
// Free any previous DirectSound objects |
FreeDirectSound(); |
// Get the HWNDs the combo boxes |
HWND hSoundDeviceCombo = GetDlgItem( hDlg, IDC_SOUND_DEVICE_COMBO ); |
// Get the index of the currently selected devices |
INT nSoundIndex = (INT)SendMessage( hSoundDeviceCombo, CB_GETCURSEL, 0, 0 ); |
// Get the GUID attached to the combo box item |
GUID* pSoundGUID = (GUID*) SendMessage( hSoundDeviceCombo, CB_GETITEMDATA, |
nSoundIndex, 0 ); |
// Create IDirectSound using the select sound device |
if( FAILED( hr = DirectSoundCreate( pSoundGUID, &g_pDS, NULL ) ) ) |
return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundCreate"), hr ); |
// Release the IDirectSound object immediately since we don't want |
// to limit this sample to only computers that support full duplex audio |
SAFE_RELEASE( g_pDS ); |
return S_OK; |
} |
//----------------------------------------------------------------------------- |
// Name: FreeDirectSound() |
// Desc: Releases DirectSound |
//----------------------------------------------------------------------------- |
HRESULT FreeDirectSound() |
{ |
// Release DirectSound interfaces |
SAFE_RELEASE( g_pDS ); |
return S_OK; |
} |
//----------------------------------------------------------------------------- |
// Name: CopySelectedSoundDeviceGUID() |
// Desc: Makes a copy of the currently selected sound device GUID |
//----------------------------------------------------------------------------- |
void CopySelectedSoundDeviceGUID( HWND hDlg, GUID *outCurrentSoundGUID) |
{ |
// Get the HWNDs the combo boxes |
HWND hSoundDeviceCombo = GetDlgItem( hDlg, IDC_SOUND_DEVICE_COMBO ); |
// Get the index of the currently selected devices |
INT nSoundIndex = (INT)SendMessage( hSoundDeviceCombo, CB_GETCURSEL, 0, 0 ); |
GUID *pGUID = NULL; |
// Get the GUID attached to the combo box item |
pGUID = (GUID*) SendMessage( hSoundDeviceCombo, CB_GETITEMDATA, |
nSoundIndex, 0 ); |
if (pGUID) |
{ |
memcpy(outCurrentSoundGUID, pGUID, sizeof(GUID)); |
} |
} |
//----------------------------------------------------------------------------- |
// Name: CopySelectedSoundDeviceName() |
// Desc: Makes a copy of the currently selected sound device name |
//----------------------------------------------------------------------------- |
void CopySelectedSoundDeviceName( HWND hDlg, TCHAR *outCurrentSoundDeviceName) |
{ |
// Get the HWNDs the combo boxes |
HWND hSoundDeviceCombo = GetDlgItem( hDlg, IDC_SOUND_DEVICE_COMBO ); |
// Get the index of the currently selected devices |
INT nSoundIndex = (INT)SendMessage( hSoundDeviceCombo, CB_GETCURSEL, 0, 0 ); |
// Get the Device Name attached to the combo box item |
LRESULT strLength = SendMessage( hSoundDeviceCombo, CB_GETLBTEXT, |
nSoundIndex, (LPARAM)outCurrentSoundDeviceName ); |
} |
//----------------------------------------------------------------------------- |
// Name: GetFile() |
// Desc: Show the open file dialog and allow the user to select a file |
//----------------------------------------------------------------------------- |
BOOL GetFile (TCHAR *theFileName) |
{ |
static TCHAR strPath[MAX_PATH] = TEXT(""); |
// Setup the OPENFILENAME structure |
OPENFILENAME ofn = { sizeof(OPENFILENAME), NULL, NULL, |
TEXT("Movie Files\0*.mov\0All Files\0*.*\0\0"), NULL, |
0, 1, theFileName, MAX_PATH, NULL, 0, strPath, |
TEXT("Open a movie file"), |
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0, |
TEXT(".mov"), 0, NULL, NULL }; |
// Get the default media path (something like C:\WINDOWS\MEDIA) |
if( '\0' == strPath[0] ) |
{ |
if( GetWindowsDirectory( strPath, MAX_PATH ) != 0 ) |
{ |
StringCchCat( strPath, MAX_PATH, TEXT("\\MEDIA") ); |
} |
} |
// Display the OpenFileName dialog. Then, try to load the specified file |
return (GetOpenFileName( &ofn ) ); |
} |
Copyright © 2006 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2006-03-03