日記帳だ! with Tux on Libserver

二度目の大改造!! 日記帳…か?を継承し、より柔軟でパワフルなBlogに変身しました。

RSSに対応しています。リンク・コメント・トラックバックは自由にしていただいてほぼ問題ありません。
RSS購読方法、僕のリンク・コメント・トラックバックについての考えを読むことをおすすめします。

<< 過去

未来 >>

Live Messengerを操作するライブラリを作る

Windows Live MessengerはきっとWindows Liveのソフトウエアでもっとも使われているでしょう。
IMとしてはYahoo! Messengerの方が好きなんだけど、かなりの友人がMSN Messengerの時代から使っていて、
それに合わせて僕もWindows Live Messengerを導入しています。
ちなみにLive IDは持ってますが、Hotmailは使ってませんよ。
新しくメールアドレスを作る必要がないので、わかってもらいやすいのでおすすめ。
さて、このLive Messengerのおもしろい機能というと、表示メッセージの機能。
僕はずっと表示名を「Hidemaro ◆3rRY3LJ8tc」としている。
まぁ当然なんだけど、これに加えて、「キーボード故障中」ということを知らせたい。
そんなとき、この表示メッセージ欄に書くといいと。
表示メッセージはメイン画面で簡単に変更することができるので便利。
けど、近所の人は、「Hidemaro ◆3rRY3LJ8tc //キーボード故障中」とかする人が多いですね。
この表示メッセージに対応してないクライアントもあるからですね。
しかし、気軽に使えるというのがこのいいところです。あまり大切な事は書かない方がいいです。
ここを音楽の再生に合わせて変えることができる。
Windows Media Playerを筆頭に多くのソフトウエアが対応してる。ユーザーによる対応も多い。
foobar2000においては、MSN Now Playingなどのプラグインで対応することができる。
仕組みだがどうも知られているらしい。
.NET FrameworkからもDllImportすれば使えるようだ。
yuuAn's Note / "再生中の曲"を表示 @MSN Messenger:あたりを参考にやってみた。
ところで調べてみたのだが、この送信モードは三種類あると。
Musicは音楽、Gamesはゲーム、Officeはよくわからない。
よくわからないのでOfficeを専ら使ってみるけど、まぁGamesで、「SimCity4」とか表示するのもいいかもしれない。
せっかくなのでライブラリを作ってみた。
Win32APIの操作を.NET Frameworkから簡単に取り扱うことのできるクラスですね。
namespace hidemaro {
/// <summary>Windows Live Messengerに状態を送信するクラスです。</summary>
public class livehack {
private IntPtr mylive;
private mode curmode;
/// <summary>コンストラクタです。Live Messengerのハンドルを確保します。</summary>
public livehack(mode curmode) {
this.mylive=FindWindow("MsnMsgrUIManager",null);
if (mylive==IntPtr.Zero) throw new NullReferenceException("送信先が見つかりません");
this.curmode=curmode;
}
/// <summary>送信モードの列挙型です。</summary>
public enum mode {
/// <summary>音楽モードです。</summary>
Music,
/// <summary>ゲームモードです。</summary>
Games,
/// <summary>Officeモードです。</summary>
Office
}
/// <summary>状態を送信します。</summary>
/// <param name="str">送信する文字列</param>
public void send(string str) {
datastruct data=new datastruct(
string.Format(@"livehack\0{0}\01\0{1}\0\0\0",this.curmode,str));
try { SendMessage(mylive,0x004A,0,ref data); } finally { data.Dispose(); }
}
/// <summary>状態を解除します。</summary>
public void remove() {
datastruct data=new datastruct(
string.Format(@"livehack\0{0}\00\0\0\0\0",this.curmode));
try { SendMessage(mylive,0x004A,0,ref data); } finally { data.Dispose(); }
}
/// <summary>デストラクタです。</summary>
~livehack() {
this.remove();
}
private struct datastruct : IDisposable {
public int dwData;
public uint cbData;
public IntPtr lpData;
public datastruct(string str) {
this.dwData=1351;
this.cbData=(uint)(str.Length+1)*2;
this.lpData=System.Runtime.InteropServices.Marshal.StringToHGlobalUni(str);
}
public void Dispose() {
System.Runtime.InteropServices.Marshal.FreeHGlobal(this.lpData);
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private extern static IntPtr FindWindow(string lpClassName,string lpWindowName);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private extern static int SendMessage(IntPtr hWnd,int msg,int wParam,ref datastruct lParam);
}
}
まぁ具体的な使用例はあまり書かなくてもOKだろう。
livehackクラスのコンストラクタでmodeを指定して、インスタンスを作って、
それで文字列をsendすればいいと。プログラムを終了する前には必ずremoveするようにしてほしい。
一応忘れても大丈夫なように~livehackというデストラクタを用意してある。
けどデストラクタはいつ呼びされるかよくわからない。まぁ念のために用意しておいただけです。
まぁIDisposableを実装しておいてusing構文を使いましょうとまでは言わないけど、忘れないようにね。
そもそも複雑な操作じゃないけど、これならかなり扱いいいですね。
IronPythonとか.NETを取り扱うことのできるスクリプト言語なら、気軽に書くだけでLive Messengerを操作出来る。
さて、実際の動作だが、あらかじめ、user32.dllより、FindWindow、SendMessageの2つの関数を読み込んでいる。
まぁこういうことができるのは.NETの強みではありますよね。
それでコンストラクタでFindWindowを用いて、送信先を探す。まぁいい加減だがこれでOK。
もし見つからなかったらNullReferenceExceptionがスローされる。なんでやねんと言われそうだが。
実際の送信だが、送信する文字列はこんな具合で書く。
Application\0Mode\01\0Format\0Title\0Artist\0Album
ここで下線を引いたものは自分で当てはめて欲しいという意味。
\0はU+005CとU+0031の二文字のことで、NULL文字ではないので注意!
1つ目にアプリケーション名。今回は全部livehackです。2つ目はモード。
3つ目はわかりにくいが、1です。送信するときは1で、消去するときは0です。
消去の時は以後の項目は何も書かなくてOKです。けど\0は残しておかないとなんかうまくいきません。
4つ目はフォーマット。実は今回全部ここに押し込めてあります。Musicのときは{0} - {1}を指定するのが多い。
5つ目はタイトル、6つ目はアーティスト名、7つ目はアルバム名。それぞれFormatの{0},{1},{2}に展開される。
もし{0},{1},{2}を使わないにしても\0は消さずに残しておく。じゃないとうまくいかない。
実は音楽モードで送信もできるけどあまりおすすめしない。{0},{1}を使ったものを作って欲しい。
文字列などを納めるdatastruct構造体だが、結構わかりにくい構造ですね。
ここで文字列だが、UTF-16の配列としてアンマネージドな領域に送られた。
その加減でかならず破棄しないといけない。けど構造体なのでデストラクタを使うわけにもいかない。
それでIDisposableを実装してみたが、SendMessageで送信するとき、refキーワード付きなのでusing構文が使えない。
使うところはlivehackクラス内2箇所だけなので、その部分ではtry~finally構文で書いてあげた。
構造体をrefで渡すというのはC#では流行らんが、Cではよく使われた技です。
構造体の分のメモリをmallocで確保して、ポインタばっかり使うと。C++・Java・C#で言うクラスみたいなもんです。
まぁ流行らんわなぁ…
それでSendMessageで送信すれば反映されると。めでたしめでたし。
まぁこんな仕組みでして、一から作ってもすぐできます。
しかしよくわからないCの世界をC#で見るのは非常にわかりにくい。
なのでこういう風にクラスを作って、それを専ら使うのが便利だとおもいます。
livehack.lzh (3.37KB)
まぁこれを展開して、適当なところに置いて、参照設定にファイルの参照で追加すれば使えます。
多分XML Documentationも読めると思う。
参考になればと思って、適当なサンプルを付けています。IDEを使わずに書いたからめんどくさかった。
ちなみにこれのコンパイル法はVisual Studioコマンドプロンプトなどを用いて次のようにする。
csc test.cs /r:livehack.dll
まぁこんな具合です。DLLも簡単に読み込めていいですね。
Author : Hidemaro
Date : 2008/09/25(Thu) 22:19
コンピュータ・インターネット | Comment | trackback (0)
blog comments powered by Disqus

トラックバック

トラックバックURL取得

Tools