Using the API
The main tool you need to get your arms around is the API document. Without it you cannot build an iTunes solution.
To call the classes, you need to include the subclasses you want to use, which are included in the iTunesVisualAPIW32 subfolder.
#include "iTunesAPI.h" #include "iTunesVisualAPI.h"
Begin by setting the function MemClear to manage memory.
// static void MemClear (LogicalAddress dest, SInt32 length) { register unsigned char *ptr; ptr = (unsigned char *) dest; if( length > 16 ) { register unsigned long *longPtr; while( ((unsigned long) ptr & 3) != 0 ) { *ptr++ = 0; --length; } longPtr = (unsigned long *) ptr; while( length >= 4 ) { *longPtr++ = 0; length -= 4; } ptr = (unsigned char *) longPtr; } while( --length >= 0 ) { *ptr++ = 0; } } // SetNumVersion // void SetNumVersion (NumVersion *numVersion, UInt8 majorRev, UInt8 minorAndBugRev, UInt8 stage, UInt8 nonRelRev) { numVersion->majorRev = majorRev; numVersion->minorAndBugRev = minorAndBugRev; numVersion->stage = stage; numVersion->nonRelRev = nonRelRev; } // ITCallApplication // static OSStatus ITCallApplicationInternal (void *appCookie, ITAppProcPtr handler, OSType message, UInt32 messageMajorVersion, UInt32 messageMinorVersion, PlayerMessageInfo *messageInfo) { PlayerMessageInfo localMessageInfo; if (messageInfo == nil) { MemClear(&localMessageInfo, sizeof(localMessageInfo)); messageInfo = &localMessageInfo; } messageInfo->messageMajorVersion = messageMajorVersion; messageInfo->messageMinorVersion = messageMinorVersion; messageInfo->messageInfoSize = sizeof(PlayerMessageInfo); return handler(appCookie, message, messageInfo); } // ITCallApplication // OSStatus ITCallApplication (void *appCookie, ITAppProcPtr handler, OSType message, PlayerMessageInfo *messageInfo) { return ITCallApplicationInternal(appCookie, handler, message, kITPluginMajorMessageVersion, kITPluginMinorMessageVersion, messageInfo); }
The PlayerSetFullScreen function allows you to set the application to full screen.
// OSStatus PlayerSetFullScreen (void *appCookie, ITAppProcPtr appProc, Boolean fullScreen) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.setFullScreenMessage.fullScreen = fullScreen; return ITCallApplication(appCookie, appProc, kPlayerSetFullScreenMessage, &messageInfo); }
If you decide to set the application to full screen you can also add the following function that allows access controls: PlayerSetFullScreenOptions.
// OSStatus PlayerSetFullScreenOptions (void *appCookie, ITAppProcPtr appProc, SInt16 minBitDepth, SInt16 maxBitDepth, SInt16 preferredBitDepth, SInt16 desiredWidth, SInt16 desiredHeight) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.setFullScreenOptionsMessage.minBitDepth = minBitDepth; messageInfo.u.setFullScreenOptionsMessage.maxBitDepth = maxBitDepth; messageInfo.u.setFullScreenOptionsMessage.preferredBitDepth = preferredBitDepth; messageInfo.u.setFullScreenOptionsMessage.desiredWidth = desiredWidth; messageInfo.u.setFullScreenOptionsMessage.desiredHeight = desiredHeight; return ITCallApplication(appCookie, appProc, kPlayerSetFullScreenOptionsMessage, &messageInfo); }
Album cover art can be loaded into your visual plugin. To access it, leverage the following function: PlayerGetCurrentTrackCoverArt.
// OSStatus PlayerGetCurrentTrackCoverArt (void *appCookie, ITAppProcPtr appProc, Handle *coverArt, OSType *coverArtFormat) { OSStatus status; PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.getCurrentTrackCoverArtMessage.coverArt = nil; status = ITCallApplication(appCookie, appProc, kPlayerGetCurrentTrackCoverArtMessage, &messageInfo); *coverArt = messageInfo.u.getCurrentTrackCoverArtMessage.coverArt; if (coverArtFormat) *coverArtFormat = messageInfo.u.getCurrentTrackCoverArtMessage.coverArtFormat; return status; }
You need to access the data of the music file being currently played. The PlayerGetPluginData function does this for you.
// OSStatus PlayerGetPluginData (void *appCookie, ITAppProcPtr appProc, void *dataPtr, UInt32 dataBufferSize, UInt32 *dataSize) { OSStatus status; PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.getPluginDataMessage.dataPtr = dataPtr; messageInfo.u.getPluginDataMessage.dataBufferSize = dataBufferSize; status = ITCallApplication(appCookie, appProc, kPlayerGetPluginDataMessage, &messageInfo); if (dataSize != nil) *dataSize = messageInfo.u.getPluginDataMessage.dataSize; return status; }
After you have the data for a plugin, you need to set this data so that it can be bound to fields. The PlayerSetPluginData enables this.
// OSStatus PlayerSetPluginData (void *appCookie, ITAppProcPtr appProc, void *dataPtr, UInt32 dataSize) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.setPluginDataMessage.dataPtr = dataPtr; messageInfo.u.setPluginDataMessage.dataSize = dataSize; return ITCallApplication(appCookie, appProc, kPlayerSetPluginDataMessage, &messageInfo); } // PlayerGetPluginNamedData // OSStatus PlayerGetPluginNamedData (void *appCookie, ITAppProcPtr appProc, ConstStringPtr dataName, void *dataPtr, UInt32 dataBufferSize, UInt32 *dataSize) { OSStatus status; PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.getPluginNamedDataMessage.dataName = dataName; messageInfo.u.getPluginNamedDataMessage.dataPtr = dataPtr; messageInfo.u.getPluginNamedDataMessage.dataBufferSize = dataBufferSize; status = ITCallApplication(appCookie, appProc, kPlayerGetPluginNamedDataMessage, &messageInfo); if (dataSize != nil) *dataSize = messageInfo.u.getPluginNamedDataMessage.dataSize; return status; } // PlayerSetPluginNamedData // OSStatus PlayerSetPluginNamedData (void *appCookie, ITAppProcPtr appProc, ConstStringPtr dataName, void *dataPtr, UInt32 dataSize) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.setPluginNamedDataMessage.dataName = dataName; messageInfo.u.setPluginNamedDataMessage.dataPtr = dataPtr; messageInfo.u.setPluginNamedDataMessage.dataSize = dataSize; return ITCallApplication(appCookie, appProc, kPlayerSetPluginNamedDataMessage, &messageInfo); } // PlayerIdle // OSStatus PlayerIdle (void *appCookie, ITAppProcPtr appProc) { return ITCallApplication(appCookie, appProc, kPlayerIdleMessage, nil); } // PlayerShowAbout // void PlayerShowAbout (void *appCookie, ITAppProcPtr appProc) { ITCallApplication(appCookie, appProc, kPlayerShowAboutMessage, nil); } // PlayerOpenURL // void PlayerOpenURL (void *appCookie, ITAppProcPtr appProc, SInt8 *string, UInt32 length) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.openURLMessage.url = string; messageInfo.u.openURLMessage.length = length; ITCallApplication(appCookie, appProc, kPlayerOpenURLMessage, &messageInfo); } // PlayerUnregisterPlugin // OSStatus PlayerUnregisterPlugin (void *appCookie, ITAppProcPtr appProc, PlayerMessageInfo *messageInfo) { return ITCallApplication(appCookie, appProc, kPlayerUnregisterPluginMessage, messageInfo); }
One of the most important functions is the capability to register a plugin. The PlayerRegisterVisualPlugin function allows you do this. Without registering, the plugin will not play.
// OSStatus PlayerRegisterVisualPlugin (void *appCookie, ITAppProcPtr appProc, PlayerMessageInfo *messageInfo) { return ITCallApplicationInternal(appCookie, appProc, kPlayerRegisterVisualPluginMessage, kITVisualPluginMajorMessageVersion, kITVisualPluginMinorMessageVersion, messageInfo); } // PlayerGetPluginITFileSpec // OSStatus PlayerGetPluginITFileSpec (void *appCookie, ITAppProcPtr appProc, ITFileSpec *pluginFileSpec) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.getPluginITFileSpecMessage.fileSpec = pluginFileSpec; return ITCallApplication(appCookie, appProc, kPlayerGetPluginITFileSpecMessage, &messageInfo); }
Visual plugins can display the track of the current song. The PlayerGetFileTrackInfo allows you to get the track information.
// OSStatus PlayerGetFileTrackInfo (void *appCookie, ITAppProcPtr appProc, const ITFileSpec *fileSpec, ITTrackInfo *trackInfo) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.getFileTrackInfoMessage.fileSpec = fileSpec; messageInfo.u.getFileTrackInfoMessage.trackInfo = trackInfo; return ITCallApplication(appCookie, appProc, kPlayerGetFileTrackInfoMessage, &messageInfo); }
The PlayerSetFileTrackInfo allows you to bind the information you received from PlayerGetFileTrackInfo to a field.
// OSStatus PlayerSetFileTrackInfo (void *appCookie, ITAppProcPtr appProc, const ITFileSpec *fileSpec, const ITTrackInfo *trackInfo) { PlayerMessageInfo messageInfo; MemClear(&messageInfo, sizeof(messageInfo)); messageInfo.u.setFileTrackInfoMessage.fileSpec = fileSpec; messageInfo.u.setFileTrackInfoMessage.trackInfo = trackInfo; return ITCallApplication(appCookie, appProc, kPlayerSetFileTrackInfoMessage, &messageInfo); } // PlayerGetITTrackInfoSize // OSStatus PlayerGetITTrackInfoSize (void *appCookie, ITAppProcPtr appProc, UInt32 appPluginMajorVersion, UInt32 appPluginMinorVersion, UInt32 *itTrackInfoSize) { PlayerMessageInfo messageInfo; OSStatus status; /*
*/ *itTrackInfoSize = 0; MemClear(&messageInfo, sizeof(messageInfo)); status = ITCallApplication(appCookie, appProc, kPlayerGetITTrackInfoSizeMessage, &messageInfo); if( status == noErr ) { *itTrackInfoSize = messageInfo.u.getITTrackInfoSizeMessage.itTrackInfoSize; } else if( appPluginMajorVersion == 10 && appPluginMinorVersion == 2 ) { // iTunes 2.0.x *itTrackInfoSize = ((UInt32) &((ITTrackInfo *) 0)->composer); status = noErr; } else if( appPluginMajorVersion == 10 && appPluginMinorVersion == 3 ) { // iTunes 3.0.x *itTrackInfoSize = ((UInt32) &((ITTrackInfo *) 0)->beatsPerMinute); status = noErr; } else { // iTunes 4.0 and later implement the kPlayerGetITTrackInfoSizeMessage message. If you got here // then the appPluginMajorVersion or appPluginMinorVersion are incorrect. status = paramErr; } if( status == noErr && (*itTrackInfoSize) > sizeof(ITTrackInfo) ) { // iTunes is using a larger ITTrackInfo than the one when this plugin was compiled. Pin *itTrackInfoSize to the plugin's known size *itTrackInfoSize = sizeof(ITTrackInfo); } return status; }