"再生中の曲"を表示 @MSN Messenger

この記事は最終更新日から 20 年以上が経過しています。

最近のMSN Messenger1やLive Messengerには、Windows Media Player(以下WMP)やiTunesで再生中の曲のタイトルを表示する機能があります。
しかし僕はWMPもiTunesも使っていないので、この機能を利用することが出来ません。

ということで、前回のmixi station同様、MSN Messengerに通知する機能も自作のプレイヤーに組み込んでみました。

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);
    }
}

  1. Version 7.0からだったかな? ↩︎

  2. 僕はこれを見落としててずいぶん悩んだ。^^; ↩︎