HSP3 あれこれ <ウィンドウ>

Last Update : 2007/04/xx

ウィンドウスタイルの変更

 HSPのウィンドウID 0 は、最大化ボタンとサイズ可変が無効になっています。ウィンドウスタイルを変更して、利用できるようにしてみます。ちなみに、スクリプトからウィンドウを最大化、最小化するには、sendmsg命令を利用。

//	最大化ウィンドウ、ウィンドウサイズ可変サンプル (by Kpan)

#include "user32.as"

;	あらかじめ最大サイズでウィンドウ作成
	screen 0, ginfo(20), ginfo(21)

;	自ウィンドウのスタイルを変更
;		$10000 = 最大化ボタン有効
;		$40000 = ウィンドウサイズ可変有効
	GetWindowLong hwnd, -16
	SetWindowLong hwnd, -16, stat | $10000 | $40000

;	実際に表示するサイズを指定
	width 200, 200

;	スクリプトから最大化ウィンドウにしたい場合
//	sendmsg hwnd, $112, $F030

 今度は上の逆パターン、すでに設定されているウィンドウスタイルを取り除きます。

//	ウィンドウスタイルの変更2 (by Kpan)

#include "user32.as"

;	-$20000 = 最小化/最大化ボタンなしウィンドウ
;	-$80000 = システムメニューなしウィンドウ
;	-$400000 = ウィンドウ境界線なしウィンドウ
;	-$800000 = タイトルバーなしウィンドウ
	GetWindowLong hwnd, -16
	SetWindowLong hwnd, -16, stat - $80000

	width 400, 200

;	システムメニューを外すと終了ボタンが消えてしまうので終了用
	onkey *exit

	stop

*exit
	end

 最後に拡張ウィンドウスタイルの変更です。

//	拡張ウィンドウスタイルの変更 by Kpan

#include "user32.as"

;	+$1000 = タイトル名部分が右側に位置するウィンドウ
;	+$20000 = 境界枠なし(細枠)ウィンドウ
	GetWindowLong hwnd, -20
	SetWindowLong hwnd, -20, stat | $1000

	width 400, 200

↑TOP↑

ウィンドウ背景色

 HSPのウィンドウ背景はデフォルトで白色になってます。しかし、一般的なツール系プログラムの背景色は灰色表示(Windows XP以降のビジュアルスタイルの場合は白系)です。HSP2では背景色としてcls命令を利用していた人がいるかもしれませんが、オブジェクト(分かりやすいのがchkbox命令)の表面色と違っていたと思います。

 HSP3では標準命令でシステムカラーを取得できるようになりました。syscolor命令のインデックス番号15がウィンドウ表面色になります。ただ、この場合、Windows 9x系OSで、画面が16ビット(High Color)の場合は色ずれ現象が起こります。(→ 参照、システムカラー一覧チェックツール

//	ウィンドウ背景色

;	オブジェクトの表面色とは異なるcls命令
;	cls 1

	syscolor 15
	boxf

	pos 100, 100
	chkbox "チェックボックス", a

;	mes命令などの描画命令を使う場合は文字色をcolor命令で戻す
	color
	mes "あいうえお!"

 Windows XP以降の環境は、ビジュアルスタイルという新たなユーザーインターフェイスが採用され、オブジェクトのデザインが変更されました。その1つにタブコントロールの表面色があり、よく見ると分かりますがクラシックスタイル時の統一された1つの色ではなく、上から下にかけて3段階のグラデーションがかかっています。この表面色を表示してみることにします。

//	ビジュアルスタイルのグラデーション表面色表示 (by Kpan)

#uselib "uxtheme"
#func OpenThemeData "OpenThemeData" int, wstr
#func DrawThemeBackground "DrawThemeBackground" int, int, int, int, int, int
#func CloseThemeData "CloseThemeData" int

#define TABP_BODY 10

;	簡易的な対応環境チェック
	if varptr(OpenThemeData) {
;		テーマハンドルを開く
		OpenThemeData hwnd, "TAB"
		if stat {
			hTheme = stat

;			テーマの描画
			RECT = 0, 0, ginfo(6), ginfo(7) ; 描画範囲
			DrawThemeBackground hTheme, hdc, TABP_BODY, 0, varptr(RECT)

;			テーマハンドルの解放
			CloseThemeData hTheme

			title "ビジュアルスタイルの背景色を適用"
		} else {
			syscolor 15
			boxf

			title "対応環境でもビジュアルスタイルが無効状態"
		}
	} else {
		syscolor 15
		boxf

		title "Windows XP以前の未対応環境"
	}

↑TOP↑

ウィンドウリージョン

 ウィンドウにおけるリージョンオブジェクトの作成です。四角形ウィンドウのところをあらかじめ指定した形状に変更します。丸いウィンドウや三角形ウィンドウなどが実現できます。ちょくとさんのページを参照。

 マウスでウィンドウを移動できるようにするには、sendmsg命令など使います。もしbgscr命令でウィンドウを作成した場合は、システムメニューがなくなってしまうので、何かしらのプログラム終了処理を用意しておく必要があります。

 まずは円形。CreateEllipticRgn関数を使用します。

;	リージョンサンプル (by Kpan)

#uselib "gdi32" 
#cfunc CreateEllipticRgn "CreateEllipticRgn" int, int, int, int

#uselib "user32"
#func SetWindowRgn "SetWindowRgn" int, int, int

	screen , 300, 200
	cls 3

;	四角形の左上XYと右下XYの座標を指定、
;	この座標で作成された四角形内に隣接する円が描かれます。
	hRegion = CreateEllipticRgn (0, 0, 300, 200)

;	それをウィンドウに適用
	SetWindowRgn hwnd, hRegion, 1

 次に、CreateRoundRectRgn関数。これは角の丸い四角形を作成です。

;	リージョンサンプル (by Kpan)

#uselib "gdi32" 
#cfunc CreateRoundRectRgn "CreateRoundRectRgn" int, int, int, int, int, int

#uselib "user32"
#func SetWindowRgn "SetWindowRgn" int, int, int

	screen , 300, 200
	cls 2

;	四角形の左上XYと右下XYの座標、
;	p5とp6は角の丸み楕円部分の高さと幅です。
	hRegion = CreateRoundRectRgn (0, 0, 300, 200, 50, 100)

	SetWindowRgn hwnd, hRegion, 1

 今度は、CreatePolygonRgn関数。多角形リージョンです。

;	リージョンサンプル (by Kpan)

#uselib "gdi32" 
#cfunc CreatePolygonRgn "CreatePolygonRgn" int, int, int

#uselib "user32"
#func SetWindowRgn "SetWindowRgn" int, int, int

	screen , 400, 400
	cls 2

;	例として三角形。この場合だと、3つの頂点ののXY座標
	POINT = 200, 0, 0, 400, 400, 400

;	p2は頂点の数。
	hRegion = CreatePolygonRgn (varptr (POINT), 3, 1)

	SetWindowRgn hwnd, hRegion, 1

 CombineRgn関数。これはリージョンとリージョンの結合を行います。

;	リージョンサンプル (by Kpan)

#uselib "gdi32"
#cfunc CreateRectRgn "CreateRectRgn" int, int, int, int
#cfunc CreateEllipticRgn "CreateEllipticRgn" int, int, int, int
#func CombineRgn "CombineRgn" int, int, int, int
#func DeleteObject "DeleteObject" int

#uselib "user32"
#func SetWindowRgn "SetWindowRgn" int, int, int

	screen , 270, 300
	cls 1

;	現在のウィンドウ(四角形)のリージョン作成。
	hRegion.0 = CreateRectRgn ( , , ginfo (6), ginfo (7))

;	大きい円のリージョン作成
	hRegion.1 = CreateEllipticRgn (80, 90, 210, 220)

;	四角形からこの円形部分のみ取り出す。
	CombineRgn hRegion.0, hRegion.0, hRegion.1, 4

;	使われないhRegion.1は削除
	DeleteObject hRegion.1

;	小さい円のリージョンを作成
	hRegion.1 = CreateEllipticRgn (20, 30, 270, 280)

;	大きい円からこの小さい円部分を取っ払う
	CombineRgn hRegion.0, hRegion.0, hRegion.1, 1

;	使われないhRegion.1は削除
	DeleteObject hRegion.1

;	ドーナツ型ウィンドウになる
	SetWindowRgn hwnd, hRegion.0, 1
;	リージョンサンプル (by Kpan)

#uselib "gdi32"
#cfunc CreateEllipticRgn "CreateEllipticRgn" int, int, int, int
#func CombineRgn "CombineRgn" int, int, int, int
#func DeleteObject "DeleteObject" int

#uselib "user32"
#func SetWindowRgn "SetWindowRgn" int, int, int

	screen , 350, 350
	cls 2

;	1つ目の円、2つ目の円
	hRegion.0 = CreateEllipticRgn (0, 0, 200, 100)
	hRegion.1 = CreateEllipticRgn (0, 20, 350, 350)

;	結合。第4パラには結合方法(1〜4)。重なり方が変わります
	CombineRgn hRegion.0, hRegion.0, hRegion.1, 3

	DeleteObject hRegion.1

	SetWindowRgn hwnd, hRegion.0, 1

 文字列からリージョンデータを起こしてみる。

;	リージョンサンプル (by Kpan)

#uselib "gdi32"
#func BeginPath "BeginPath" int
#func EndPath "EndPath" int
#cfunc PathToRegion "PathToRegion" int

#uselib "user32"
#func SetWindowRgn "SetWindowRgn" int, int, int

	font "MS Pゴシック", 80, 1
	color $FF, $FF : boxf

	BeginPath hdc
		mes "□▽△◎○!"
	EndPath hdc

	SetWindowRgn hwnd, PathToRegion (hdc), 1
	stop

↑TOP↑

移動できないウィンドウ

 タイトルバーをドラッグしても移動できないウィンドウを作成するには、システムメニューの[移動]項目を削除することで実現できます。

#uselib "user32"
#cfunc GetSystemMenu "GetSystemMenu" int, nullptr
#func DeleteMenu "DeleteMenu" int, int, nullptr

;	システムメニューのハンドル取得
	hSystemMenu = GetSystemMenu (hwnd)

;	第2パラに削除する項目。
;	$F000=サイズ変更、$F010=移動、$F020=最小化、$F030=最大化、
;	$F060=終了、$F120=元のサイズに戻す
	DeleteMenu hSystemMenu, $F010

↑TOP↑

ウィンドウの表示アニメート

 ウィンドウ表示のアニメーションができます。この AnimateWindow関数 はWindows 98/2k以降の対応です。第2パラは表示時間(ミリ秒)、第3パラは アニメーションのタイプ。

;	ウィンドウアニメーションサンプル (by Kpan)
;	!要Windows 98/2k以降

#uselib "user32"
#func AnimateWindow "AnimateWindow" int, int, int

#define AW_SLIDE $40000
#define AW_ACTIVATE $20000
#define AW_BLEND $80000
#define AW_HIDE $10000
#define AW_CENTER $10
#define AW_HOR_POSITIVE $1
#define AW_HOR_NEGATIVE $2
#define AW_VER_POSITIVE $4
#define AW_VER_NEGATIVE $8

	objsize 200
	button "スライドアニメート", *slide
	button "中央に向かってアニメート", *center
	button "フェードアウト/フェードイン", *fade
	
	stop

;	スライドアニメート
*slide
	AnimateWindow hwnd, 2000, AW_HOR_POSITIVE | AW_HIDE ; 左→右
	AnimateWindow hwnd, 2000, AW_HOR_NEGATIVE | AW_ACTIVATE ; 右→左
	AnimateWindow hwnd, 2000, AW_VER_POSITIVE | AW_HIDE ; 上→下
	AnimateWindow hwnd, 2000, AW_VER_NEGATIVE | AW_ACTIVATE ; 下→上
	stop

;	中央に向かってアニメート
*center
	AnimateWindow hwnd, 2000, AW_CENTER | AW_HIDE ; 中央に
	AnimateWindow hwnd, 2000, AW_CENTER | AW_ACTIVATE ; 元に戻る
	stop

;	ウィンドウのフェードアウト/フェードイン
*fade
	AnimateWindow hwnd, 1000, AW_BLEND | AW_HIDE ; フェードアウト
	AnimateWindow hwnd, 1000, AW_BLEND | AW_ACTIVATE ; フェードイン
	stop

↑TOP↑

ウィンドウの非アクティブ化チェック

 ウィンドウメッセージ「WM_ACTIVATE」は自ウィンドウがアクティブになった時と非アクティブになった時に通知されます。wparamの下位ワードにはアクティブの状態、wparamの上位ワードには最小化の状態かが返ります。

//	ウィンドウのアクティブ化・非アクティブ化

#define ctype LOWORD(%1) (%1 & $FFFF)
#define ctype HIWORD(%1) (%1 >> 16 & $FFFF)

;	WM_ACTIVATE
	oncmd gosub *activate, $6

	stop

*activate
;	0=非アクティブ化、1=クリック外でアクティブ化、2=マウスクリックでアクティブ化
	mes "状態: "+LOWORD(wparam)

;	0=通常、0以外=最小化状態
	mes "最小化: "+HIWORD(wparam)

	return

↑TOP↑

ウィンドウの無効化

 EnableWindow関数を使って自ウィンドウ全体の無効化 or 有効化の切り替えです。オブジェクト単体もこの関数を利用することで、有効無効の切り替えができます。(→参照、HSP3あれこれ チェックボックスの監視

//	ウィンドウの無効化  (by Kpan)

#include "user32.as"

	button "切り替え", *change

	screen 1
	hWindow = hwnd

	listbox a, 50, "HSP\nサンプル\nウィンドウ"
	chkbox "あいうえお", b

	gsel 0

	stop

*change
;	第2パラで状態指定。(1=有効化、0=無効化)
	EnableWindow hWindow, value

	value ^= 1

	if value {
		mes "無効"
	} else {
		mes "有効"
	}

↑TOP↑

ウィンドウの最大化・最小化判定

 このページで紹介しているように、ウィンドウスタイルを変更することで最大化ウィンドウが実現可能です。IsZoomed関数IsIconic関数を使って、ウィンドウが最大化状態か最小化(アイコン化)状態か普通の状態かの判定です。

//	ウィンドウの最大化・最小化状態の判定 (by Kpan)

#include "user32.as"

	screen , ginfo(20), ginfo(21)

	onexit gosub *exit

;	サイズ可変ウィンドウ化
	GetWindowLong hwnd, -16
	SetWindowLong hwnd, -16, stat | $10000 | $40000

	width 300, 300

	stop

*exit
;	第1パラにチェックするウィンドウハンドル値を指定

	IsIconic hwnd
	check.0 = stat

	IsZoomed hwnd
	check.1 = stat

	dialog "最小化: "+check.0+"\n最大化: "+check.1+"

	end

↑TOP↑

ウィンドウの半透明化

 SetLayeredWindowAttributes関数を利用して自ウィンドウを半透明化させる処理です。この関数は、Windows 2000以降で対応しており、Windows 9x系OSでは利用できません。透過時は通常よりもスペックが要求されます。

 簡単に流れを書くと、現在の拡張ウィンドウスタイルに「WS_EX_LAYERED」を追加して、SetLayeredWindowAttributes関数で透過状態にします。下のサンプルでは、トラックバーで透明度をリアルタイムで調節できるようにしてあります。

//	ウィンドウの半透明化 (by Kpan)
//	要 Windows 2000以降

#include "user32.as"

#define WS_EX_LAYERED $80000

#define LWA_COLORKEY 1
#define ULW_ALPHA 2

;	簡易的なOSチェック
	if varptr(SetLayeredWindowAttributes) = 0 {
		dialog "Windows 2000/XP/Vista じゃないっぽい。。。"
		end
	}

;	トラックバー用ウィンドウメッセージ
	oncmd gosub *vscroll, $114

;	拡張ウィンドウスタイルにWS_EX_LAYEREDを追加適用
	GetWindowLong hwnd, -20
	SetWindowLong hwnd, -20, stat | WS_EX_LAYERED

;	透明度調節用のトラックバー
	pos 200, 200
	winobj "msctls_trackbar32", "", , $50000000 | $100, 200, 30
	hTrackbar = objinfo(stat, 2)

;	TBM_SETPOS
	sendmsg hTrackbar, $405, 1, 100

	stop

;	EM_VSCROLL
*vscroll
	if lparam = hTrackbar {
;		TBM_GETPOS
		sendmsg hTrackbar, $400

;		第3パラに透明度 (アルファ値の範囲 0〜255)
		SetLayeredWindowAttributes hwnd, 0, 255 * stat / 100, ULW_ALPHA

		return
	}

	return

↑TOP↑

タイトルバーの点滅

 FlashWindow関数を使って、タイトルバーを点滅させます。点滅回数は1回で、複数回点滅させる場合はrepeat命令などを使用してください。Windows 98以降で点滅回数も指定できるFlashWindowEx関数というのももあります。

//	タイトルバーの点滅

#include "user32.as"

	wait 100
	FlashWindow hwnd, 1

↑TOP↑

タイトルバーのアイコン変更

 タイトルバー部分のアイコンをWindowsが持っているアイコンに変更します。すべてのウィンドウでアイコンが変わります。(LoadIcon関数についてはちょくとさんのページを参照)

//	タイトルバーアイコン変更サンプル1 (by Kpan)

#include "user32.as"

	screen 2

;	LoadIcon関数の第1パラにアイコンID。「32513」=「停止マーク」。
	LoadIcon 0 , 32513
	SetClassLong hwnd, -14, stat

	wait 200

;	元に戻すには
	LoadIcon hinstance, 128
	SetClassLong hwnd, -14, stat

 次は、個別ウィンドウごとにアイコンを変更します。

//	タイトルバーアイコン変更サンプル2 (by Kpan)

#include "user32.as"

	screen 2

;	LoadIcon関数の第1パラにアイコンID。「32515」=「!マーク」。
	LoadIcon 0 , 32515
	sendmsg hwnd, $80, 1, stat

	screen 3

;	「32514」=「?マーク」
	LoadIcon 0 , 32514
	sendmsg hwnd, $80, 1, stat

	wait 200

;	元のアイコンに戻す
	LoadIcon hinstance, 128
	sendmsg hwnd, $80, 1, stat

↑TOP↑

〜HSP3 あれこれ〜
ウィンドウ | オブジェクト | ファイル | フォルダ | キーボード | マウス | メニュー | システム | 文字列 | COM | その他

Copyright © 2005-2012 . All rights reserved.