Home -> HSP講座 -> 初級編 No.6

ウィンドウでドウ?

タイトルが滑っているとは何事もじゃぁ!?(何)
それはともかく、今回は「ウィンドウ」の話です。
小難しい話を始める前に、下のスクリプトを実行してみてください。

	// 前回の画像のスクリプト
	screen 0, 120, 220
	pos 20, 20
	objsize 80, 25, 30
	button "ID 0", *a
	button "ID 1", *a
	button "ID 2", *a
	button "ID 3", *a
	button "ID 4", *a
	button "ID 5", *a
*a
	stop

前回の、(自称) 謎のスクリプトです。
スクリプトを見せたら答えがバレバレなのですが、ウィンドウの大きさが 640 × 480 じゃないんです!

………

今までは HSP が自動で用意してくれるウィンドウを使ってきましたが、
今回は、自分でウィンドウを用意してみましょう。
こうしないと、複数の画面を切り替えるときに困りますので。
そんな時に活躍するのが、この screen 命令です。

パラメータが本講座史上最大の数を持つ命令なので、詳しく解説。

	screen IDW, SizeX, SizeY, Flag, PosX, PosY, ClientX, ClientY

ふう。出ました、8個です。
HSP の標準命令としては、最多です。
一位タイ : screen, bgscr, gzoom, winobj

さて本題。screen 命令のパラメータを一つ一つ丁寧に解説してみます。
ちなみに、8個とも整数値 ( int ) です。

IDW
ウィンドウID を指定します。
HSP のウィンドウには、全部数値が振られていて、それで、どのウィンドウを指しているかを識別する仕組みになっています。
オブジェクトID とほぼ同じ感じ。
ちなみに、いままで使っていたのは ID 0 です。
SizeX
ウィンドウの横幅の大きさを指定します。
SizeY
ウィンドウの縦幅の高さを指定します。タイトルバーとかは含みません。
Flag
作成するウィンドウに付けるオプションを選び、指定します。
使いたいオプションの数値を足し合わせれば、複数選択できます。
詳しくは下の表にて。
PosX
ウィンドウを表示する左上の「X座標」を指定します。
ウィンドウを表示するんだから、当然どこに置くかを指定しないといけませんよね?
このパラメータには、ディスプレイの左端から何ドット右にずれた所をウィンドウの左上にするのかを決めます。
PosY
ウィンドウを表示する左上の「Y座標」を指定します。
これも PosX と同様、デスクトップ全体から見て、「上」から何ドット目を左上として表示するかを決めます。
この時注意しなければいけないことは、数学ででてくる「Y座標」と上下逆さま( 数学では、下から上に進む )ということです。
ClientX
Client は、一般的には「クライアント」と読みます。
ウィンドウのクライアント領域の横幅を指定します。
クライアント領域というのは、実際に画面に映される部分の事です。
例えば、このページの一番下にある「by 上大」という文字は、このページ(一つのウィンドウ)の中にあるにも関わらず、
全く表示されていませんよね? (パソコンに依りますが、表示されないはずです! (>o<;)
しかし、この「やっほー」という文字は表示されています。この今見えている部分が「クライアント領域」で、「by 上大」のように見えていない部分を「非クライアント領域」と言います。
実は、SizeX, SizeY で指定したのは、非クライアント領域も含む値だったのです。
ClientY
ClientX の横バージョン。

screen 命令の Flag に指定できる値と意味
Number Meaning
1 パレットモードにします。(僕もよく知りません。申し訳ない。)
2 画面に表示しません。(後から表示できる)
4 ウィンドウの大きさを変えられません。
8 ツールウィンドウ。独特の外観を持っています。
タスクバーにタイトルが表示されません。
16 ウィンドウの周りに、深い溝をつけます。

ちなみに、作成後のウィンドウの設定を行う width 命令というのもあります。

	width ClientX, ClientY, PosX, PosY

ではさっそく、実際にウィンドウを作ってみましょう。


#const IDW_test 1	// IDW_test を 1 と定義
	
	screen IDW_Test, 320, 240, 8
	stop
[EOF]

#const 疑似命令は非常に便利なモノで、

#const ONE 1

と書くと、それ以降のスクリプトにある 「ONE」 という単語が 1 と置き換えられます。
プリプロセッサ命令 と言うのですが、それは後述。
今は #const だけ覚えていてくれれば結構です。

え、何が便利なんだ? と思う人もいるでしょう。(僕もそうでした)
#const の便利さは一言で表せます。

後で簡単に変更できるし、
何の数値か分かりやすい。

(一言じゃねぇぇぇええええ!!)

なんだか、毎回変なミニコントしてる様な気がしてきた今日この頃です。(笑)

結構簡単な構造のソフトでも、意外と 500行 くらいのスクリプトになるものです。
そんな長いスクリプトを編集していたとします。

もし、ウィンドウID 10 を使えなくなったりしたら、どうしましょう?
元々 10 だったウィンドウを適当な wID (例えば100) に変更しなければなりません。
かなり無駄な労力を使うことになっちゃいます。
しかし、あらかじめ全てのウィンドウ ID を #const で管理しておけば

#const IDW_X 10


#const IDW_X 100

にするだけ。楽ですねぇ〜  (例えがおかしいとかは言わないこと)。

ウィンドウの話に戻ります。

今まではウィンドウが一つだけだったので気にすることでは無かったんですが、
mes 命令などで画面をいじるとき、
"何に"描画するのかということを、全く指定しませんでした。
まぁ当たり前ですね。一択問題みたいなもんでしたから。
でも、今日からは違います。
「どれに」というのも、しっかり宣言しなければなりません!

#const IDW_Main 0	// メイン画面
#const IDW_Sub  1	// サブの画面
	
	screen IDW_Main, 320, 240	// ウィンドウを作成
	screen IDW_Sub , 160, 120	// もう一個作成
	
	mes "これはサブ画面"
	
	gsel IDW_Main, 0		// 目標を変更!
	mes "こっちはメイン"
	
	gsel IDW_Sub , 0		// サブに変える
	mes "戻ってきました〜。"
	
	stop

さて、見てわかるとおり、gsel命令で対象を変更しています。
gsel 命令は、「操作先ウィンドウ」というものを設定します。
mes 命令など、ウィンドウに対して何かする命令は、
この操作先ウィンドウを対象にします。
screen 命令は、作成したウィンドウを操作先にします。

ちなみに、オブジェクトID はウィンドウごとに割り振られています。
たとえば、以下のようなスクリプトです。

#const IDW_Main 0	// メイン画面
#const IDW_Sub  1	// サブの画面
	
	// メイン画面に設置
	screen IDW_Main, 320, 240
	button "メインのボタン", *dummy
	
	// サブ画面に設置
	screen IDW_Sub , 160, 120
	button "サブのボタン", *dummy
	
	wait 120
	
	// サブのボタンの文字列を変更

;	gsel IDW_Main, 0
	objprm 0, "sub button"
	
*dummy
	stop

objprm 命令は、オブジェクトの状態を変える命令でした。
これを button に使うと、文字列が変更されるんでしたね。
オブジェクトID がウィンドウを区別していない場合、サブ画面のボタンは 1 のはずですが、
0で反応していると言うことは、どちらも0なわけです。
gsel IDW_Main のコメントを外すと、メイン画面のボタンが反応します。


前に押し出す

パソコンの画面はそんなに広くないことが多いので、
いくつかウィンドウがあると、重なってしまいます。


これじゃ見えない

ウィンドウを最前面にする方法は、もちろんあります。
さっきの gsel 命令を使用します。

#const IDW_Main 0	// メイン画面
#const IDW_Sub  1	// サブの画面
	
	screen IDW_Main, 320, 240, 0, 80, 30	// ウィンドウを作成
	screen IDW_Sub , 160, 120, 0, 60, 40	// もう一個作成
	
	mes "これはサブ画面"
	wait 120
	
	gsel IDW_Main, 1		// 目標を変更!
	mes "こっちはメイン"
	
	wait 120
	
	gsel IDW_Sub , 1		// サブに変える
	mes "戻ってきました〜。"
	
	stop

さ、実行っ!
使い回しだなと思ってるあなたも、どうか気にせず!

今回は、wait 命令を入れて、処理をわかりやすくしました。
わかりましたね。


ウィンドウを隠蔽する

逆に、隠したい場合もあるでしょう。
この方法は、ほかのウィンドウを覆い被せるというむちゃくちゃな方法とは違い、
しっかりと消し去ることが出来ます。

予想通り、gsel 命令を使います。
gsel は非常に便利なので、くどくど説明して覚えさせようという作戦です。(ヒヒッ)
今回は、モード -1 を使います。

#const IDW_Main 0	// メイン画面
#const IDW_Sub  1	// サブの画面
	
	screen IDW_Main, 320, 240, 2, 80,  30	// 隠して作成する
	screen IDW_Sub , 160, 120, 0, 60, 300
	
	mes "これはサブ画面"
	wait 120
	
	gsel IDW_Sub , -1		// サブ画面消失
	gsel IDW_Main,  1		// メイン画面登場
	mes "こっちはメイン"
	
	wait 120
	gsel IDW_Main, -1		// 消滅
	
	gsel IDW_Sub , 1		// 復活
	mes "戻ってきました〜。"
	
	wait 300
	gsel IDW_Main, 1		// いちおう復活させておく
	
	stop

半ば予想できた使い回しです。
実行してみると、出てきたり消えたりを繰り返すようになっています。

「ウィンドウを削除する」という時がありますが、
HSPでは、HSPの命令で作ったウィンドウを削除することは出来ないので、実際には gsel で隠すだけにします。


最前面で維持させる

さて、登場・消失ができて、まだあるのかよという感じですが、題名通り、最前面に維持させる方法です。
だれもが予想できた gsel 命令を使用します。
とりあえず、やってみてください。

#const IDW_Main 0	// メイン画面
#const IDW_Sub  1	// サブの画面
	
	screen IDW_Main, 320, 240, 0, 80, 30
	screen IDW_Sub , 160, 120, 0, 60, 40
	
	mes "これはサブ画面"
	wait 120
	
	gsel IDW_Main, 2		// 最前面に指定!!
	mes "こっちはメイン"
	wait 120
	
	gsel IDW_Sub , 1		// サブを前にもってくる……?
	mes "戻ってきました〜。"
	
	stop

分かりましたか?
最前面に維持するとはそのままの意味で、「ずーと最前面にいる」ということです。
これは便利なときもありますが、作りすぎると鬱陶しいので、気を付けてください。


これで、第六回の講座は終わりです。

gsel のモード
モード 効果
0 操作先ウィンドウを変更するだけです。
1 ウィンドウを最前面に持ってきます。
2 ウィンドウを最前面に維持させます。
-1 ウィンドウを削除 (隠) します。

by 上大

第五章へ   第七章へ