【HSP】タスクトレイにアイコン表示【Win32】

【HSP】タスクトレイにアイコン表示【Win32】

既にたくさんネット上に HSP でタスクトレイにアイコン表示サンプルあるけど、ソースコードの書き方が気に入らないという理由だけで自作しました。自分的にはかなり見やすくかけた自身がある。
関係ない話になるけど、数々の HSP 入門サイトではやたらと「BASICライクな」って書いてあるけど、セミコロンがコメントだったり全部グローバル変数だったりして、どっちかというとアセンブリに近い気がする。BASIC をほとんどやっていないのが原因かもしれないけど。

#include "kernel32.as"
#include "shell32.as"
#include "user32.as"

// 
// メイン
// 
// 割り込み
RegisterWindowMessage "TaskbarCreated"
oncmd gosub *OnTaskbarCreated, stat // "TaskbarCreated"
oncmd gosub *OnClose, 0x0010 // WM_CLOSE
oncmd gosub *OnTrayIcon, 0x0401 // WM_TRAYICON

// タスクトレイにアイコン表示
gosub *AddTaskbarIcon

// テスト
/* ウィンドウ非表示 */
gsel 0, -1

stop

// 
// タスクトレイにアイコン表示
// 
*AddTaskbarIcon

// 自身のアイコン取得
sdim FileName, 260
GetModuleFileName hModule, varptr(FileName), 260
ExtractIconEx varptr(FileName), 0, 0, varptr(hIconSmall), 1
hIcon = hIconSmall(0)

// 自身のウィンドウタイトル取得
GetWindowTextLength hwnd
sdim WindowTitle, stat + 1
GetWindowText hwnd, varptr(WindowTitle), stat + 1

// NOTIFYICONDATA 構造体
dim IconData,22
IconData(0) = 88
IconData(1) = hwnd
IconData(2) = 1
IconData(3) = 0x0007 // NIF_MESSAGE | NIF_ICON | NIF_TIP
IconData(4) = 0x0401 // WM_TRAYICON
IconData(5) = hIcon
poke IconData, 4 * 6, WindowTitle

// タスクバーにアイコン表示
Shell_NotifyIcon 0x00000000, varptr(IconData) // NIM_ADD

return

// 
// タスクトレイのイコン削除
// 
*DeleteTaskbarIcon

// NOTIFYICONDATA 構造体
dim IconData,22
IconData(0) = 88
IconData(1) = hwnd
IconData(2) = 1
IconData(3) = 0x0002 // NIF_ICON

// タスクバーのアイコン削除
Shell_NotifyIcon 0x00000002, varptr(IconData) // NIM_DELETE

return

// 
// *OnTaskbarCreated
// 
*OnTaskbarCreated

// タスクトレイにアイコン表示
gosub *AddTaskbarIcon

return

// 
// *OnClose
// 
*OnClose

// タスクバーのアイコン削除
gosub *DeleteTaskbarIcon

return

// 
// *OnTrayIcon
// 
*OnTrayIcon

if (wparam == 1) {
switch (lparam)
case 0x0201 // WM_LBUTTONDOWN

// テスト
/* ウィンドウ表示 */
gsel 0, 2

swbreak
swend
}

return

※補足 (2014/08/27追記)

WM_CLOSE 発生時は、終了確認ダイアログを表示するときなどに使うべきであり、終了処理は WM_DESTROY 発生時に行うべきかもしれませんね…。そうすれば、 HSP の end 命令を使用した場合もちゃんと動いてくれますし…。
あと、実際に HSP 3.32 で確認したところ、PostQuitMessage(0); を自前でする必要はないようです。きちんとプロセス終了してました。
訂正場所

oncmd gosub *OnClose, 0x0010 // WM_CLOSE

oncmd gosub *OnDestroy, 0x0002 // WM_DESTROY

// 
// *OnClose
// 
*OnClose

// タスクバーのアイコン削除
gosub *DeleteTaskbarIcon

return

// 
// *OnDestroy
// 
*OnDestroy

// タスクバーのアイコン削除
gosub *DeleteTaskbarIcon

return

説明

  1. タスクトレイのアイコンとメッセージを自分で指定するのは面倒なので、自身の実行ファイルのアイコンと、ウィンヅタイトルを利用することに。
  2. タスクバーの強制終了、再起動時にアイコンを再生成。
  3. 「表示」でなく「格納」したい場合は、普通にアイコンの表示/非表示処理とウィンドウの表示/非表示処理を交互に入れればいいです。
こんな感じの代物です。
ちなみに、自分流の HSP のソースコードの書き方
  1. すべて関数でなく命令になってしまうものの、APIの関数の定義をズラッと書くと長くなるので、できるだけ既存のヘッダを使う。
  2. マクロ定義も長くなるので、定数を書き、その後ろにコメントで本来のマクロ名を書く。
  3. if文 は C っぽく カッコ をつける。中身は インデント 1
  4. switch, case, swend は同じ数のインデント、case の中身と swbreak はさらにもうひとつインデント (swbreak も中身と考えて)
  5. メインプログラム および サブルーチンは、ラベルはインデントなし、中身はインデント 1つ目 から。(メインプログラム も 1つ のルーチンであると考えて)。#deffunc #defcfunc も同様
  6. repeat (foreach) loop 内は インデント 1
repeat (foreach) と loop のように、case と swbreak や、ラベル と return を同じインデントにして中身を挟んだ感じにする、という風にしないのは、必ずしも対応している必要がないからです。swbreak を省略して、複数の case で同じ処理をさせられるし、return は、C や アセンブリで、プログラムの中身として扱うことのほうが多い気がしたからです。
なんか関係ない話が多くなっちゃいましたが、ひさしぶりにまともそうなプログラムがかけて楽しかったです。
ではまたいつか。ノシ
↓ブログランキング投票 (クリック) お願いします~。

参考