XREA.COM Logo XREA.COM Ad

旧雑記サルベージ

106管理人 ★:06/09/06 17:46 ID:???
2006年02月23日
■AutoHotkeyでタスクトレイアイコンを直接操作
TaskTrayIcon.zip(http://lukewarm.s101.xrea.com/myscripts/TaskTrayIcon.zip)
TrayCommand(http://hp.vector.co.jp/authors/VA026310/)のように擬似的にタスクトレイアイコンの操作イベントを発生させたりするために作ってみた。

タスクトレイにアイコンを登録するとき、タスクトレイアイコンの操作イベントが発生したときに通知するウィンドウのハンドルと、そのときに送るウィンドウメッセージの番号、複数のアイコンがあるときに識別するための番号などが登録される。
これらの情報が分かれば、スクリプトからタスクトレイアイコンの操作イベントを発生させることが可能になるはずである。

TrayCommandの動作を見たところ、タスクトレイのアイコンが表示されているToolbarWindow32からTB_GETBUTTONメッセージで情報を取得しているらしい。
TB_GETBUTTONでは、ツールバーの項目の情報を格納した構造体が得られるらしい。
構造体にはdwDataというメンバがあり、アプリケーションが独自に何らかのデータを関連づけておけるようになっている。
おそらく、ここにウィンドウハンドルやアイコンの識別番号、メッセージなどが格納されているのだろう。

構造体のデータ構造がよく分からなかったが、TrayExpandのソースを調べたら見つかった。
Shell_NotifyIconで使われている構造体とは構造が違うようだが、内部データ用の形式だろうか?
このような情報はどこで仕入れてくるのか。
typedef struct _TRAYNOTIFY{
    HWND    hWnd;
    UINT    uID;
    UINT    uCallbackMessage;
    DWORD    dwInfoFlags;
    DWORD    dwDammy;
    HICON    hIcon;
}TRAYNOTIFY;

これで、必要な情報と、ついでにアイコンのハンドルが得られそうだ。

他のプロセスからウィンドウメッセージなどで構造体のデータをやりとりするときは、VirtualAllocExで当該プロセスに共有メモリを確保し、そこにデータを受け取ってからReadProcessMemoryで読み取らなくてはならないらしい。
うっかりGlobalAllocで確保したメモリに受け取ろうとしたら、エクスプローラがメモリアクセスエラーで不正終了してしまった。


アイコンの数については、TB_BUTTONCOUNTメッセージで簡単に取得できる。

そんな感じで、任意のトレイアイコンの情報を取得する関数と、アイコンの数を取得する関数を作成した。
アイコンの数だけループして、条件に一致したときに指定の操作イベントを通知するようにすれば、TrayCommandのように指定したアプリケーションのトレイアイコンを操作することができるようになる。

プロセスの実行ファイルパスを取得する関数をコピーしてくるのが面倒だったので、サンプルでは「WinGet,pn,ProcessName」の結果のプロセス名を使用して判定するようにした。



TrayExpandのようにアイコンを隠す機能も作ろうと思ったが、TB_HIDEBUTTONで非表示にすると、消したアイコンの分のスペースが空いてしまう。
そこで、Shell_NotifyIconで状態を非表示に設定することにした。
これなら、スペースをちゃんと調節してくれる。
Shell_NotifyIconに与える情報は、先ほどの関数で取得したhWndやuIDを使用すればいい。
別のプロセスのアイコンの状態を勝手に変更できてしまうとは、結構いい加減なAPIだ。

ついでに、TB_MOVEBUTTONでアイコンの順番を入れ替える関数も作った。
スタートアップの実行タイミングやプログラムの再起動でアイコンの順番が変わってしまうのは鬱陶しいので便利かも。
131KB
名前: E-mail:
ファイル:
0ch BBS 2005-10-08