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
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以前の未対応環境" }
ウィンドウにおけるリージョンオブジェクトの作成です。四角形ウィンドウのところをあらかじめ指定した形状に変更します。丸いウィンドウや三角形ウィンドウなどが実現できます。ちょくとさんのページを参照。
マウスでウィンドウを移動できるようにするには、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
タイトルバーをドラッグしても移動できないウィンドウを作成するには、システムメニューの[移動]項目を削除することで実現できます。
#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
ウィンドウ表示のアニメーションができます。この 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
ウィンドウメッセージ「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
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 "有効" }
このページで紹介しているように、ウィンドウスタイルを変更することで最大化ウィンドウが実現可能です。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
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
FlashWindow関数を使って、タイトルバーを点滅させます。点滅回数は1回で、複数回点滅させる場合はrepeat命令などを使用してください。Windows 98以降で点滅回数も指定できるFlashWindowEx関数というのももあります。
// タイトルバーの点滅 #include "user32.as" wait 100 FlashWindow hwnd, 1
タイトルバー部分のアイコンを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
Copyright © 2005-2012 Kpan. All rights reserved.