便利なオブジェクト2
前章、利用者がマウスクリックだけで処理を制御させることができるボタン系オブジェクトを紹介しました。
当章では利用者にマウスで選択をさせることができるリスト系オブジェクトについて紹介します。
標準命令1つで配置できるリスト系オブジェクトはリストボックスとコンボボックスの2タイプです。
リストボックスから説明しましょう。
listbox インデクス保持変数, 高さ, リスト内容
インデクス保持変数「どの項目が選択されているかを示す行番号」を保持する変数。
高さリストボックスの高さ(単位ピクセル)。
リスト内容選択させるリスト項目の内容。
第1パラメータは選択された行番号を保持させる変数を指定します。
最上段項目が選択されていた場合は0が、上から2段目は1が…それぞれセットされます。
もし、いずれも選択されていない状態であれば−1が入ります。
第2パラメータはリストボックスの高さを指定しますが、思い通りに行かない時があります。
実は、リストの高さはリスト1段分(厳密には文字)の高さに依存しています。
項目は縦に並べられるわけですが、リストに収まらない程の項目数がある場合、
一番下に表示される段の文字が欠けるということにはならず、
その段が丸々表示されないか、もしくはその段が表示しきれる高さとなるようです。
このことはFAQに回避策を書いていますが、リストボックスでは回避できないかと思われます。
第3パラメータのリスト内容は、そのままの意味で、選択させる各項目のテキストとなります。
各項目間の区切りは改行文字で表し、区切り1つで2項目が、区切り2つで3項目…がリストに表示されます。
例えば「東京」「大阪」「博多」という3項目を設定したい場合は、
"東京\n大阪\n博多"を入れた変数又は文字列そのままを指定します。
尚、リストボックスではテキストのみ扱えます。
エクスプローラのようにテキストと共に画像(アイコン)を表示させようとするならば、
リストボックスではなく、高度なリストビューを使わなければなりません。
リストビューはHSPでも扱えるものの、標準命令では用意されていませんし、設定が複雑です。
現段階では、慣れる意味でもとりあえずはリストボックスを使うようにしましょう。
 1
 2
 3
 4
 5
	objsize 120, 100 // 現在のオブジェクト高さ
	pos  50, 50 : listbox index1, 100, "あいうえお\nかきくけこ\nさしすせ\nそたちつてと"
	pos 200, 50 : listbox index2, 30, "現在の\nオブジェクト高さより\n大きくできても\n小さくできない"
	objsize 120, 20 // 現在のオブジェクト高さを縮める
	pos 350, 50 : listbox index3, 30, "こうすれば小さくなる"
サンプルではリストボックス毎にインデクスに使用している変数を別々にしていましたが、
コレが全て同じであってもエラーにはなりません。
ただ、最後に触ったリストボックスのカレント行が保持されることとなるので、
意図しない行番号となることでしょう。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
	objsize 50, 50
	repeat 8
		pos cnt * 60 + 50, 50 : listbox index, , "1行目\n2行目\n3行目\n4行目\n5行目\n6行目"
	loop
	objsize 100, 20
	pos 50, 250 : button "選択行チェック", *check
	stop

*check
	dialog "現在" + (index + 1) + "行目を選択しています?"
それぞれの選択行を別々に知る必要があるならば、
別々の変数、もしくは配列にして別々の配列要素を割り当てましょう。
さて、別タイプのリスト形オブジェクトの紹介に移りましょうか。
combox インデクス保持変数, 一覧の高さ, リスト内容
インデクス保持変数「どの項目が選択されているかを示す行番号」を保持する変数。
一覧の高さコンボボックスを開いた時の高さ(単位ピクセル)。
リスト内容選択させるリスト項目の内容。
設定内容はlistbox命令と同じですね。
1点違うところは、リストの高さが一覧の高さに変わったという点です。
コンボボックスは、触っていないときは、現在選択している項目だけが表示され、
選択項目を切り替える時に一覧を表示させて、その中から選択するというものです。
よって、普段の高さはリスト1段分(文字)の高さとなります。
第2パラメータの高さ部分は、選択を切り替える時に表示される一覧の高さになると言うわけですね。
高さはlistbox命令同様に、一番下に表示される項目の文字が欠けないよう自動で調整された高さとなります。
リストボックスと異なり、リストの高さは「最大でも全項目文の高さ」となり、
リストボックスのように「項目行よりも大きい場合に余白ができる」ということはありません。
インデクス保持変数はlistbox命令同様に、先頭行だと0、先頭から2段目は1、未選択だと−1が入ります。
リスト内容もlistbox命令同様に、項目間を改行文字で区切って表しましょう。
 1
 2
 3
 4
	type = "ハッチバック\nクーペ\nオープン\nセダン\nステーションワゴン\nトールワゴン"
	objsize 120, 20
	pos  50, 50 : mes "車種タイプ"
	pos 150, 50 : combox index, 100, type // コンボボックスを配置
さて、配置後にリスト内容を変更したいという時もあると思います。
例えば先ほどのサンプルで言えば、車種タイプを選択するだけのものでした。
このプログラムに、実際の車種リストを選択するリストボックスを付け加えて、
選択した車種タイプに当てはまる車種を車種リストに表示させたいとしましょう。
このような動きを実現させたい場合、オブジェクト内容の更新を行う必要がありますね。
objprm オブジェクトID, 変更後の内容
オブジェクトID更新するオブジェクトのID番号
変更後の内容更新後の内容
第1パラメータにはオブジェクトのIDを指定します。
オブジェクトのID…???
今までに、このIDについて触れていませんでしたので、初めて聞く方もいるはずです。
プログラマが割り当てるものではなくオブジェクトを配置する時、
オブジェクト毎に自動で割り当てられる番号のことをオブジェクトIDと呼んでいます。
基本的に、重複はしないよう0から順番に割り振られていきますが、
途中にあるオブジェクトの配置を取り消した場合、そのオブジェクトのIDが歯抜けとなります。
歯抜けの状態でオブジェクトを新規に配置すると、
その新オブジェクトのIDは歯抜けのIDが割り当てられるようになっています。
具体的には、0〜6まで順番に割り振った後に2と4のオブジェクトを削除すると、
次に配置するオブジェクトは2、その次は4、その次は7になると言うことですね。
このオブジェクトIDはウィンドウ毎に用意されたもので、
ウィンドウ0で0〜5まで割り当てても、
ウィンドウ1以降に新しくオブジェクトを配置すると0から割り当てられます。
当然、ウィンドウ0に戻って、新しくオブジェクトを配置すると6が割り当てられることになりますよ。
HSP2以前は、1ウィンドウ毎に最大で64個(0〜63)までしか配置できませんでしたが、
HSP3以降は、1ウィンドウ毎に最大で16,384個(0〜16,383)まで配置可能となりました。
1,024個を超えると警告メッセージが表示されるとのことで、実際に配置させてみたところ、
メッセージが出て、それより多く配置することはできませんでした(Version3.0時点)。
objprm命令の第2パラメータに話を戻します。
listboxまたはcomboxの場合、パラメータに文字列又は文字列型変数を指定するとリスト内容の更新を行い、
数値又は数値型変数を指定することで選択項目の変更を行います。
HSP2以前ではこの説明でよかったのですが、HSP以降は実数型が使えるようになりました。
整数値ではなく実数値を第2パラメータに指定すると、エラーとなりますので指定しないでください。
objprm命令はオブジェクト内容の更新をする命令ですので、listboxcomboxだけでなく、
その他の標準命令によるオブジェクトもOKです。
ボタンであればキャプションのテキスト、チェックボックスならチェックのON/OFF。
次章に説明するエディット系オブジェクトの場合だとボックス内容の更新を行います。
それでは、先ほど説明していた車種タイプのサンプルを紹介しましょう。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
11
12
13
14
15
16
17
18
19
	index.1 = -1 // 選択項目の変更チェック用
	type = "ハッチバック\nクーペ\nオープン\nセダン\nステーションワゴン\nトールワゴン"
	carlist.0 = "アヴァンシア\neKワゴン\nヴィッツ\nVWゴルフ"
	carlist.1 = "シルビア\nスープラ\nNSX\nポルシェ911"
	carlist.2 = "セリカ\nユーノスロードスター\nM・ベンツSLK"
	carlist.3 = "ギャラン\nセルシオ\nレガシィ\nローレル"
	carlist.4 = "カルディナ\nボルボV70\nレガシィ"
	carlist.5 = "キューブ\nムーヴ\nファンカーゴ\nワゴンR"
	objsize 120, 20
	pos  50, 50 : mes "車種タイプ"
	pos 150, 50 : combox index, 100, type // オブジェクトID0
	pos 300, 50 : mes "車種"
	pos 350, 50 : listbox syasyu, 100, "" // オブジェクトID1
	repeat
		if index ! index.1 {
			index.1 = index
			objprm 1, carlist.index // 定義した文字列型配列の特定要素内容に切り替える
		}
		wait 1
	loop