/* *************************************************************** * 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 #include #include #include #include #include #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) { *npOldString = (LPTSTR)LocalReAlloc((HLOCAL)*npOldString, len, LMEM_MOVEABLE); } else { DPF("Current file Does not exist\n"); *npOldString = (LPTSTR)LocalAlloc(LPTR, len); } if (*npOldString == NULL) { DPF("ReAlloc 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; }