今回は、自分で準備したアイコンイメージを使って、トレイアイコンをアニメーション表示する方法を紹介しましょう。
手順としては、アニメーションをするのに必要なだけのアイコンオブジェクトを作成しておき、 Shell_NotifyIcon 関数を繰り返し呼び出して、アイコンを変更していきます。 Shell_NotifyIcon 関数についてはこれまでに使ってきているので、特に説明の必要はないでしょう。
問題となるのはアイコンの作成です。任意のイメージからアイコンを作成するのにはいくつか方法がありますが、今回はイメージリストからアイコンを作成する方法を使ってみることにしましょう。
手順は以下のようになります。
まずは、トレイアイコンのアニメーションに使用したいイメージをすべて含んだイメージリストを作成します。透明部分を持つアイコンを作成するために、イメージリストはマスク付きで作成しておきましょう。
イメージリストについては、『イメージリストを作成してみる』の項を参照してください。
イメージリストからアイコンを作成するには、 ImageList_GetIcon 関数を呼び出します。
HICON ImageList_GetIcon( HIMAGELIST himl, // イメージリストのハンドル int index, // イメージのインデックス UINT flags // 描画スタイル );
himl パラメータにはイメージリストのハンドルを、 index パラメータにはイメージリスト中におけるイメージのインデックスを指定します。今回はマスク部分を透明化したアイコンを作成したいので、 flags パラメータには 1 (ILD_TRANSPARENT) を指定します。
この関数は、戻り値として作成されたアイコンのハンドルを返します。すべてのイメージのアイコンを作成し、ハンドルを配列変数に格納しておきましょう。
今回は、タスクトレイに表示されたアイコン上でマウスクリックされたときに、ショートカットメニューを表示するようにしてみましょう。
すべてのイメージのアイコンを作成できたら、イメージリストはもう必要なくなります。したがって、 ImageList_Destroy 関数でイメージリストを破棄しておきます。
すでにタスクバーのステータスエリアに表示されているアイコンを変更するには、まず、 NOTIFYICONDATA 構造体の uFlags メンバに 2 (NIF_ICON) を指定し、 hIcon メンバに新しいアイコンハンドルを指定します。そして、 Shell_NotifyIcon 関数の第1引数(dwMessage パラメータ)に 1 (NIM_MODIFY) を指定します。
この関数では、アイコンイメージだけでなく、ツールチップ文字列を変更することもできます。この場合には、 NOTIFYICONDATA 構造体の uFlags メンバに 4 (NIF_TIP) を指定し、 szTip メンバには新しいツールチップ文字列を格納しておきます。
さて、実際にスクリプトを書いてみます。
アイコン用のイメージとして、以下の画像を使用します。このビットマップファイルは、1つのイメージサイズが 16×16 ピクセルで、それを横に4つつなげたものになっています。マスクを生成する色として、白(RGB値は 0xFFFFFF )を指定します。
(iconlist2.bmp)
#include "llmod.as" #module ;###### ビットマップオブジェクト作成モジュール ######### ;=============================================================== ; 描画中ウィンドウのイメージからビットマップオブジェクト(DIB)作成 ; CreateDIB p1, p2, p3, p4 ; p1 : HSPウィンドウx座標 ; p2 : HSPウィンドウy座標 ; p3 : 幅 ; p4 : 高さ ; stat : ビットマップのハンドルが返る ;=============================================================== #deffunc CreateDIB int, int, int, int mref px, 0 ; HSPウィンドウx座標 mref py, 1 ; HSPウィンドウy座標 mref sx, 2 ; xサイズ mref sy, 3 ; yサイズ mref stt, 64 ; stat mref bmscr, 67 ; 描画中ウィンドウのBMSCR構造体 ; DIBセクションオブジェクト作成 pm = bmscr.4, sx, sy dllproc "CreateCompatibleBitmap", pm, 3, D_GDI@ hbitmap = stat ; ビットマップオブジェクトのハンドル ; メモリデバイスコンテキスト作成 pm = bmscr.4 dllproc "CreateCompatibleDC", pm, 1, D_GDI@ hdcMemory = stat ; メモリデバイスコンテキストのハンドル ; ビットマップをデバイスコンテキストに選択 pm = hdcMemory, hbitmap dllproc "SelectObject", pm, 2, D_GDI@ ; HSPウィンドウからビットマップにイメージをコピー pm = hdcMemory, 0, 0, sx, sy, bmscr.4, px, py, $CC0020 dllproc "BitBlt", pm, 9, D_GDI@ ; デバイスコンテキストを削除 dllproc "DeleteDC", hdcMemory, 1, D_GDI@ stt = hbitmap ; ビットマップオブジェクトのハンドル return #global ;############# モジュール終わり ######################## #module ;######### イメージリスト操作モジュール ################ ;=============================================================== ; イメージリストの作成 ; CreateImageList p1, p2, p3, p4 ; p1 : イメージの幅 ; p2 : イメージの高さ ; p3 : イメージリストのタイプ ; p4 : イメージの数 ; stat : イメージリストのハンドルが返る ;=============================================================== #deffunc CreateImageList int, int, int, int mref sx, 0 ; イメージの幅 mref sy, 1 ; イメージの高さ mref flags, 2 ; イメージリストのタイプ mref num, 3 ; イメージの数 ; イメージリストの作成 pm.0 = sx pm.1 = sy pm.2 = flags pm.3 = num pm.4 = 0 dllproc "ImageList_Create", pm, 5, D_COMCTL@ return ;=============================================================== ; イメージリストに描画中ウィンドウのイメージ追加 ; AddImageList p1, p2, p3, p4, p5 ; p1 : イメージリストのハンドル ; p2 : HSPウィンドウx座標 ; p3 : HSPウィンドウy座標 ; p4 : 幅 ; p5 : 高さ ; p6 : マスクに用いる色 ; stat : イメージのインデックスが返る ;=============================================================== #deffunc AddImageList int, int, int, int, int, int mref himl, 0 ; イメージリストのハンドル mref cx, 1 ; x座標 mref cy, 2 ; y座標 mref sx, 3 ; xサイズ mref sy, 4 ; yサイズ mref crmask, 5 ; マスク生成に用いる色 mref stt, 64 ; stat ; DIBオブジェクトの作成 CreateDIB cx, cy, sx, sy hbitmap = stat ; ビットマップハンドル ; ビットマップをイメージリストに追加 pm.0 = himl pm.1 = hbitmap pm.2 = crmask dllproc "ImageList_AddMasked", pm, 3, D_COMCTL@ index = stat ; 最初のイメージのインデックス ; ビットマップオブジェクトを削除 dllproc "DeleteObject", hbitmap, 1, D_GDI@ stt = index ; イメージのインデックスをstatに格納 return ;=============================================================== ; イメージリストの破棄 ; DestroyImageList p1 ; p1 : イメージリストのハンドル ;=============================================================== #deffunc DestroyImageList int mref himl, 0 ; イメージリストのハンドル ; イメージリストを破棄 pm.0 = himl dllproc "ImageList_Destroy", pm, 1, D_COMCTL@ return ;=============================================================== ; イメージリストのイメージからアイコン作成 ; GetIconImageList p1, p2 ; p1 : イメージリストのハンドル ; p2 : イメージのインデックス ; stat : アイコンハンドルが返る ;=============================================================== #deffunc GetIconImageList int, int mref himl, 0 ; イメージリストのハンドル mref index, 1 ; イメージのインデックス ; アイコン作成 pm.0 = himl pm.1 = index pm.2 = 1 ; ILD_TRANSPARENT dllproc "ImageList_GetIcon", pm, 3, D_COMCTL@ return #global ;############# モジュール終わり ######################## ; トレイアイコン用のアイコンID #define ID_TRAYICON 1 ; トレイアイコン用のメッセージコード #define MYWM_TRAYICON 0x1000 #define ICON_SIZE_X 16 ; アイコンイメージの幅 #define ICON_SIZE_Y 16 ; アイコンイメージの高さ #define ICON_NUM 4 ; アイコンイメージの数 ; ビットマップファイルの読み込み buffer 2,,, 0 picload "iconlist2.bmp" ; 24bit DIB イメージリスト作成(マスクあり) CreateImageList ICON_SIZE_X, ICON_SIZE_Y, 0x0018 | 0x0001, ICON_NUM himl = stat ; イメージリストのハンドル ; イメージをイメージリストに追加(白を透過色に) AddImageList himl, 0, 0, ICON_SIZE_X*ICON_NUM, ICON_SIZE_Y, 0xFFFFFF ; アイコンハンドルを格納する変数 dim hicon, ICON_NUM ; イメージリストからアイコン作成 repeat ICON_NUM GetIconImageList himl, cnt hicon.cnt = stat loop ; イメージリストの破棄 DestroyImageList himl gsel 0 mref bmscr, 67 ; ウィンドウのBMSCR構造体 hwnd = bmscr.13 ; ウィンドウハンドル ; NOTIFYICONDATA 構造体 tooltext = "トレイアイコンのアニメーションのテスト" dim nid, 22 nid.0 = 88, hwnd, ID_TRAYICON, 1|2|4, MYWM_TRAYICON, hicon.0 poke nid, 24, tooltext ; ツールチップ文字列 ; タスクトレイにアイコンを追加 pm.0 = 0 ; NIM_ADD getptr pm.1, nid ; NOTIFYICONDATA 構造体アドレス dllproc "Shell_NotifyIconA", pm, 2, D_SHELL onexit *onQuit *mainloop wait 10 if wcnt > 5 { ; 次のアイコンに変更する gosub *ChangeIcon wcnt = 0 } wcnt++ goto *mainloop *ChangeIcon iconindex++ if iconindex >= ICON_NUM : iconindex = 0 ; NOTIFYICONDATA 構造体 dim nid, 22 nid.0 = 88 ; 構造体サイズ nid.1 = hwnd ; ウィンドウハンドル nid.2 = ID_TRAYICON ; アイコンID nid.3 = 2 ; NIF_ICON nid.5 = hicon.iconindex ; 新しいアイコンのハンドル ; タスクトレイのアイコンを変更 pm.0 = 1 ; NIM_MODIFY getptr pm.1, nid ; NOTIFYICONDATA 構造体アドレス dllproc "Shell_NotifyIconA", pm, 2, D_SHELL return *onQuit ; 終了時の処理 ; NOTIFYICONDATA 構造体(cbSize, uID のみセット) dim nid, 22 nid.0 = 88 ; 構造体サイズ(=88) nid.1 = hwnd ; ウィンドウハンドル nid.2 = ID_TRAYICON ; アイコンID ; タスクトレイからアイコンを削除 pm.0 = 2 ; NIM_DELETE getptr pm.1, nid ; NOTIFYICONDATA 構造体アドレス dllproc "Shell_NotifyIconA", pm, 2, D_SHELL ; アイコンの破棄 repeat ICON_NUM pm = hicon.cnt dllproc "DestroyIcon", hicon, 1, D_USER loop end