I make all sorts of pieces of software, some on CD-ROM and occasionally that CD can contain Audio tracks. Occasionally, I need to be able to open the local CD playing application – whatever that is (often Windows Media Player). Turns out, getting this to load and auto play can be rather tricky.
Not on a CD-ROM. Whilst an Audio CD under Windows appears as a set of .CDA files (pointers to the actual audio tracks), on a CD-ROM, Windows decides that the data volume takes precedence over the audio tracks. They aren’t shown and you can’t find them in Windows Explorer.
(As a point of interest, OS X does mount CD-ROMs that contains audio tracks as a separate Audio track volume and a Data volume).
Whilst we don’t want to dive too far into the mess that is Windows programming, we do need to do a tiny bit and look at a useful function called ShellExecuteEx (used for asking the Shell to Execute External programs), and the information structure ShellExecuteInfo.
Performs an operation on a specified file.
Structure for ShellExecuteEx function
Whilst the ShellExecuteInfo structure looks hideous, it turns out we only need a few bits to open the CD playing app.
The main points to note here are lpFile = NULL, and the lpClass = _T(“AudioCD”) – We don’t need to specify a file, e.g. X:\Track01.cda (because we can’t see it anyway). We also pass in the “play” verb – lpVerb = _T(“play”) asking the system to run the “play” action against the AudioCD entry in the registry. Finally we pass in the lpDirectory = _T(“d:”) – which is the letter of the drive containing the audio CD. In reality the CD Drive may not be on drive D: and this should be a variable.
#include "stdafx.h" #include <shlobj.h> int _tmain(int argc, _TCHAR* argv[]) { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // split the program name into two chunks by : char* p = strtok((char*)argv[0], ":"); char drive[3]={"d:"}; sprintf(drive, "%s:", p); // Create and clear out the shellexecuteinfo structure SHELLEXECUTEINFO ShExecInfo; memset(&ShExecInfo, 0, sizeof(SHELLEXECUTEINFO)); // Set all the parameters ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask = SEE_MASK_CLASSNAME; ShExecInfo.lpClass = _T("AudioCD"); ShExecInfo.lpVerb = _T("play"); ShExecInfo.hwnd = NULL; ShExecInfo.lpFile = NULL; ShExecInfo.lpParameters = NULL; ShExecInfo.lpDirectory = (LPCWSTR)drive; // drive letter ShExecInfo.nShow = SW_SHOW; // show the app on screen ShExecInfo.hInstApp = NULL; BOOL result = ShellExecuteEx(&ShExecInfo); if (!result) { DWORD error = GetLastError(); return error; } return 0; }
Categories
Submit a Comment