Last Update : 2006/06/xx
スタティックテキスト(スタティックコントロール)は、単純に文字列を表示するオブジェクトです。文字の表示(正確には「描画」)を行うmes命令と違って、後で書き換える時にあらかじめ表示されている文字列を消す処理がいりません。
HSP2 (HSP 2.x) では、mesbox命令のスタイル2指定で利用できましたが、HSP3 (HSP 3.x)ではこのスタイルだけ廃止になっています。ただ、common\hsp3util.as モジュールファイルに代替として、スタティックテキストを作成する命令と、内容を変更する命令が用意されています(objprm命令を利用できないため)。内部的には、winboj命令を利用して表示する形になります。
スタティックテキストは文字列を表示するオブジェクトです。
ところで、このwinboj命令で作成したスタティックテキストは、HSPのfont命令やsysfont命令の効果を適用できません。というわけで、それと同等の効果を適用してみるサンプルです。このフォントの指定に関しては、ちょくとさんのページに詳しく書かれてあるのでチェック!
まずは、sysfont命令を利用している場合。この命令は、内部的には GetStockObject関数 に相当するものです。フォントの種類のパラメータ値はsysfont命令と同じです。
#uselib "gdi32" #cfunc GetStockObject "GetStockObject" int ; スタティックテキストの作成 ; 第2パラのウィンドウスタイルは[WS_CHILD + WS_VISIBLE = $50000000] ; オブジェクトのサイズを変更したい場合は、winobj命令の第3/4パラ、 ; あるいはobjsize命令で。 winobj "static", "こんにちは!", , $50000000 ; フォント設定 (WM_SETFONT) ; GetStockObject関数 の第1パラのフォントの種類を指定。 ; ここではデフォルトGUIフォント。 sendmsg objinfo(stat, 2), $30, GetStockObject(17)
次に、font命令の場合。以下のサンプルでは、ちょくとさんのページでも指摘されているように、これ以降にfont命令を呼び出すとデフォルトフォントがリセットされてしまいます。
; 普通にフォントを指定し、このフォントハンドルをBMSCR構造体から取得 font "MS ゴシック", 30, 2 mref bmscr, 67 : hFont = bmscr.38 winobj "static", "かきくけこ", , $50000000, 200, 30 ; フォント設定。取得したフォントハンドルを適用してやる。 ; objinfo関数の第1パラにはオブジェクトIDを入れます。 sendmsg objinfo(stat, 2), $30, hFont ; ちなみにスタティックテキストの文字列変更 (objprm命令相当) ; sendmsg objinfo(0, 2) ,$C , , "へんこー"
もし、フォントリセットを避けたい場合は、ちょくとさんページにも書かれてあるようにbuffer命令で別ウィンドウを作っておき、そこのフォント指定からフォントハンドルを取得しておく手段。
; 未使用の仮想ウィンドウを作成 buffer 1, 0, 0 ; この仮想ウィンドウ上からフォントハンドル取得 font "", 30, 16 | 1 mref bmscr, 67 : hFont = bmscr.38 ; 描画先を元のメインウィンドウに戻す。 gsel winobj "static", "フォフォフォントー", , $50000000, 200, 30 sendmsg objinfo(stat, 2), $30, hFont font "", 10 mes "上のbuffer命令、gsel命令をコメントアウトすると。。。"
[おまけネタ] スタティックコントロールのウィンドウスタイルを変更し、外観を変えるサンプル。ウィンドウスタイル一覧はちょくとさんのページ参照。winobj命令の第2パラに追加してやります。
syscolor 15 : boxf
objsize 400
winobj "static", "境界線枠 (WS_BORDER)", , $50000000 | $800000
winobj "static", "無効 (WS_DISABLED)", , $50000000 | $8000000
winobj "static", "膨らみ (WS_DLGFRAME)", , $50000000 | $400000
winobj "static", "真ん中テキスト (SS_CENTER)", , $50000000 | $1
winobj "static", "右寄りテキスト (SS_RIGHT)", , $50000000 | $2
winobj "static", "浅い凹み (SS_SUNKEN)", , $50000000 | $1000
; これは拡張ウィンドウスタイル(第1パラ)の変更
winobj "static", "深い凹み {WS_EX_WINDOWEDGE}", $200, $50000000
上のスタティックテキスト表示の発展になります。カーソルをスタティックテキストの上にもって行くと、ハンドカーソルに変わり(テキスト色は変わらず)、クリックするとブラウザが立ち上がって任意のウェッブページが開く、というような感じの簡易的なハイパーリンク処理を持つコントロールの作成です。
作成の流れとして、スタティックテキストを設置(上参照)、文字列の表示色を変更、フォントを変更(上参照)、ハンドカーソルに変更(マウスカーソルの変更参照)、マウスクリックした時の処理、という感じです。スタティックテキストの文字色を変更するのは色々と大変です。
; ハイパーリンクテキストサンプル1 (by Kpan) #uselib "gdi32" #func SetTextColor "SetTextColor" int, int #func SetBkMode "SetBkMode" int, int #uselib "user32" #cfunc GetSysColorBrush "GetSysColorBrush" int #cfunc LoadCursor "LoadCursorA" nullptr, int #func SetClassLong "SetClassLongA" int, int, int ; RGBマクロ #define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16) ; スタティックテキストを設置 ; マウスクリックで反応するようウィンドウスタイルにSS_NOTIFY($100) pos 50, 50 winobj "static", "ホームページ", , $50000001 | $100, 100, 13 ; オブジェクトのハンドル取得 hStatic = objinfo (stat, 2) ; スタティックテキストのフォント変更 ; アンダーラインを引いた文字列に font "MS Pゴシック", 12, 4 mref bmscr, 67 sendmsg hStatic, $30, bmscr.38 ; スタティックテキスト上のカーソルをハンドカーソルに変更 SetClassLong hStatic, -12, LoadCursor (32649) ; スタティックテキスト自体の背景色用ブラシのハンドルを取得 hBrush = GetSysColorBrush (15) ; スタティックテキストが描画されるときに送られてくるウィンドウ ; メッセージ (WM_CTLCOLORSTATIC) oncmd gosub *ctlcolorstatic, $138 ; マウスクリックした際のウィンドウメッセージ (WM_COMMAND) oncmd gosub *command, $111 stop *ctlcolorstatic ; lparamにオブジェクトのハンドルが返る if hStatic = lparam { ; テキスト色 (青) SetTextColor wparam, RGB ($00, $00, $FF) ; テキスト背景色 (透過) SetBkMode wparam, 1 ; スタティックテキスト自体の背景色を反映 return hBrush } return *command ; lparamにオブジェクトのハンドルが返る if hStatic = lparam { ; クリック時の処理。メルアドなら「mailto: 〜」。 exec "http://lhsp.s206.xrea.com/", 16 } return
次に、マウスカーソルがスタティックコントロール上に来るとテキスト色が変わる、というのにチャンレンジ。これが最良の方法かはよく分かりませんが...
カーソルの動きをリアルタイムで監視(WM_SETCURSORメッセージ)し、スタティックコントロール内にカーソルが入った事を確認(PtInRect関数)したら、色が変わるようスタティックコントロールを再描画(InvalidateRect関数)する、という処理を加えています。ここではハンドカーソル変更処理は省略しています。
; ハイパーリンクテキストサンプル2 (by Kpan) #uselib "gdi32" #func SetTextColor "SetTextColor" int, int #func SetBkMode "SetBkMode" int, int #uselib "user32" #cfunc GetSysColorBrush "GetSysColorBrush" int #func GetWindowRect "GetWindowRect" int, int #cfunc PtInRect "PtInRect" int, int, int #func InvalidateRect "InvalidateRect" int, int, int #define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16) pos 50, 50 winobj "static", "バージョン情報", , $50000001 | $100, 100, 13 hStatic = objinfo (stat, 2) ; 下線フォント font "MS Pゴシック", 12, 4 mref bmscr, 67 sendmsg hStatic, $30, bmscr.38 ; 下線なしで単なる色変化だけなら以下のように ; (GetStockObject関数の#cfunc宣言要) ; sendmsg hStatic, $30, GetStockObject (17) hBrush = GetSysColorBrush (15) oncmd gosub *ctlcolorstatic, $138 oncmd gosub *command, $111 ; WM_SETCURSOR oncmd gosub *wmsetcursor, $20 ; RECT構造体用 dim RECT, 4 stop *ctlcolorstatic if hStatic = lparam { if oncursor { crColor = RGB ($FF, $00, $00) } else { crColor = RGB ($00, $00, $FF) } SetTextColor wparam, crColor SetBkMode wparam, 1 return hBrush } return *command if hStatic = lparam { dialog "ハイパーリンクサンプル by Kpan", , "情報" } return *wmsetcursor if (lparam & $FFFF) != 1 : return ; オブジェクトの左上XY、右下XYの座標位置を取得 GetWindowRect hStatic, varptr (RECT) ; 取得したオブジェクトの座標位置とカーソルの座標位置を比較 if PtInRect (varptr (RECT) , ginfo (0), ginfo (1)) { if oncursor : return InvalidateRect hStatic oncursor = 1 } else { if oncursor = 0 : return InvalidateRect hStatic oncursor = 0 } return
上のスタティックテキスト表示、ハイパーリンクテキスト表示の発展になります。スタティックテキストを作成し、これをクリックすると色選択ダイアログが表示され、選択した色が表面色として反映される、といった感じのオブジェクトです。
上のハイパーリンクテキスト表示でも言えることですが、何もわざわざWindows APIを呼ばないで、マウスカーソルの動きを監視して、標準のboxf命令やらcolor命令やら駆使すれば実現できる代物ではありますが・・・。
; カラー表示オブジェクトサンプル by Kpan
#uselib "gdi32"
#cfunc CreateSolidBrush "CreateSolidBrush" int
#func DeleteObject "DeleteObject" int
#uselib "user32"
#func InvalidateRect "InvalidateRect" int, int, int
#define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16)
syscolor 15 : boxf
; スタティックコントロールを作成
; ウィンドウスタイルを変更して見た目を変えています。
pos 50, 50
winobj "static", "", $1, $50000000 | $100, 35, 35
; オブジェクトのハンドルを取得しておく
hStatic.0 = objinfo (stat, 2)
; 初期の表示色を指定しておく場合はこんな感じ
hBrush.0 = CreateSolidBrush (RGB ($FF, $FF, $00))
; 2つ目のスタティックコントロール
pos 50, 100
winobj "static", "", $20000, $50000000 | $400000 | $100, 35, 35
hStatic.1 = objinfo (stat, 2)
hBrush.1 = CreateSolidBrush (RGB ($FF, $00, $00))
; WM_COLORSTATIC
; スタティックコントロールの色を変更する処理
oncmd gosub *ctlcolorstatic, $138
; WM_COMMAND
; スタティックコントロールをクリックした時の処理
oncmd gosub *command, $111
onexit *exit
stop
*ctlcolorstatic
if hStatic.0 = lparam : return hBrush.0
if hStatic.1 = lparam : return hBrush.1
return
*command
if hStatic.0 = lparam | hStatic.1 = lparam {
hControle = lparam
; 色選択ダイアログ
dialog , 32
if stat = 1 {
rgbclr = RGB (ginfo (16),ginfo (17),ginfo (18))
if hStatic.0 = hControle {
; 変更前のブラシの破棄
if hBrush.0 != 0 : DeleteObject hBrush.0
; 選択した色のブラシを作成
hBrush.0 = CreateSolidBrush (rgbclr)
}
if hStatic.1 = hControle {
if hBrush.1 != 0 : DeleteObject hBrush.1
hBrush.1 = CreateSolidBrush (rgbclr)
}
; 色を反映させるためコントロールを再描画させる
InvalidateRect hControle
}
}
return
*exit
; 作成したブラシの破棄
DeleteObject hBrush.0
DeleteObject hBrush.1
end
自分自身の実行ファイルが持っているアイコンをオブジェクトとして表示してみます。
Windows APIのLoadImage関数で自分自身からアイコンを読み込み、sendmsg命令を使ってスタティックコントロールに貼り付ける、という流れです。スタティックコントロールには、文字列の表示以外にも画像(BMP/ICOファイル)を表示させる機能も持っています。
このサンプルを元に作成したアイコン表示オブジェクト設置モジュールをこのページの最下部から入手できます。ついでに、マウスでアイコンのクリックorダブルクリックすると反応するバージョンのモジュールも含めてあります。
; アイコン表示オブジェクト #uselib "user32" #cfunc LoadImage "LoadImageA" int, sptr, int, int, int, int pos 50, 50 ; スタティックコントロールを設置 ; ウィンドウスタイルにアイコンの表示を行うSS_ICON($3)を指定 winobj "static", "", , $50000000 | $3 hStatic = objinfo (stat, 2) ; 実行ファイルからアイコンのハンドルを取得 ; p1=インスタントハンドル ; p2=アイコン名 (HSP製実行ファイルは128) ; p3=画像タイプIMAGE_ICON(1) ; p4,p5=表示したいアイコンサイズ ; p5=LR_SHARED($8000) hIcon = LoadImage (hinstance, 128, 1, 32, 32, $8000) ; スタティックコントロールにアイコンハンドルを適用 sendmsg hStatic, $170, hIcon
上のサンプルは、あくまでアイコンが表示されているオブジェクト(コントロール)です。ついでネタとして、DrawState関数を使ってウィンドウ上にアイコンを「描画」するサンプルソースです。(同関数を使った文字表示サンプルソースはこちら〜)
; アイコン描画 #uselib "user32" #cfunc LoadImage "LoadImageA" int, sptr, int, int, int, int #func DrawState "DrawStateA" int, int, int, sptr, int, int, int, int, int, int syscolor 15 : boxf ; 自分自身のアイコンを読み込みハンドル取得 hIcon = LoadImage (hinstance, 128, 1, 32, 32, $8000) ; パラメータがたいそう多いですが、p6〜p7が表示するXY座標位置、 ; p10はアイコン表示を意味するDST_ICON($3)を必ず指定 DrawState hdc, , , hIcon, , 50, 50, , , $3 ; DSS_DISABLED($20)を加えると無効状態風アイコン DrawState hdc, , , hIcon, , 100, 100, , , $3 | $20 ; 再描画で反映されます redraw
HSP 2.x の時だと、color命令 + line命令 あたりを使って描画する感じだったでしょうか。winboj命令でサクっと表示できます。区切り線(セパレータライン)は実際のところスタティックコントロールの見た目を変えただけです。
syscolor 15 boxf ; 横線の場合。第3パラが長さ pos 50, 50 winobj "static", "", , $50000000 | $10, 200 ; 縦線の場合。第4パラが長さ pos 70, 100 winobj "static", "", , $50000000 | $11, , 100
上のサンプルを元に、縦方向と横方向の区切り線を表示するモジュールをこのページの最下部にて公開しています。わざわざモジュールにしなければならないほどの複雑なソーススクリプトではありませんが... (^^;
そして、上の「スタティックテキストの表示」とこの「区切り線の表示」を合体した自前コントロールを表示するモジュールも公開しています。区切り線(セパレータライン)上の任意の位置に、文字列表示のスタティックテキスト(スタティックコントロール)が表示されます。標準の mes命令 + line命令 で十分な代物でありますが...
ついでに、DrawEdge関数を利用したボーダー風囲い枠の描画サンプルソース。
#uselib "user32" #func DrawEdge "DrawEdge" int, int, int, int syscolor 15 : boxf ; DrawEdge関数 ; 第1パラはデバイスコンテキストのハンドル (hdcを指定) ; 第2パラは矩形サイズ (左上XY座標、右下XY座標を指定) ; 第3パラに境界線の形状スタイル ; 1列目 ; BDR_RAISEDOUTER (外側隆起) rect = 20, 20, 100, 100 DrawEdge hdc, varptr (rect), $1, $F ; BDR_SUNKENOUTER (外側陥没) rect = 120, 20, 200, 100 DrawEdge hdc, varptr (rect), $2, $F ; BDR_RAISEDINNER (内側隆起) rect = 220, 20, 300, 100 DrawEdge hdc, varptr (rect), $4, $F ; BDR_SUNKENINNER (内側陥没) rect = 320, 20, 400, 100 DrawEdge hdc, varptr (rect), $8, $F ; 2列目 (以下は境界線の形状スタイル組み合わせ) rect = 20, 120, 100, 200 DrawEdge hdc, varptr (rect), $1 | $4, $F rect = 120, 120, 200, 200 DrawEdge hdc, varptr (rect), $1 | $8, $F rect = 220, 120, 300, 200 DrawEdge hdc, varptr (rect), $2 | $4, $F rect = 320, 120, 400, 200 DrawEdge hdc, varptr (rect), $2 | $8, $F ; 実際に表示を反映させるには再描画が必要な場合あり ; (redraw命令やwidth命令あたりで redraw
このページで紹介しているサンプルスクリプトに基づいたモジュールです。自分自身のアイコン表示モジュール、区切り線描画モジュール、スタティックテキスト付き区切り線描画モジュールの3ファイルを含んでいます。(HSP 3.x用)
<< オブジェクト編 2 | HSP3 オブジェクト | オブジェクト編 4 >>
Copyright © 2005-2008 Kpan. All rights reserved.