HSP3 あれこれ <オブジェクト 2>

Last Update : 2007/09/xx

 ◇ 入力ボックス (input命令) / メッセージボックス (mesbox命令)

 input命令 と mesbox命令。HSP上では別命令になっていますが、内部的には全く同じ「エディットコントロール」というオブジェクトで、1行表示 or 複数行表示 というのが主な違いです。

 このオブジェクトに関する基礎的な解説講座は、input命令の解説エンターキーの判定パスワード入力ボックス)やmesbox命令の解説のページを参照あれ〜。

↑TOP↑

入力ボックス/メッセージボックスのスタイル変更

 入力ボックスやメッセージボックスのスタイルを変更してみるサンプルです。文字列の表示位置(中央、右寄せ)を変更したり、数字しか入力できないボックスを用意することができます。スタイルの詳細は、ちょくとさんのページ(ウィンドウスタイルコントロール固有のスタイル)を参照。

 まずは mesbox命令。これは mesbox命令 のp4でスタイルの変更ができてしまいます。ボタンやチェックボックスのスタイル変更では省略してしまいましたが、GetWindowLong関数で現在のウィンドウスタイルを取得し、新たなウィンドウスタイルをSetWindowLong関数で反映します。

//	メッセージボックスのウィンドウスタイル変更 (by Kpan)

#include "user32.as"

	objsize 200, 50

;	テキスト表示位置変更 ($1=中央、$2=右寄り)
	x = "まんなか"
	mesbox x
	hMesbox = objinfo(stat, 2)

	GetWindowLong hMesbox, -16
	SetWindowLong hMesbox, -16, stat | $1

;	特定文字変換入力 ($8=大文字変換、$10=小文字変換)
	x = "必ず大文字"
	mesbox x
	hMesbox = objinfo(stat, 2)

	GetWindowLong hMesbox, -16
	SetWindowLong hMesbox, -16, stat | $8

;	数値のみ入力可 (数値専用=$2000)
;	$2001 のように組み合わせれば「中央表示の数字のみ」となります
	x = "数字しか入らんよ"
	mesbox x
	hMesbox = objinfo(stat, 2)

	GetWindowLong hMesbox, -16
	SetWindowLong hMesbox, -16, stat | $2000

 次に、input命令。入力ボックスのスタイルは、「WS_CHILD + WS_VISIBLE + WS_TABSTOP + ES_AUTOHSCROLL = $50010080」となっているので、GetWindowLong関数の部分は省略してます。

//	入力ボックスのウィンドウスタイル変更 (by Kpan)

#include "user32.as"

	objsize 200

;	ここでは右寄せの例だけ。mesbox命令で登場した他のスタイルも利用可
	x = "右にホイ"
	input x
	hInput = objinfo(stat, 2)

	SetWindowLong hInput, -16, $50010080 | $2

↑TOP↑

入力ボックス/メッセージボックの表示色変更

 Windowsのデフォルト設定では、黒(文字色)と白(背景色)になっている入力ボックスやメッセージボックスの表示色を変更します。HSP2では拡張プラグインやマシン語などを利用しないと実現できなかった代物ですが、HSP3ではoncmd命令の登場でそれなりに楽に実装できるようになりました。また、カラー用のデータを用意するためWin32 API関数を使います。

 まずは、文字色だけの変更。サンプルではinput命令のみ使用していますが、同じエディットコントロールであるmesbox命令(書き換え可能スタイルのみ)でも利用できます。文字全体が1つの指定した色になります。HSP3スクリプトエディタのように文字の単語ごとに異なる色を表示するようなことはできません。

//	エディトコントロール内文字色変更サンプル (by Kpan)

#include "gdi32.as"

;	色指定用のRGBマクロ (0x00BBGGRR形式へ変換)
#define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16)

;	エディットコントロールが描画されるときに送られてくる
;	ウィンドウメッセージ (WM_CTLCOLOREDIT)
	oncmd gosub *ctlcoloredit, $133

	a = "文字色だけ変えてみる"
	input a, 200
;	入力ボックスオブジェクトのウィンドウハンドルを取得
	hInput = objinfo(stat, 2)

;	オブジェクトの背景用に白色ブラシのハンドルを取得
	GetStockObject 0
	hBrush = stat

	stop

*ctlcoloredit
;	lparamにオブジェクトのウィンドウハンドルが返る
	if hInput = lparam {
;		SetTextColor関数。呼んで字のごとく文字色設定です
;		第1パラにデバイスコンテキストのハンドル(wparamを指定)
;		第2パラに文字色 (ここでは黄色)
		SetTextColor wparam, RGB($FF, $FF, $00)

;		背景用に白色ブラシのハンドルを返す
		return hBrush
	}

	return

 次に文字色とともに背景色部分も変更します。Win32 API関数の処理が増えます。

//	エディトコントロール内文字色&背景色変更サンプル (by Kpan)

#include "gdi32.as"

#define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16)

	dim hInput, 2

;	エディットコントロールが描画されるときに送られてくる
;	ウィンドウメッセージ (WM_CTLCOLOREDIT)
	oncmd gosub *ctlcoloredit, $133

;	生成したカラーデータを破棄するための処理に必要
	onexit *exit

	a = "文字色&背景色を変えてみる1"
	input a, 200
	hInput.0 = objinfo(stat, 2)

	b = "文字色&背景色を変えてみる2"
	input b, 200
	hInput.1 = objinfo(stat, 2)

;	背景カラー用のブラシを生成しハンドルを取得。
	CreateSolidBrush RGB($FF, $00, $00)
	hBrush.0 = stat

	CreateSolidBrush RGB($FF, $00, $FF)
	hBrush.1 = stat

	stop

*ctlcoloredit
;	lparamにオブジェクトのウィンドウハンドルが返る
	if hInput.0 = lparam {
		SetTextColor wparam, RGB($FF, $FF, $00)

;		テキスト背景色 (hBrush.0と同色を指定)
		SetBkColor wparam, RGB($FF, $00, $00)

;		ボックス背景色
		return hBrush.0
	}

	if hInput.1 = lparam {
		SetTextColor wparam, RGB($00, $FF, $00)

;		テキスト背景色 (hBrush.1と同色を指定)
		SetBkColor wparam, RGB($FF, $00, $FF)

		return hBrush.1
	}

	return

*exit
;	作成した背景カラー用のブラシを破棄
	DeleteObject hBrush.1
	DeleteObject hBrush.0

	end

↑TOP↑

入力ボックスの編集無効

 input命令 を書き換え不可、書き込み禁止、つまり編集できないグレー(灰色/淡色)表示にします。sendmsg命令 でサクッとできます。メッセージボックス(mesbox命令)に対しても、同じ方法で編集無効 or 無効解除が可能です。

//	編集無効な入力ボックス

;	sendmsg命令の第3パラを1にすると編集できなくなる (EM_SETREADONLY)
	input b
	hInput = objinfo(stat, 2)
	sendmsg hInput, $CF, 1

	button "解除", *change
	stop

*change
;	第3パラを0(ここでは省略)にすると編集できるように
	sendmsg hInput, $CF

 少し発展的なネタコードとして、上のように編集無効のオブジェクトにした場合、背景色が灰色(っぽい色)になり、編集できるオブジェクトとできないオブジェクトの違いというのが目に見えるわけですが、編集できないにも関わらず真っ白背景という状態の入力ボックスやメッセージボックスの作成です。

//	真っ白背景の使用不可エディトコントロールサンプル (by Kpan)

#include "gdi32.as"

;	WM_CTLCOLORSTATIC
	oncmd gosub *ctlcolorstatic, $138

	a = "真っ白背景の書き換え不可なインプットボックスでーす"
	input a, 300
;	インプットボックスのウィンドウハンドル取得
	hInput = objinfo(stat, 2)
;	普通に編集不可にする
	sendmsg hInput, $CF, 1

	b = "真っ白背景の\n 書き換え不可な\n  メッセージボックスだ"
	mesbox b, 300, 100, 0
;	メッセージボックスのハンドルを取得
	hMesbox = objinfo(stat, 2)

;	背景色用として白色ブラシのハンドルを取得
	GetStockObject 0
	hBrush = stat

	stop

*ctlcolorstatic
;	lparamにオブジェクトのウィンドウハンドルが返る
	if lparam = hInput | lparam = hMesbox {
;		文字の背景を透過モード
		SetBkMode wparam, 1

;		白色ブラシを返す
		return hBrush
	}

	return

↑TOP↑

入力ボックスの文字数超過を監視

 input命令 は、第4パラメータで入力できる最大文字数を指定できます。もし文字数が超えたら反応するサンプルコードです。HSP2では、input命令で指定した変数の長さをループ中に逐一チェックする方法をとったでしょうが、HSP3はoncmd命令のお世話になりましょう。

※注意!
 Windows XP環境以降のHSP3製実行ファイルは、文字数をUnicode形式で数える仕様があります(HSP HELP CENTERさんの該当スレッド、MSサポート「この動作は仕様です」)。下の7文字制限を例にすると、XP(SP2)環境では全角7文字超えであふれます。一方、XP以前の環境では全角3文字超えであふれることになります。OSにより全角文字列を扱いが異なる・・・、ということではてさて。(-_-;

//	文字数入力超過の監視
//	(OS環境により挙動が異なるため注意!)

;	上位ワード取得用マクロ
#define ctype HIWORD(%1) (%1 >> 16 & $FFFF)

;	ウィンドウメッセージ (WM_COMMAND)
	oncmd gosub *command, $111

;	ここでは7文字制限
	a = ""
	input a, 100, 22, 7
	hInput = objinfo (stat, 2)

	stop


*command
;	lparamにウィンドウハンドル
	if lparam = hInput {
;		wparamの上位ワードに通知コード
;		(文字数が越えると EN_MAXTEXT が通知される)
		if HIWORD (wparam) = $501 {
			mes "あっぷっぷー"
		}
	}

	return

 ウィンドウメッセージWM_COMMANDネタついでに、テキスト内容のリアルタイム監視。

//	リアルタイムでボックス内の文字入力を監視 (by Kpan)

;	上位ワード取得用マクロ
#define ctype HIWORD(%1) (%1 >> 16 & $FFFF)

;	WM_COMMAND
	oncmd gosub *command, $111

	a = ""
	input a, 200
	hInput = objinfo(stat, 2)

	stop

*command
	if lparam = hInput {
;		wparamの上位ワードに通知コード
;		(内容が変更されると EN_CHANGE が通知される)
		if HIWORD(wparam) = $300 {
			title ""+a+" ["+strlen (a)+"]
			return
		}
		return
	}

	return

↑TOP↑

入力ボックスの先頭に余白

 入力ボックスの左側部分と文字の先頭部分に余白(マージン)を設けてみーる。EM_SETMARGINSメッセージをPostMessage関数で送信します。同じエディトコントロールであるメッセージボックスでも可能です。

//	ボックスにマージン

#uselib "user32"
#func PostMessage "PostMessageA" int, int, int, int

	a = "Let's HSP!"
	input a, 200
	hInput = objinfo(stat, 2)

;	EM_SETMARGINS
;	第4パラのlparam値に幅(ピクセル単位)
	PostMessage hInput, $D3, 1, 20

↑TOP↑

境界線枠なし入力ボックスの作成

 input命令には、入力部分まわりの境界線枠が付いています。これは、拡張ウィンドウスタイルに WS_EX_CLIENTEDGE ($200) が指定されているためです。これを取り外すことで、枠のない入力ボックスというのが実現できます。(ちょくとさんのページ拡張ウィンドウスタイルも参照。

 SetWindowLong関数 で新たな拡張ウィンドウスタイルを指定してやります。普通のウィンドウスタイルの変更と違って、拡張ウィンドウスタイルの場合は、SetWindowPos関数 を呼び出して再描画をやらないと実際に変更が反映されないようです。

;	境界線なしエディトコントロール表示サンプル (by Kpan)

#uselib "user32"
#func SetWindowLong "SetWindowLongA" int, int, int
#func SetWindowPos "SetWindowPos" int, nullptr, nullptr, nullptr, \
 nullptr, nullptr, int
;	↑長いので改行しています。1行にする場合は「\」を取ってください。

	x = "あいうえお"
	objsize 200, 50

	pos 50, 50

;	普通の枠あり入力ボックス
;	これには拡張ウィンドウスタイルに $200 が指定されている。
	input x

	pos 50, 100

;	枠なし入力ボックス
;	objinfo関数の第1パラにオブジェクトIDを入れます。
;	拡張ウィンドウスタイルに $0(何もなし) を指定してやる。
	input x
	SetWindowLong objinfo (1, 2), -20, $0 ; スタイルを変えて
	SetWindowPos objinfo (1, 2), $27 ; 再描画

	pos 50, 150

;	[おまけ] 少し沈んだ枠($20000)あり入力ボックス
	input x
	SetWindowLong objinfo (2, 2), -20, $20000
	SetWindowPos objinfo (2, 2), $27

 また、 input命令 と同じように、mesbox命令 や listbox命令 も 拡張ウィンドウスタイル に WS_EX_CLIENTEDGE ($200) が指定されています。上のサンプルと同じようにすればOKです。

↑TOP↑

メッセージボックスのスクロールバー表示

 mesbox命令のメッセージボックスには、第4パラメータのスタイルごとに違いますが、右側と下側にスクロールバー(垂直、水平)が表示されます。ShowScrollBar関数を利用したスクロールバーの表示、非表示の切り替えです。

//	メッセージボックスのスクロールバー表示・非表示サンプル (by Kpan)

#include "user32.as"

#define SB_BOTH 3	; 両方
#define SB_HORZ 0	; 水平バー
#define SB_VERT 1	; 垂直バー

	a = "HSP3向けのサンプルコードだよーん。スクロールバーのありなし。"

;	ShowScrollBar関数
;		第1パラにオブジェクトのウィンドウハンドル
;		第2パラに対象バーの指定
;		第3パラに表示(1) or 非表示(0)

;	両方のバーなし、折り返しあり
	mesbox a, 200, 50, 1
	ShowScrollBar objinfo(stat, 2), SB_VERT, 0

;	水平バーのみ、折り返しなし
	mesbox a, 200, 50, 5
	ShowScrollBar objinfo(stat, 2), SB_VERT, 0

;	両方のバーなし、折り返しなし
	mesbox a, 200, 50, 5
	ShowScrollBar objinfo(stat, 2), SB_BOTH, 0

;	垂直バーのみ、折り返しなし
	mesbox a, 200, 50, 5
	ShowScrollBar objinfo(stat, 2), SB_HORZ, 0

↑TOP↑

<< オブジェクト 1 | HSP3 オブジェクト | オブジェクト 3 >>

Copyright © 2005-2012 . All rights reserved.