Windows Media PlayerとLive Messengerを使って、再生中の音楽情報にLive Messengerの表示メッセージを変える機能があるよね。Windows Media Player側では、Windows Live Messenger ミュージック プラグインという名前が付いています。
これを自アプリケーションから変えようって話し。この機能はMSN Messengerと呼ばれていた時代からありまして……、答えは MsnMsgrUIManager でググれ! はい、終了。嘘です。私は、ググって 長時間はまってしまったので少し書いておきます。
まずは、たいへん参考になるページ。ほんと検索したらいっぱい出ます。
方法は、MsnMsgrUIManager というクラス名を持つウィンドウにCOPYDATASTRUCT構造体のデータをSendMessageを使ってメッセージを送信します。
詳しくは各ページでってことで、いきなりVB.NETのコードを置いておきます。続きはコードの後に。
Imports System.Runtime.InteropServices
Public Class PersonalMessage
Private Const WM_COPYDATA As Integer = &H4A
Public Enum MessageType
Music
Games
Office
End Enum
<StructLayout(LayoutKind.Sequential)> _
Structure COPYDATASTRUCT
Public dwData As Int32
Public cdData As Int32
Public lpData As IntPtr
End Structure
<DllImport("user32")> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByRef lParam As COPYDATASTRUCT) As Integer
End Function
<DllImport("user32")> _
Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, ByVal lclassName As String, ByVal windowTitle As String) As IntPtr
End Function
Public Shared Sub Show(ByVal applicationName As String, ByVal type As MessageType, ByVal format As String, ByVal parameters() As String)
Dim list = New List(Of String)
list.Add(applicationName)
list.Add(type.ToString)
list.Add("1")
list.Add(format)
list.AddRange(parameters)
ChangeMessage(String.Join("\0", list.ToArray) & "\0\0" & vbNullChar)
End Sub
Public Shared Sub Delete(ByVal applicationName As String, ByVal type As MessageType)
Dim list = New List(Of String)
list.Add(applicationName)
list.Add(type.ToString)
list.Add("0")
ChangeMessage(String.Join("\0", list.ToArray) & "\0\0" & vbNullChar)
End Sub
Private Shared Sub ChangeMessage(ByVal message As String)
Dim messengers = New List(Of IntPtr)
Dim chiledAfter = IntPtr.Zero
Do
chiledAfter = FindWindowEx(IntPtr.Zero, chiledAfter, "MsnMsgrUIManager", Nothing)
If chiledAfter <> IntPtr.Zero Then
messengers.Add(chiledAfter)
End If
Loop Until (chiledAfter = IntPtr.Zero)
If messengers.Count = 0 Then
Exit Sub
End If
Dim cds As New COPYDATASTRUCT With { _
.dwData = 1351, _
.cdData = System.Text.Encoding.Unicode.GetByteCount(message), _
.lpData = Marshal.StringToHGlobalUni(message)}
For Each m In messengers
SendMessage(m, WM_COPYDATA, IntPtr.Zero, cds)
Next
Marshal.FreeHGlobal(cds.lpData)
End Sub
End Class
メソッド名や引数がいまいちな感じがしてるコードなので、あまり参考にはしないでください。すごい単純ぽいんだけど、これにすごいはまりました。64bit環境で開発している場合は、ターゲットCPUはx86にして実行しましょう! 気づくのにだいぶかかりましたよ。
あと、MsnMsgrUIManager はなんらかの原因で落ちてない場合もあるようです。Live Messengerを再起動しましょう。また、MsnMsgrUIManager というクラス名を持つソフトを作って、Windows Media Playerなどからの情報を受け取るアプリもあるようです。そのようなのも考慮してあげると MsnMsgrUIManager を持つウィンドウすべてにメッセージ送るのが良いかもしれません。上のコードではそうしてます。
これを調べようと思ったのは、表示メッセージにリンクを表示できないかという質問が某フォーラムにあったからです。結論からいうと無理みたいですね。通常の表示メッセージもできませんし、この外部アプリから設定も単に文字列を指定できるだけです。メッセージの種類として音楽、ゲーム、Officeが選べ、音楽の場合のみリンクとして表示されます。リンクをクリックするとWindows Media PlayerかLive Messengerの設定によりオンラインショップでの検索か、Live Searchの検索になるようです。ここを利用すると単語の検索には使えそうですがイマイチ有用な感じではありませんね。