WMPTSE API: Difference between revisions
Line 199: | Line 199: | ||
#ifdef _USRDLL | #ifdef _USRDLL | ||
#define STINGTAG_API | #define STINGTAG_API __declspec( dllexport ) | ||
#else | #else | ||
#define STINGTAG_API | #define STINGTAG_API | ||
#endif | #endif | ||
Line 207: | Line 207: | ||
#ifdef _USRDLL | #ifdef _USRDLL | ||
#define STINGTAG_API | #define STINGTAG_API extern __declspec( dllimport ) | ||
#elif defined( _EXPORTDLL ) | #elif defined( _EXPORTDLL ) | ||
#define STINGTAG_API | #define STINGTAG_API extern __declspec( dllexport ) | ||
#else | #else | ||
#define STINGTAG_API | #define STINGTAG_API extern | ||
#endif | #endif | ||
Revision as of 13:53, 21 November 2006
The WMPTSE API is the interface between the WMPTSE plug-in and its "tag support dll".
A tag support dll give WMPTSE the ability to add support of a tag format in Windows Media Player. With the this "tag support dll" properly installed, files tagged with its format are readable inside WMP.
API
Every WMPTSE API application must export two function (c standard call):
BOOL Read<TagFormat>Tag( LPTSTR lpstrFileFullPath, METATAG * pMetaTag ) BOOL Write<TagFormat>Tag( LPTSTR lpstrFileFullPath, TAGITEM tagiChangedItem )
<TagFormat> will be the name of the corresponding tag format (APE, Vorbis, MPEG4 for example). The complete function names will be search by WMPTSE during the load process.
The boolean return value is important.
For the read function, it tells WMPTSE if the "tag support dll" has find the correct tag format structures (even if they are empty). If the value is TRUE, WMPTSE will stop searching for compatible tag format for this file (yes, a file can be multi-tagged). If the value is FALSE, WMPTSE will continue searching in its compatible tag format list.
For the write function, it tells WMPTSE if the "tag support dll" has correctly write the new value. If this is true, WMPTSE will continue using this "tag support dll" for this filetype. If this value is false, WMPTSE may unload the "tag support dll".
These function types are defined as FP_TAGREAD (read), FP_TAGWRITE (write) in "WMPTSE.h".
Definition
Note : All types and definition are declared in WMPTSE.h. It is simple for developper to include it at first.
For reading purpose, we will expose the necessary structure definition here.
struct stTagItem { char * MetaTagWMPKey; /** the MediaLibrary attribute's name */ LPTSTR MetaTagValue; /** the value to set */ }; #define TAGITEM struct stTagItem typedef struct stTagItem * LPTAGITEM;
struct stMetaTag { UINT uiNbItems; /** number of list tags */ LPTAGITEM tagiItems; /** pointer to array of pointer to tag items */ }; #define METATAG struct stMetaTag typedef struct stMetaTag * LPMETATAG;
Example Source Code
In this example, we will add support for a weird tag format : the "Sting fan" format. In fact, every file considered tagged with this format will return "Sting" as Album Artist. The sign of a true fan :)
Note : We will not create the write function as it is a "read only" tag format.
Let's see the documented code :
///////////////////////////////////////////////////////////////////////////// // // StingTagSupport.c : // Handler for Sting tags support // // Copyxxx (\C) 200x - // ///////////////////////////////////////////////////////////////////////////// #define STING_TAGSUPPORT_C #include "StingTagSupport.h" #undef STING_TAGSUPPORT_C BOOL STINGTAG_API ReadStingTag ( LPTSTR lpstrFileFullPath, METATAG * pMetaTag ) { UINT uiFilePathSize; LPSTR lpcFileFullPath; LPVOID lpvTempPtr; //First we get the filepath length before retrieving it uiFilePathSize = WideCharToMultiByte ( CP_ACP, 0, lpstrFileFullPath, -1, NULL, 0, NULL, NULL ); //then we alloc on the process Heap the memory lpcFileFullPath = ( LPSTR ) HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, uiFilePathSize ); //and we retrieve the filepath WideCharToMultiByte ( CP_ACP, 0, lpstrFileFullPath, -1, lpcFileFullPath, uiFilePathSize, NULL, NULL ); //now, we fill the MetaTag structure with start values //at start we don't have any Tags.. pMetaTag->uiNbItems = 0; //at start we need to have a "root" TAGITEM table so we alloc it pMetaTag->tagiItems = ( LPTAGITEM )HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( TAGITEM ) ); //We will handles just Album Artist (it should be enough for an example) //first we resize our previous TAGITEM table lpvTempPtr = ( LPTAGITEM )HeapReAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, pMetaTag->tagiItems, sizeof( TAGITEM ) * ( pMetaTag->uiNbItems + 1 ) ); if( lpvTempPtr == NULL ) // we handle a worse case scenario return FALSE; //we replace with the new pointer (if it has changed) pMetaTag->tagiItems = lpvTempPtr; //we alloc the new string to store our tag value //it will be freed by WMPTSE, so be sure to have it alloced yourself. //(no static string...) pMetaTag->tagiItems[ pMetaTag->uiNbItems ].MetaTagValue = HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( TCHAR ) * ( lstrlen( STING_FAN_ARTIST ) + 1 ) ); //we copy the tag value lstrcpy( pMetaTag->tagiItems[ pMetaTag->uiNbItems ].MetaTagValue, STING_FAN_ARTIST ); //we give WMPTSE the right tag Key (it must be a WMP_TAG_ string, see WMPTSE.h) pMetaTag->tagiItems[ pMetaTag->uiNbItems ].MetaTagWMPKey = WMP_TAG_ALBUMARTIST; //we increase our tagitem number pMetaTag->uiNbItems++; //all is finished, we can release the filepath string HeapFree( GetProcessHeap(), 0, lpcFileFullPath ); return TRUE; } BOOL STINGTAG_API WriteStingTag ( LPTSTR lpstrFileFullPath, TAGITEM tagiChangedItem ) { return TRUE; }
And the nice header to go with it
///////////////////////////////////////////////////////////////////////////// // // StingTagSupport.h : // Handler header for Sting tags support // // Copyxxx (\C) 200x - // ///////////////////////////////////////////////////////////////////////////// #ifndef STING_TAG_SUPPORT_H #define STING_TAG_SUPPORT_H #define WIN32_LEAN_AND_MEAN #define UNICODE #include <windows.h> #include "WMPTSE.h" #ifdef STING_TAGSUPPORT_C #define STING_FAN_ARTIST TCHAR( "Sting" ) #ifdef _USRDLL #define STINGTAG_API __declspec( dllexport ) #else #define STINGTAG_API #endif #else #ifdef _USRDLL #define STINGTAG_API extern __declspec( dllimport ) #elif defined( _EXPORTDLL ) #define STINGTAG_API extern __declspec( dllexport ) #else #define STINGTAG_API extern #endif #endif // // TODO : add your exportable function declaration here // // WMPTSE TagSupport API BOOL STINGTAG_API ReadStingTag ( LPTSTR lpstrFileFullPath, METATAG * pMetaTag ); BOOL STINGTAG_API WriteStingTag ( LPTSTR lpstrFileFullPath, TAGITEM tagiChangedItem ); #endif STING_TAG_SUPPORT_H
Installation
To be effective, a "tag support dll" must be correctly installed in WMPTSE.
You have two choice to install a "tag support dll" :
- use the WMPTSE tag support wizard (see WMPTSE - How to add support for a tag format)
- edit the registry yourself :
Note : In this guide, we will not expose the registry editing for complete file type support in Windows (MIME Types, Media Library Support, etc...). Please refer to Microsoft Windows Media Player documentation for this.
On load, WMPTSE browse the HKEY_LOCAL_MACHINE\SOFTWARE\piPOol\WMPTSE registry key.
Each subkey it finds will be consider a <TagFormat> definition.
Inside each subkey (or <TagFormat> definition), WMPTSE browse for file type support.
Each string in HKEY_LOCAL_MACHINE\SOFTWARE\piPOol\WMPTSE\<TagFormat> describe the file type to support (registry string name) and the path to the "tag support dll" to load (registry string value).
After reading all file types definitions, WMPTSE loads each "tag support dll" and try to get the Read<TagFormat>Tag and Write<TagFormat>Tag functions.
For each dll, If one of those two functions doesn't exist, the dll is considered non-WMPTSE API compatible and is unloaded.
It those two functions exist, the dll is registered as a "tag support dll" for the registered file type.