最近のMSN Messenger1やLive Messengerには、Windows Media Player(以下WMP)やiTunesで再生中の曲のタイトルを表示する機能があります。
しかし僕はWMPもiTunesも使っていないので、この機能を利用することが出来ません。
ということで、前回のmixi station同様、MSN Messengerに通知する機能も自作のプレイヤーに組み込んでみました。
上のスクリーンショットの、赤枠で囲った部分が、再生中の曲を表示している部分です。
送信方法は、mixi stationのときと同様に、WMPに組み込まれたプラグインが、MSN Messengerに曲情報を送るという仕組みのようです。
とはいえ自分で調べるのは面倒なので、今回も偉人の力を借ります。:p
この記事によると、どうやら送信は次のようにして行っているようです。
以下引用。
- MsnMsgrUIManagerクラスに対してメッセージを送信している
- メッセージの種類は WM_COPYDATA
- COPYDATASTRUCT構造体は以下のように使う
- dwData : 1351 (固定)
- cbData : データの長さ(NULL含)
- lpData : データへのポインタ
- データには以下の内容を、それぞれ「\0」(NULLでは無くただの文字)で連結し、UTF-16にエンコードしたものを使用する
- アプリ名 : 自分のアプリ名です。ちなみに、iTunesは「ITunes」が、WMPでは空です。
- Music : 文字列「Music」を指定します。
- 1 または 0 : これは、終了を通知するものです。0を指定して送ると、以後は表示メッセージ欄には楽曲名は表示されません。
- 表示書式 : 曲名やアーティストを表示するときの書式です。デフォルトは「{0} - {1}」です。
- 曲名 : 曲名です。書式の {0} に展開されます。
- アーティスト : アーティストです。書式の {1} に展開されます。
- アルバム : アルバム名です。書式の {2} に展開されます。
- (検証してないけど、↑この辺は\0区切りで延々続けられるかも・・?)
引用元にも書いてありますが、区切り文字として扱っている「\0」は、ヌル文字ではなく "\\0" ですので、注意してください。2
これらを元に、MSN Messengerに曲情報を送るプログラムを、C#で書いてみました。
以下はその一部です。
C/C++で書きたい場合は、上で挙げた参考にしたページにC++のサンプルソースがありましたので、そちらを参考にしてください。
using System; using System.Runtime.InteropServices; private const int WM_COPYDATA = 0x004A; private struct COPYDATASTRUCT { public int dwData; public uint cbData; public IntPtr lpData; } [DllImport("user32.dll")] private extern static IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] private extern static int SendMessage(IntPtr hWnd, int msg, int wParam, ref COPYDATASTRUCT lParam); private void SendToMsnMsgr(string title, string artist) { // MsnMsgrUIManagerクラスを検索 IntPtr msgr = FindWindow("MsnMsgrUIManager", null); // 発見したら if (msgr != IntPtr.Zero) { // 曲データの連結 string buf = @"myplayer\0Music\01\0{0} - {1}\0" + title + @"\0" + artist + @"\0\0"; // COPYDATASTRUCT構造体 COPYDATASTRUCT cds; cds.dwData = 1351; // マジックナンバー cds.cbData = (uint)(buf.Length + 1) * 2; // データのサイズ cds.lpData = Marshal.StringToHGlobalUni(buf); // データへの参照 // Messengerに対してWM_COPYDATAメッセージを送る Win32API.SendMessage(msgr, WM_COPYDATA, 0, ref cds); // メモリの解放 Marshal.FreeHGlobal(cds.lpData); } }
Hello, About removing the song from the msgr:
public void RemoveSongFromMsnMsgr()
{
IntPtr msgr = FindWindow("MsnMsgrUIManager", null);
if (msgr != IntPtr.Zero)
{
string buf = @"myplayer\0Music\00\0 – \0" + @"\0" + @"\0\0";
// COPYDATASTRUCT
COPYDATASTRUCT cds;
cds.dwData = 1351;
cds.cbData = (uint)(buf.Length + 1) * 2;
cds.lpData = Marshal.StringToHGlobalUni(buf);
SendMessage(msgr, WM_COPYDATA, 0, ref cds);
Marshal.FreeHGlobal(cds.lpData);
}
}