INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: Sample C# Interface Plugin - Broadcasting Playing Now for MSN  (Read 10981 times)

jbholtz

  • Recent member
  • *
  • Posts: 49

Well since I finally got this done and since this is probably a common interface plugin that people can use to get started I thought that I'd post this up.  With the new MC12 release I could not get the PlayingNow plugin's out there working.  I spent a good week googling all over to find all the interface stuff.

The code was built using Visual Studio C# 2005 .NET Express
1) I started with ChriZ wonderful template. (Thanks for all the work on this) NOTE:  Please reference ChriZ's doc which contains great info on how to register your plugin once done into both MediaCenter and the Registery.  VERY IMPORTANT

2) In the reference section of Solution Explorer I removed the MediaJukeBox reference and instead added a COM reference to the MediaCenter COM object (This should be the tlb file in the MediaCenter Directory)

3) Next I added using System.Runtime.InteropServices to the Libraries region
We need this so that we can access the standard Win32 API to send Messages to the Windows Live Messenger Application

4) The following code what then added to supply me with the Win32 API
        #region InteropServices
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, IntPtr lParam );
       
        [DllImport("user32.dll", EntryPoint = "FindWindowExA")]
        private static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);

        [StructLayout(LayoutKind.Sequential)]
        private struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            public IntPtr lpData;
        }
        private const int WM_COPYDATA = 0x4A;
        #endregion
You may see the above code using different parameters if you google around.  The above code though is more complete in that it uses IntPtr instead of int allowing you cross use on 32/64 bit machines

5) The Attributes region needed to change from MediaJukebox.MJAutomation to MediaCenter.MCAutomation (NOTE: lowercase medaCenterAutomation)
        private MediaCenter.MCAutomation mediaCenterAutomation;

6) Also a static COPYDATASTRUCT needs to be added.
        private static COPYDATASTRUCT data;

7) Next I added two helper Properties:
        #region Properties
        public MediaCenter.MCAutomation MediaCenterAutomation
        {
            get { return mediaCenterAutomation; }
        }
        public MediaCenter.IMJFileAutomation CurrentTrack
        {
            get
            {
                MediaCenter.IMJCurPlaylistAutomation playlist = MediaCenterAutomation.GetCurPlaylist();
                if (playlist != null)
                    return playlist.GetFile(playlist.Position);
                else
                    return
null;
            }
        }
        #endregion
Continued in next reply......
Logged

jbholtz

  • Recent member
  • *
  • Posts: 49
Re: Sample C# Interface Plugin - Broadcasting Playing Now for MSN
« Reply #1 on: April 11, 2007, 10:20:30 am »

8 ) Now I was finally ready to start coding the functionality.  First I needed to receive the events when a file was started/stoped playing.  Thus inside the Init function I added
            try
            {                 
                this.mediaCenterAutomation = mediaCenterReference;
                UpdateOnPlayerStateChange();
                // Set up a EventHandler to receive when Events happen
                mediaCenterAutomation.FireMJEvent += new MediaCenter.IMJAutomationEvents_FireMJEventEventHandler(mediaCenterAutomation_FireMJEventHandler);
            }
The += for the FireMJEvent adds to the list of Handlers MediaCenter will call.  If a = was used instead then essentially we are deregistering other plugins that have registered to receive Events.  The UpdateOnPlayerStateChange() function before registering for Events is there because there is a long period of time before the plugin will startup and the user may press play already and thus we will not get an event until the next track

9) The FireMJEventHandler() is rather simple.  We need to set the Text on Track change and also when the players state is changed
        private void mediaCenterAutomation_FireMJEventHandler(string bstrType, string bstrParam1, string bstrParam2)
        {
            switch (bstrType)
            {
                case "MJEvent type: MCCommand":
                    switch (bstrParam1)
                    {
                        case "MCC: NOTIFY_TRACK_CHANGE":
                            // Your code here
                            MediaCenter.IMJFileAutomation file = CurrentTrack;
                            if (file != null)
                                SetMSNMusic(true, file.Name, file.Artist, file.Album);
                            break;
                        case "MCC: NOTIFY_PLERSTATE_CHANGE":
                            // Your code here
                            UpdateOnPlayerStateChange();
                            break;

                        default:
                            // Unknown (new?) type
                            MessageBox.Show(bstrType + "-" + bstrParam1 + "-" + bstrParam2);
                            break;
                    }

                    break;

                default:
                    // Unknown (new?) type
                    MessageBox.Show(bstrType + "-" + bstrParam1 + "-" + bstrParam2);
                    break;
            }
        }

10) The UpdateOnPlayerStateChange() also is staightforward. 
  • Clear the Text when the player is stopped
  • Set the Text to the CurrentTrack info when Playing or Paused (Could add PAUSED to the text here)
        private void UpdateOnPlayerStateChange()
        {
            MediaCenter.IMJFileAutomation file = CurrentTrack;
            if (file != null)
                switch (MediaCenterAutomation.GetPlayback().State)
                {
                    case MediaCenter.MJPlaybackStates.PLAYSTATE_STOPPED:
                        SetMSNMusic(false, "", "", "");
                        break;
                    case MediaCenter.MJPlaybackStates.PLAYSTATE_PLAYING:
                        SetMSNMusic(true, file.Name, file.Artist, file.Album);
                        break;
                    case MediaCenter.MJPlaybackStates.PLAYSTATE_PAUSED:
                        SetMSNMusic(true, file.Name, file.Artist, file.Album);
                        break;
                    default:
                        SetMSNMusic(false, "", "", "");
                        break;
                }
        }

11) Now the real code that communicates with Windows Live Messenger.  It consists of two functions; the first creates memory for the data that will be passed, and the second actually finds the window and sends the data to the application.
NOTE:  If you look around there are other categorys that can be sent to the MsnMsgrUIManager (Games,Office,....) Instead of the headphones that appear, other icons appear.
        private static IntPtr VarPtr(object e)
        {
            GCHandle GC = GCHandle.Alloc(e, GCHandleType.Pinned);
            IntPtr gc = GC.AddrOfPinnedObject();
            GC.Free();
            return gc;
        }
        private void SetMSNMusic(bool enable, string title, string artist, string album)
        {
            string category = "Music";
            string buffer = "\\0" + category + "\\0" + (enable ? "1" : "0") + "\\0{0}-{1}\\0" + title + "\\0" + artist + "\\0" + album + "\\0\\0\0";
            int handle = 0;
            IntPtr handlePtr = new IntPtr(handle);

            data.dwData = (IntPtr)0x0547;
            data.lpData = VarPtr(buffer);
            data.cbData = buffer.Length * 2;

            // Call method to update IM's - PlayingNow
            handlePtr = FindWindowEx(IntPtr.Zero, handlePtr, "MsnMsgrUIManager", null);
            if (handlePtr.ToInt32() >0)
                SendMessage(handlePtr, WM_COPYDATA, IntPtr.Zero, VarPtr(data));
        }


And That's it!!
Logged

_PM_

  • Recent member
  • *
  • Posts: 8
Re: Sample C# Interface Plugin - Broadcasting Playing Now for MSN
« Reply #2 on: August 27, 2007, 12:24:52 pm »

Hi !
Do you know how to add the current cover to msn's display picture? I know CAD does that well.
Logged

Mr ChriZ

  • Citizen of the Universe
  • *****
  • Posts: 4375
  • :-D
Re: Sample C# Interface Plugin - Broadcasting Playing Now for MSN
« Reply #3 on: August 28, 2007, 03:16:56 am »

On behalf of everyone else in the coding community here, cheers for the code.
I've added a link to this article to the useful Interface information post.

PaulSinnema

  • Galactic Citizen
  • ****
  • Posts: 393
  • You don't know what you're missing until its gone
Re: Sample C# Interface Plugin - Broadcasting Playing Now for MSN
« Reply #4 on: August 28, 2007, 05:47:26 am »

I don't get it. All that (and more) is in the Template you can upload from my server. Here's a link http://yabb.jriver.com/interact/index.php?topic=40171.0
Logged

Mr ChriZ

  • Citizen of the Universe
  • *****
  • Posts: 4375
  • :-D
Re: Sample C# Interface Plugin - Broadcasting Playing Now for MSN
« Reply #5 on: August 28, 2007, 06:19:48 am »

I was refering to the bit of getting it to talk with MSN messenger

PaulSinnema

  • Galactic Citizen
  • ****
  • Posts: 393
  • You don't know what you're missing until its gone
Re: Sample C# Interface Plugin - Broadcasting Playing Now for MSN
« Reply #6 on: August 28, 2007, 02:11:31 pm »

Yeah... understand that, sorry, reacted to quick (again).

Paul.
Logged
Pages: [1]   Go Up