〜 ウィンドウ 〜
タイトルバーのアイコンを変更

通常、起動したウィンドウのタイトルバーアイコンはEXEのアイコンが表示されます。
今回はこの「タイトルバー左端に表示される小さなアイコン画像を変更する」Tipsです。
変更するにはウィンドウズに標準搭載しているUser32.DLLのAPI関数LoadImageを使いましょう。
API関数LoadImageを使い終わった後は明示的に解放したほうがリソースメモリの節約になりますが、
HSPウィンドウを閉じて終了させると自動的に解放しますので、ココでは解放せずに変更のみ行います。
LoadImageは第1引数から順に「インスタンスハンドル」「イメージリソースIDまたはリソース名」
「イメージタイプ」「表示幅」「高さ」「読込方法」をそれぞれ指定します。
今回のようにファイルから読み込む場合は実行モジュールのインスタンスハンドルは指定しません。
リソース名パラメータにはファイルパスを格納した変数ポインタを指定しておきましょう。
イメージタイプには以下のいずれかより指定ということでIMAGE_ICON(=0x0001)を指定します。
IMAGE_BITMAP0x0000ビットマップ
IMAGE_ICON0x0001アイコン
IMAGE_CURSOR0x0002カーソル
表示幅と高さには0を指定するとシステム寸法が自動的に設定されるので0を指定します。 読込方法には以下の定数の組み合わせということでLR_LOADFROMFILE(=0x0010)を指定します。
LR_DEFAULTCOLOR0x0000デフォルトカラーを使用
LR_MONOCHROME0x0001イメージを白と黒のモノクロカラーで読み込む
LR_LOADFROMFILE0x0010イメージリソースはファイル名
LR_LOADTRANSPARENT0x0020イメージの最初のピクセルと同一色を全てCOLOR_WINDOWに置き換える
LR_DEFAULTSIZE0x0040アイコン・カーソルはシステムサイズを使用、指定しない場合はリソースサイズを使用
LR_VGACOLOR0x0080標準16色のVGAカラーを使う
LR_LOADMAP3DCOLOR0x1000カラーテーブルを検索して特定の灰色を指定色と置き換える
LR_CREATEDIBSECTION0x2000タイプがビットマップの時はDIBSectionビットマップを返す
LR_SHARD0x8000同じリソースをロードしたときハンドルを共有する
尚、API関数LoadImageはアイコン等の画像を使用できるように準備するだけのものであるため、 特定箇所に描画させるには別の命令・関数を使用する必要があります。 「WM_SETICON(=0x0080)」をメッセージ送信することでタイトルバーのアイコンを変更できるので、 objsend命令(HSP2)、sendmsg命令(HSP3)を使用してHSPウィンドウにメッセージ送信を行います。 HSP3ではシステム変数から取得できますが、HSP2ではBMSCR構造体からしか取得ができません。 何より、objsend命令はHSP3のsendmsg命令と同じ内容であるものの、 メッセージの送信先対象がコントロール(HSPでのオブジェクト)に限定されており、 パラメータに指定するのは1つ目のオブジェクトを0としたオブジェクトIDとなっています。 コレは表向きなもので、実はオブジェクトIDを指すというより、 BMSCR構造体の要素41(hCld)からの要素番号を指しているので、 ウィンドウハンドルが保持されている要素13(hwnd)を指せば、ウィンドウを指定したことになるのです。 HSP2「objsend 13 - 41, 0x0080, 0, イメージハンドル, 1」 HSP3「sendmsg hwnd, 0x0080, 0, イメージハンドル」 もし、マルチプルアイコンやアイコンライブラリのような複数アイコン入っているファイルの 0番目以外のアイコンを使いたい場合はAPI関数LoadImageではロードできません。 コチラで紹介しているExtractIconExを使ってください。

titleicon アイコン
アイコンタイトルバーに表示させるアイコンファイルパスを指定する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
	ll_libload user, "user32.dll"
	ll_getproc LoadImage, "LoadImageA", user

#module
#deffunc titleicon str
	mref file, 32
	prm = 0, 0, 1, 0, 0, 0x0010
	ll_getptr file : ll_ret prm.1
	ll_callfunc prm, 6, LoadImage@
	ll_ret prm
	objsend -28, 0x0080, , prm, 1
	return
#global

	dialog "ico", 16, "変更後のアイコン"
	if stat : titleicon refstr
	stop

titleicon アイコン
アイコンタイトルバーに表示させるアイコンファイルパスを指定する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#uselib "user32.dll"
#func  global LoadImage "LoadImageA" int, str, int, int, int, int

#module
#deffunc titleicon str file
	LoadImage 0, file, 1, , , 0x0010
	sendmsg hwnd, 0x0080, , stat
	return
#global

	dialog "ico", 16, "変更後のアイコン"
	if stat : titleicon refstr