〜 オブジェクト 〜
ボタンに画像貼り付け (要USER32.DLL)

HSP2のllmodに「ボタンに画像データを貼り付ける命令」がありましたが、
このTIPSは別のAPIを用いてボタンに画像を表示させるサンプルで、
また、画像データ読込用のバッファを使わず、直接指定ファイルからボタンに転送するというものです。
処理としてはまず、「BS_ICON(=0x0040)」でアイコン対応、
「BS_BITMAP(=0x0080)」でビットマップ対応スタイルをAPI関数SetWindowLongで適用しています。
(画像スタイル以外はGetWindowLongで現在のスタイルを取得)
次にOEMリソースからではなく「LR_LOADFROMFILE(=0x0010)」でファイルから読み込むように指定した
LoadImageAPIを使って画像ファイルからロードしたデータのポインタを取得して、
最後に、SendMessage(HSP2はobjsend命令、HSP3はsendmsg命令)で対象オブジェクトに
「BM_SETIMAGE(=0x00F7)」メッセージを送信して表示させています。
LoadImageAPIの第3パラメータ(uType)は、BMP、アイコン、カーソルとで指定する値が違います。
BMPの時は「IMAGE_BITMAP(=0x0000)」、アイコンは「IMAGE_ICON(=0x0001)」、
カーソルは「IMAGE_CURSOR(=0x0002)」を指定するように指示されていますが、
BMPの時は0(=IMAGE_BITMAP)、アイコンとカーソルは1(=IMAGE_ICON)でも動いているようです。
同様に、オブジェクトへメッセージ送信する際にも、wParamにイメージタイプを指定しなければなりません。
定数も同様で、BMPは0(=IMAGE_BITMAP)、アイコンとカーソルは1(=IMAGE_ICON)を指定します。
lParamLoadImageAPIの戻り値であるポインタ値をそのまま渡す形となるので、
HSP2のobjsend命令第5パラメータには変数アドレスではなく、値そのものを渡す1を指定してください。

HSP2「objsend オブジェクトID, 0x00F7, 0(=BMP) or 1(=ICO ,CUR), 読込画像のポインタ, 1」 HSP3「sendmsg オブジェクトハンドル, 0x00F7, 0(=BMP) or 1(=ICO ,CUR), 読込画像のポインタ

尚、サンプルで使用しているAPI関数LoadImageは、BMP(DIB)とICO、CUR形式のみの対応で、 JPGやPNG等の別形式も読み込めるようにするには、従来のGDI機能を拡張したGDI+を使います。 現在確認できている問題が一点。。。 BMPの画像表示後にアイコンかカーソルを表示する、またはアイコン・カーソルの後に画像表示させると、 エラーにはならないもののうまく表示できていないようです。問題わかる方、ご一報いただければと思います。 BMPだけ、アイコン・カーソルだけを複数回読み込むことは正常にいっています。 LoadImageAPIでロードしたものは解放しなくてもよいはずですが…この辺が問題? HSP3.2からボタンに画像を貼り付けられるobjimage命令が標準命令として追加されています。 コレを使うことで、ボタンの背景を替えられるだけでなく、ボタンにマウスオーバーした時、 ボタンが押された時にもそれぞれ設定したボタン画像を表示させることが出来ます。 詳しくは入門講座をご覧ください。

loadbuttonimage オブジェクトID, ファイルパス
オブジェクトID画像貼付対象ボタンを指定する。
ファイルパス貼付対象の画像(BMP,ICO,CUR)を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
	ll_libload user, "user32.dll"
	ll_getproc GetWindowLong, "GetWindowLongA", user
	ll_getproc SetWindowLong, "SetWindowLongA", user
	ll_getproc LoadImage, "LoadImageA", user

#module
#deffunc loadbuttonimage int, str
	mref id, 0 : mref file, 33
	mref bmscr, 67
	getpath k, file, 2
	if k = ".bmp" : flg = 0 : else : flg = 1
	i = id + 41 : i = bmscr.i
	prm = i, -16
	ll_callfunc prm, 2, GetWindowLong@
	ll_ret i
	prm.2 = 0x0080 - (0x0040 * flg) | i
	ll_callfunc prm, 3, SetWindowLong@
	ll_getptr file : ll_ret i
	prm = 0, i, flg, 0, 0, 0x0010 // LR_LOADFROMFILE
	ll_callfunc prm, 6, LoadImage@
	ll_ret i
	objsend id, 0x00F7, flg, i, 1 // BM_SETIMAGE
	return
#global

	objsize 120, 90
	pos 10, 10 : button "画像指定", *change
	stop

*change
	dialog "bmp;*.ico;*.cur", 16, "ボタンに表示する画像"
	if stat = 1 {
		loadbuttonimage 0, refstr
	}
	stop

loadbuttonimage オブジェクトID, ファイルパス
オブジェクトID画像貼付対象ボタンを指定する。
ファイルパス貼付対象の画像(BMP,ICO,CUR)を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#uselib "user32.dll"
#cfunc global GetWindowLong "GetWindowLongA" int, int
#func  global SetWindowLong "SetWindowLongA" int, int, int
#cfunc global LoadImage "LoadImageA" int, str, int, int, int, int

#module
#deffunc loadbuttonimage int id, str file, local flg, local h
	if getpath(file, 2) = ".bmp" : flg = 0 : else : flg = 1
	SetWindowLong objinfo(id, 2), -16, GetWindowLong(objinfo(id, 2), -16) | 0x0080 - 0x0040 * flg
	h = LoadImage(0, file, flg, , , 0x0010) // LR_LOADFROMFILE
	sendmsg objinfo(id, 2), 0x00F7, flg, h // BM_SETIMAGE
	return
#global

	objsize 120, 90
	pos 10, 10 : button gosub "画像指定", *change
	stop

*change
	dialog "bmp;*.ico;*.cur", 16, "ボタンに表示する画像"
	if stat = 1 {
		loadbuttonimage 0, refstr
	}
	return