|
|
/*
*************************************************************** * sndfile.c * * This file contains the code to fill up the list and combo boxes, * show the RIFF Dibs and the current sound mappings * * Copyright 1993, Microsoft Corporation * * History: * * 07/94 - VijR (Created) * *************************************************************** */ #include <windows.h>
#include <mmsystem.h>
#include <string.h>
#include <ole2.h>
#include <prsht.h>
#include <cpl.h>
#include "mmcpl.h"
#include "draw.h"
#include "sound.h"
/*
*************************************************************** * Globals *************************************************************** */ HSOUND ghse;
/*
*************************************************************** * extern *************************************************************** */ extern TCHAR gszMediaDir[]; extern TCHAR gszCurDir[]; extern BOOL gfWaveExists; // indicates wave device in system.
extern BOOL gfChanged; // Is set TRUE if any changes are made
extern BOOL gfNewScheme;
//Globals used in painting disp chunk display.
extern HTREEITEM ghOldItem;
/*
*************************************************************** * Defines *************************************************************** */ #define DF_PM_SETBITMAP (WM_USER+1)
#define FOURCC_INFO mmioFOURCC('I','N','F','O')
#define FOURCC_DISP mmioFOURCC('D','I','S','P')
#define FOURCC_INAM mmioFOURCC('I','N','A','M')
#define FOURCC_ISBJ mmioFOURCC('I','S','B','J')
#define MAXDESCLEN 220
/*
*************************************************************** * Prototypes *************************************************************** */ HANDLE PASCAL GetRiffDisp (HMMIO); BOOL PASCAL ShowSoundMapping (HWND, PEVENT); BOOL PASCAL ChangeSoundMapping (HWND, LPTSTR, PEVENT); BOOL PASCAL PlaySoundFile (HWND, LPTSTR); BOOL PASCAL ChangeSetting (LPTSTR*, LPTSTR); LPTSTR PASCAL NiceName(LPTSTR sz, BOOL fNukePath);
// Stuff in dib.c
//
HPALETTE WINAPI bmfCreateDIBPalette(HANDLE); HBITMAP WINAPI bmfBitmapFromDIB(HANDLE, HPALETTE);
// Stuff in drivers.c
//
LPTSTR lstrchr (LPTSTR, TCHAR); int lstrnicmp (LPTSTR, LPTSTR, size_t);
// Stuff in scheme.c
//
void PASCAL AddMediaPath (LPTSTR, LPTSTR);
/*
*************************************************************** *************************************************************** */ STATIC void NEAR PASCAL ChopPath(LPTSTR lpszFile) { TCHAR szTmp[MAX_PATH]; size_t cchTest = lstrlen (gszCurDir);
szTmp[0] = TEXT('\0');
ExpandEnvironmentStrings(lpszFile, (LPTSTR)szTmp, MAXSTR); lstrcpy(lpszFile,szTmp);
if (gszCurDir[ cchTest-1 ] == TEXT('\\')) --cchTest; lstrcpy((LPTSTR)szTmp, lpszFile); if (!lstrnicmp((LPTSTR)szTmp, (LPTSTR)gszCurDir, cchTest)) { if (szTmp[ cchTest ] == TEXT('\\')) { lstrcpy(lpszFile, (LPTSTR)(szTmp+cchTest+1)); } } } /*
*************************************************************** * QualifyFileName * * Description: * Verifies the existence and readability of a file. * * Parameters: * LPTSTR lpszFile - name of file to check. * LPTSTR lpszPath - returning full pathname of file. * int csSize - Size of return buffer * * Returns: BOOL * True if absolute path exists * *************************************************************** */
BOOL PASCAL QualifyFileName(LPTSTR lpszFile, LPTSTR lpszPath, int cbSize, BOOL fTryCurDir) { BOOL fErrMode; BOOL f = FALSE; BOOL fHadEnvStrings; TCHAR szTmpFile[MAXSTR]; int len; BOOL fTriedCurDir; TCHAR* pszFilePart; HFILE hFile;
if (!lpszFile) return FALSE;
fHadEnvStrings = (lstrchr (lpszFile, TEXT('%')) != NULL) ? TRUE : FALSE;
ExpandEnvironmentStrings (lpszFile, (LPTSTR)szTmpFile, MAXSTR); len = lstrlen((LPTSTR)szTmpFile)+1;
fErrMode = SetErrorMode(TRUE); // we will handle errors
AddExt (szTmpFile, cszWavExt);
fTriedCurDir = FALSE;
TryOpen: hFile = (HFILE)HandleToUlong(CreateFile(szTmpFile,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); if (-1 != hFile) { if (fHadEnvStrings) lstrcpyn(lpszPath, lpszFile, cbSize); else GetFullPathName(szTmpFile,cbSize/sizeof(TCHAR),lpszPath,&pszFilePart); f = TRUE;
CloseHandle(LongToHandle(hFile)); } else /*
** If the test above failed, we try converting the name to OEM ** character set and try again. */ { /*
** First, is it in MediaPath? ** */ if (lstrchr (lpszFile, TEXT('\\')) == NULL) { TCHAR szCurDirFile[MAXSTR]; AddMediaPath (szCurDirFile, lpszFile); if (-1 != (HFILE)HandleToUlong(CreateFile(szCurDirFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))) { GetFullPathName(szCurDirFile,cbSize/sizeof(TCHAR),lpszPath,&pszFilePart); f = TRUE; goto DidOpen; } }
//AnsiToOem((LPTSTR)szTmpFile, (LPTSTR)szTmpFile);
if (-1 != (HFILE)HandleToUlong(CreateFile(szTmpFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))) { if (fHadEnvStrings) lstrcpyn(lpszPath, lpszFile, cbSize); else GetFullPathName(szTmpFile,cbSize/sizeof(TCHAR),lpszPath,&pszFilePart); f = TRUE; } else if (fTryCurDir && !fTriedCurDir) { TCHAR szCurDirFile[MAXSTR];
//OemToAnsi((LPTSTR)szTmpFile, (LPTSTR)szTmpFile);
lstrcpy (szCurDirFile, gszCurDir); lstrcat (szCurDirFile, cszSlash); lstrcat (szCurDirFile, szTmpFile); lstrcpy((LPTSTR)szTmpFile, (LPTSTR)szCurDirFile); fTriedCurDir = TRUE; goto TryOpen; } }
DidOpen: SetErrorMode(fErrMode); return f; }
/*
*************************************************************** * ChangeSoundMapping * * Description: * Change the sound file associated with a sound * * Parameters: * HWND hDlg - handle to dialog window. * LPTSTR lpszFile - New filename for current event * LPTSTR lpszDir - New foldername for current event * LPTSTR lpszPath - New absolute path for file * * Returns: BOOL * *************************************************************** */ BOOL PASCAL ChangeSoundMapping(HWND hDlg, LPTSTR lpszPath, PEVENT pEvent) { TCHAR szValue[MAXSTR]; if (!pEvent) { if(!ghse) EnableWindow(GetDlgItem(hDlg, ID_PLAY), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_SOUND_FILES), FALSE); ShowSoundMapping(hDlg,NULL); return TRUE; } szValue[0] = TEXT('\0'); if (!ChangeSetting((LPTSTR *)&(pEvent->pszPath), lpszPath)) return FALSE; if(!ghse) EnableWindow(GetDlgItem(hDlg, ID_PLAY), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_SOUND_FILES), TRUE); ShowSoundMapping(hDlg,pEvent); gfChanged = TRUE; gfNewScheme = TRUE; PropSheet_Changed(GetParent(hDlg),hDlg); return TRUE; }
STATIC void SetTreeStateIcon(HWND hDlg, int iImage) { TV_ITEM tvi; HWND hwndTree = GetDlgItem(hDlg, IDC_EVENT_TREE); HTREEITEM hti;
if (ghOldItem) hti = ghOldItem; else hti = TreeView_GetSelection(hwndTree); if (hti) { tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; tvi.hItem = hti; tvi.iImage = tvi.iSelectedImage = iImage; TreeView_SetItem(hwndTree, &tvi); RedrawWindow(hwndTree, NULL, NULL, RDW_ERASE|RDW_ERASENOW|RDW_INTERNALPAINT|RDW_INVALIDATE | RDW_UPDATENOW); } }
/*
*************************************************************** * ShowSoundMapping * * Description: * Highlights the label and calls ShowSoundDib to display the Dib * associated with the current event. * * Parameters: * HWND hDlg - handle to dialog window. * * Returns: BOOL * *************************************************************** */ BOOL PASCAL ShowSoundMapping(HWND hDlg, PEVENT pEvent) { TCHAR szOut[MAXSTR];
if (!pEvent) { EnableWindow(GetDlgItem(hDlg, IDC_SOUND_FILES), FALSE); EnableWindow(GetDlgItem(hDlg, ID_BROWSE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_STATIC_NAME), FALSE); // wsprintf((LPTSTR)szCurSound, (LPTSTR)gszSoundGrpStr, (LPTSTR)gszNull);
} else { EnableWindow(GetDlgItem(hDlg, IDC_SOUND_FILES), TRUE); EnableWindow(GetDlgItem(hDlg, ID_BROWSE), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_STATIC_NAME), TRUE); // wsprintf((LPTSTR)szCurSound, (LPTSTR)gszSoundGrpStr, (LPTSTR)pEvent->pszEventLabel);
} //SetWindowText(GetDlgItem(hDlg, IDC_SOUNDGRP), (LPTSTR)szCurSound);
//RedrawWindow(GetDlgItem(hDlg, IDC_EVENT_TREE), NULL, NULL, RDW_ERASE|RDW_ERASENOW|RDW_INTERNALPAINT|RDW_INVALIDATE | RDW_UPDATENOW);
if (!pEvent || !QualifyFileName(pEvent->pszPath, szOut, sizeof(szOut), FALSE)) { int iLen;
if(!ghse) EnableWindow(GetDlgItem(hDlg, ID_PLAY), FALSE); if(pEvent) iLen = lstrlen(pEvent->pszPath); if (pEvent && iLen > 0) { if (iLen < 5) { lstrcpy(pEvent->pszPath, gszNull); gfChanged = TRUE; gfNewScheme = TRUE; PropSheet_Changed(GetParent(hDlg),hDlg); } else { TCHAR szMsg[MAXSTR]; TCHAR szTitle[MAXSTR];
LoadString(ghInstance, IDS_NOSNDFILE, szTitle, sizeof(szTitle)/sizeof(TCHAR)); wsprintf(szMsg, szTitle, pEvent->pszPath); LoadString(ghInstance, IDS_NOSNDFILETITLE, szTitle, sizeof(szTitle)/sizeof(TCHAR)); if (MessageBox(hDlg, szMsg, szTitle, MB_YESNO) == IDNO) { lstrcpy(pEvent->pszPath, gszNull); ComboBox_SetText(GetDlgItem(hDlg, IDC_SOUND_FILES), gszNone); gfChanged = TRUE; gfNewScheme = TRUE; PropSheet_Changed(GetParent(hDlg),hDlg); if (pEvent && pEvent->fHasSound) { SetTreeStateIcon(hDlg, 2); pEvent->fHasSound = FALSE; } } else { lstrcpy(szOut ,pEvent->pszPath); ChopPath((LPTSTR)szOut); NiceName((LPTSTR)szOut, FALSE); ComboBox_SetText(GetDlgItem(hDlg, IDC_SOUND_FILES), szOut); if (!pEvent->fHasSound) { SetTreeStateIcon(hDlg, 1); pEvent->fHasSound = TRUE; } } } } else { ComboBox_SetText(GetDlgItem(hDlg, IDC_SOUND_FILES), gszNone); if (pEvent && pEvent->fHasSound) { SetTreeStateIcon(hDlg, 2); pEvent->fHasSound = FALSE; } } } else { if(!ghse) EnableWindow(GetDlgItem(hDlg, ID_PLAY),gfWaveExists); ChopPath((LPTSTR)szOut); NiceName((LPTSTR)szOut, FALSE); ComboBox_SetText(GetDlgItem(hDlg, IDC_SOUND_FILES), szOut); if (!pEvent->fHasSound) { SetTreeStateIcon(hDlg, 1); pEvent->fHasSound = TRUE; }
} return TRUE; }
/*
*************************************************************** * PlaySoundFile * * Description: * Plays the given sound file. * * Parameters: * HWND hDlg - Window handle * LPTSTR lpszFile - absolute path of File to play. * * Returns: BOOL * *************************************************************** */ BOOL PASCAL PlaySoundFile(HWND hDlg, LPTSTR lpszFile) { TCHAR szOut[MAXSTR]; TCHAR szTemp[MAXSTR]; BOOL rb = TRUE; if (!QualifyFileName(lpszFile, szTemp, sizeof(szTemp), FALSE)) { ErrorBox(hDlg, IDS_ERRORPLAY, lpszFile); rb = FALSE; } else{ MMRESULT err = MMSYSERR_NOERROR;
ExpandEnvironmentStrings (szTemp, szOut, MAXSTR);
if((soundOpen(szOut, hDlg, &ghse) != MMSYSERR_NOERROR) || ((err = soundPlay(ghse)) != MMSYSERR_NOERROR)) { if (err >= (MMRESULT)MMSYSERR_LASTERROR) ErrorBox(hDlg, IDS_ERRORUNKNOWNPLAY, lpszFile); else if (err == (MMRESULT)MMSYSERR_ALLOCATED) ErrorBox(hDlg, IDS_ERRORDEVBUSY, lpszFile); else ErrorBox(hDlg, IDS_ERRORFILEPLAY, lpszFile); ghse = NULL; rb = FALSE; } } return rb; }
/*
*************************************************************** * ChangeSetting * * Description: * Displays the labels of all the links present in the lpszDir folder * in the LB_SOUNDS listbox * * Parameters: * HWND hDlg - Window handle * LPTSTR lpszDir - Name of sound folder whose files must be displayed. * * Returns: BOOL * *************************************************************** */ BOOL PASCAL ChangeSetting(LPTSTR *npOldString, LPTSTR lpszNew) { int len = (lstrlen(lpszNew)*sizeof(TCHAR))+sizeof(TCHAR);
if (*npOldString) { LocalFree(*npOldString); } *npOldString = (LPTSTR)LocalAlloc(LPTR, len); if (*npOldString == NULL) { DPF("LocalAlloc Failed\n"); return FALSE; } lstrcpy(*npOldString, lpszNew); DPF("New file is %s\n", (LPTSTR)*npOldString); return TRUE; }
STATIC HANDLE PASCAL GetRiffDisp(HMMIO hmmio) { MMCKINFO ck; MMCKINFO ckRIFF; HANDLE h = NULL; LONG lSize; DWORD dw;
mmioSeek(hmmio, 0, SEEK_SET);
/* descend the input file into the RIFF chunk */ if (mmioDescend(hmmio, &ckRIFF, NULL, 0) != 0) goto error;
if (ckRIFF.ckid != FOURCC_RIFF) goto error;
while (!mmioDescend(hmmio, &ck, &ckRIFF, 0)) { if (ck.ckid == FOURCC_DISP) { /* Read dword into dw, break if read unsuccessful */ if (mmioRead(hmmio, (LPVOID)&dw, sizeof(dw)) != (LONG)sizeof(dw)) goto error;
/* Find out how much memory to allocate */ lSize = ck.cksize - sizeof(dw);
if ((int)dw == CF_DIB && h == NULL) { /* get a handle to memory to hold the description and
lock it down */ if ((h = GlobalAlloc(GHND, lSize+4)) == NULL) goto error;
if (mmioRead(hmmio, GlobalLock(h), lSize) != lSize) goto error; } } //
// if we have both a picture and a title, then exit.
//
if (h != NULL) break;
/* Ascend so that we can descend into next chunk
*/ if (mmioAscend(hmmio, &ck, 0)) break; }
goto exit;
error: if (h) { GlobalUnlock(h); GlobalFree(h); } h = NULL;
exit: return h; }
|