Anyway, I spent more time with the iTunes _IiTunesEvents interface, but apparently i'm too dense to understand how to use it...I have no problems detecting when COM is enabled/disabled, but you can't just do a simple Sleep() in your specified function, or it blocks up iTunes from doing anything else... the only think I could think of off the top of my head is to wrap every single call to the iTunes interface with a event sink, but it certainly doesn't seem to be a very intelligent way of doing things... maybe this is a job for multithreading? (something I know nothing about)
I'm willing to bet that you know more about it than I do. I don't grok COM yet. I learned a lot trying to code the EXE version (the magic of interfaces, for example, and how that magic is a PITA to work with), but I haven't tried to mess with events yet. I'm looking into it.
Finally, if you don't mind, might I ask what iTunesEncoder was written in? I've been toying with a C# version because its quite easy to gain access to the interfaces, but I don't quite grasp how to do that same thing in C++? (.Net is surely simple, but i'd rather have a native application).
I wrote it in Visual C++ 6.0. I simply used the two files they included in the COM SDK. Include the iTunesCOMInterface.h, do CoInitialize(NULL) to init COM, then do this to create the iTunes object:
HRESULT hRes;
IiTunes * iiTunes = NULL;
hRes = ::CoCreateInstance(CLSID_iTunesApp, NULL, CLSCTX_LOCAL_SERVER, IID_IiTunes, (PVOID *)&iiTunes);
Working with this crap in C++ is nowhere near as friendly as scripting or probably C# is. Consider the following:
IITEncoderCollection * encoderCollection = NULL;
hRes = iiTunes->get_Encoders(&encoderCollection);
IITEncoder * encoder = NULL;
hRes = encoderCollection->get_ItemByName(encoderName.AllocSysString(),&encoder);
if (hRes != S_OK || encoder == NULL)
{
// deal with error
And so on. Because the functions always return an HRESULT, it's not really too awful object oriented. If they returned something more like the script, that above code could become:
IITEncoder * encoder = iiTunes->get_Encoders()->get_ItemByName(encoderName.AllocSysString());
if (encoder == NULL)
{
// deal with error