Last Update : 2007/09/xx
input命令 と mesbox命令。HSP上では別命令になっていますが、内部的には全く同じ「エディットコントロール」というオブジェクトで、1行表示 or 複数行表示 というのが主な違いです。
このオブジェクトに関する基礎的な解説講座は、input命令の解説(エンターキー判定、パスワードボックス)やmesbox命令の解説のページを参照あれ〜。
入力ボックスやメッセージボックスのスタイルを変更してみるサンプルです。文字列の表示位置(中央、右寄せ)を変更したり、数字しか入力できないボックスを用意することができます。スタイルの詳細は、ちょくとさんのページ (ウィンドウスタイル、コントロール固有のスタイル) を参照。
まずは mesbox命令。これは mesbox命令 のp4でスタイルの変更ができてしまいます。ボタンやチェックボックスのスタイル変更では省略してしまいましたが、現在のウィンドウスタイルを取得する GetWindowLong関数 があったほうがよいでしょう。
; エディトコントロールのウィンドウスタイル変更サンプル (by Kpan) #uselib "user32" #cfunc GetWindowLong "GetWindowLongA" int, int #func SetWindowLong "SetWindowLongA" int, int, int objsize 200, 50 ; テキスト表示位置変更 ($1=中央、$2=右寄り) x = "まんなか" mesbox x hMesbox = objinfo (stat, 2) SetWindowLong hMesbox, -16, GetWindowLong (hMesbox, -16) | $1 ; 特定文字変換入力 ($8=大文字変換、$10=小文字変換) x = "必ず大文字" mesbox x hMesbox = objinfo (stat, 2) SetWindowLong hMesbox, -16, GetWindowLong (hMesbox, -16) | $8 ; 数値のみ入力可 (数値専用=$2000) ; $2001 のように組み合わせれば「中央表示の数字のみ」となります x = "数字しか入らんよ" mesbox x hMesbox = objinfo (stat, 2) SetWindowLong hMesbox, -16, GetWindowLong (hMesbox, -16) | $2000
次に、input命令。入力ボックスのスタイルは、WS_CHILD + WS_VISIBLE + WS_TABSTOP + ES_AUTOHSCROLL = $50010080 となっているので、GetWindowLong関数 部分は省略しています。
#uselib "user32" #func SetWindowLong "SetWindowLongA" int, int, int objsize 200 ; ここでは右寄せの例だけ。mesbox命令で登場した他のスタイルも利用可 x = "右にホイ" input x SetWindowLong objinfo (stat, 2), -16, $50010080 | $2
Windowsのデフォルト設定では、黒(文字色)と白(背景色)になっている入力ボックスやメッセージボックスの表示色を変更するサンプルです。HSP2では、さすがに拡張プラグインやマシン語などを利用しないと実現できなかった代物ですが、HSP3ではoncmd命令の登場により、それなりに楽に実装できるようになりました。
まずは、文字色だけの変更。サンプルでは、input命令のみ使用していますが、同じエディットコントロールであるmesbox命令(書き換え可スタイルのみ)でも利用できます。文字全体が1つの指定した色になります。文字の単語ごとに異なる色を表示するようなことは不可能です(→リッチエディトコントロール)。
; エディトコントロール内文字色変更サンプル (by Kpan) #uselib "gdi32" #func SetTextColor "SetTextColor" int, int #cfunc GetStockObject "GetStockObject" int ; 色指定用のRGBマクロ (0x00BBGGRR形式へ変換) #define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16) ; エディットコントロールが描画されるときに送られてくる ; ウィンドウメッセージ (WM_CTLCOLOREDIT) oncmd gosub *ctlcoloredit, $133 a = "文字色だけ変えてみる" input a, 200 ; 入力ボックスオブジェクトのウィンドウハンドルを取得 hInput = objinfo (stat, 2) ; オブジェクトの背景用に白色ブラシのハンドルを取得 hBrush = GetStockObject (0) stop *ctlcoloredit ; lparamにウィンドウハンドルが返るのでそれで見分ける if hInput = lparam { ; SetTextColor関数。呼んで字のごとく文字色設定です ; 第1パラにデバイスコンテキストのハンドル(wparamを指定) ; 第2パラに文字色 (ここでは黄色) SetTextColor wparam, RGB ($FF, $FF, $00) ; 白色ブラシのハンドルを返す return hBrush } return
次に文字色とともに背景色部分も変更。処理がさらに増えます。
; エディトコントロール内文字色&背景色変更サンプル (by Kpan) #uselib "gdi32" #func SetTextColor "SetTextColor" int, int #func SetBkColor "SetBkColor" int, int #cfunc CreateSolidBrush "CreateSolidBrush" int #func DeleteObject "DeleteObject" int #define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16) oncmd gosub *ctlcoloredit, $133 onexit *exit a = "文字色&背景色を変えてみる1" input a, 200 hInput1 = objinfo (stat, 2) b = "文字色&背景色を変えてみる2" input b, 200 hInput2 = objinfo (stat, 2) ; オブジェクトの背景用にブラシを作成しハンドルを取得。 ; ここでは赤とピンク。このように作成したブラシは最後に ; 削除しておく必要があるようです。 hBrush.0 = CreateSolidBrush (RGB ($FF, $00, $00)) hBrush.1 = CreateSolidBrush (RGB ($FF, $00, $FF)) stop *ctlcoloredit if hInput1 = lparam { SetTextColor wparam, RGB ($FF, $FF, $00) ; テキスト背景色 (hBrush.0と同色を指定) SetBkColor wparam, RGB ($FF, $00, $00) return hBrush.0 } if hInput2 = lparam { SetTextColor wparam, RGB ($00, $FF, $00) ; テキスト背景色 (hBrush.1と同色を指定) SetBkColor wparam, RGB ($FF, $00, $FF) return hBrush.1 } return *exit ; 作成した背景用ブラシを削除 DeleteObject hBrush.0 DeleteObject hBrush.1 end
input命令 を書き換え不可、書き込み禁止、つまり編集できないグレー(灰色/淡色)表示にします。sendmsg命令 でサクッとできます。メッセージボックス(mesbox命令)に対しても、同じ方法で編集無効 or 無効解除が可能です。
; [おまけ] 見た目だけ編集無効風 (入力可) input a sendmsg objinfo (stat, 2), $A ; 編集無効。sendmsgの第3パラを1にすると編集できなくなる (EM_SETREADONLY) input b hinput = objinfo (stat, 2) sendmsg hinput, $CF, 1 button "解除", *change stop *change ; 第3パラを0(ここでは省略)にすると編集できるように sendmsg hInput, $CF
少し発展的なネタコードとして、上のように編集無効のオブジェクトにした場合、背景色が灰色(っぽい色)になり、編集できるオブジェクトとできないオブジェクトの違いというのが目に見えるわけですが、編集できないにも関わらず真っ白背景という状態の入力ボックスやメッセージボックスの作成です。
; 真っ白背景の使用不可エディトコントロールサンプル (by Kpan) #uselib "gdi32" #cfunc GetStockObject "GetStockObject" int #func SetBkMode "SetBkMode" int, int a = "真っ白背景の書き換え不可なインプットボックスでーす" input a, 300 ; インプットボックスのウィンドウハンドル取得 hInput = objinfo (stat, 2) ; 普通に編集不可にする sendmsg hInput, $CF, 1 b = "真っ白背景の\n 書き換え不可な\n メッセージボックスだ" mesbox b, 300, 100, 0 ; メッセージボックスのハンドルを取得 hMesbox = objinfo (stat, 2) ; 背景色用として白色ブラシのハンドルを取得 hBrush = GetStockObject () ; WM_CTLCOLORSTATIC oncmd gosub *ctlcolorstatic, $138 stop *ctlcolorstatic ; lparamにオブジェクトのハンドルが返る if lparam = hInput | lparam = hMesbox { ; 文字の背景を透過モード SetBkMode wparam, 1 ; 白色ブラシを返す return hBrush } return
input命令 は、第4パラメータで入力できる最大文字数を指定できます。もし文字数が超えたら反応するサンプルコードです。HSP2では、input命令で指定した変数の長さをループ中に逐一チェックする方法をとったでしょうが、HSP3はoncmd命令のお世話になりましょう。
※注意!
Windows XP環境以降のHSP3製実行ファイルは、文字数をUnicode形式で数える仕様があります(HSP
HELP CENTERさんの該当スレッド、MSサポート「この動作は仕様です」)。下の7文字制限を例にすると、XP(SP2)環境では全角7文字超えであふれます。一方、XP以前の環境では全角3文字超えであふれることになります。OSにより全角文字列を扱いが異なる・・・、ということではてさて。(-_-;
; (注! 環境により挙動が。。。)
; 上位ワード取得用マクロ
#define ctype HIWORD(%1) (%1 >> 16 & $FFFF)
; ウィンドウメッセージ (WM_COMMAND)
oncmd gosub *command, $111
; ここでは7文字制限
a = ""
input a, 100, 22, 7
hInput = objinfo (stat, 2)
stop
*command
; lparamにウィンドウハンドル
if lparam = hInput {
; wparamの上位ワードに通知コード
; (文字数が越えると EN_MAXTEXT が通知される)
if HIWORD (wparam) = $501 {
mes "あっぷっぷー"
}
}
return
ウィンドウメッセージWM_COMMANDネタついでに、テキスト内容のリアルタイム監視。
; 上位ワード取得用マクロ
#define ctype HIWORD(%1) (%1 >> 16 & $FFFF)
oncmd gosub *command, $111
a = ""
input a, 200
hInput = objinfo (stat, 2)
stop
*command
if lparam = hInput {
; wparamの上位ワードに通知コード
; (内容が変更されると EN_CHANGE が通知される)
if HIWORD (wparam) = $300 {
title ""+a+" ["+strlen (a)+"]
}
}
return
入力ボックスの左側部分と文字の先頭部分に余白(マージン)を設けてみーる。
#uselib "user32" #func PostMessage "PostMessageA" int, int, int, int a = "Let's HSP!" input a, 200 hInput = objinfo (stat, 2) ; EM_SETMARGINS ; 第4パラのlparam値に幅(ピクセル単位) PostMessage hInput, $D3, 1, 20
input命令には、入力部分まわりの境界線枠が付いています。これは、拡張ウィンドウスタイルに WS_EX_CLIENTEDGE ($200) が指定されているためです。これを取り外すことで、枠のない入力ボックスというのが実現できます。(ちょくとさんのページ拡張ウィンドウスタイルも参照。
SetWindowLong関数 で新たな拡張ウィンドウスタイルを指定してやります。普通のウィンドウスタイルの変更と違って、拡張ウィンドウスタイルの場合は、SetWindowPos関数 を呼び出して再描画をやらないと実際に変更が反映されないようです。
; 境界線なしエディトコントロール表示サンプル (by Kpan) #uselib "user32" #func SetWindowLong "SetWindowLongA" int, int, int #func SetWindowPos "SetWindowPos" int, nullptr, nullptr, nullptr, \ nullptr, nullptr, int ; ↑長いので改行しています。1行にする場合は「\」を取ってください。 x = "あいうえお" objsize 200, 50 pos 50, 50 ; 普通の枠あり入力ボックス ; これには拡張ウィンドウスタイルに $200 が指定されている。 input x pos 50, 100 ; 枠なし入力ボックス ; objinfo関数の第1パラにオブジェクトIDを入れます。 ; 拡張ウィンドウスタイルに $0(何もなし) を指定してやる。 input x SetWindowLong objinfo (1, 2), -20, $0 ; スタイルを変えて SetWindowPos objinfo (1, 2), $27 ; 再描画 pos 50, 150 ; [おまけ] 少し沈んだ枠($20000)あり入力ボックス input x SetWindowLong objinfo (2, 2), -20, $20000 SetWindowPos objinfo (2, 2), $27
また、 input命令 と同じように、mesbox命令 や listbox命令 も 拡張ウィンドウスタイル に WS_EX_CLIENTEDGE ($200) が指定されています。上のサンプルと同じようにすればOKです。
mesbox命令のメッセージボックスには、第4パラメータのスタイルごとに違いますが、右側と下側にスクロールバー(垂直、水平)が表示されます。ShowScrollBar関数を利用したスクロールバーの表示、非表示の切り替えです。
; メッセージボックスのスクロールバー表示・非表示サンプル (by Kpan) #uselib "user32" #func ShowScrollBar "ShowScrollBar" int, int, int #define SB_BOTH 3 ; 両方 #define SB_HORZ 0 ; 水平バー #define SB_VERT 1 ; 垂直バー a = "AAAAABBBBBCCCCCDDDDDEEEEEFFFFFGGGGG" ; ShowScrollBar関数 ; 第1パラにオブジェクトのウィンドウハンドル ; 第2パラに対象バーの指定 ; 第3パラに表示(1) or 非表示(0) ; 両方のバーなし、折り返しあり mesbox a, 200, 50, 1 ShowScrollBar objinfo (stat, 2), SB_VERT, 0 ; 水平バーのみ、折り返しなし mesbox a, 200, 50, 5 ShowScrollBar objinfo (stat, 2), SB_VERT, 0 ; 両方のバーなし、折り返しなし mesbox a, 200, 50, 5 ShowScrollBar objinfo (stat, 2), SB_BOTH, 0 ; 垂直バーのみ、折り返しなし mesbox a, 200, 50, 5 ShowScrollBar objinfo (stat, 2), SB_HORZ, 0
<< オブジェクト編 1 | HSP3 オブジェクト | オブジェクト編 3 >>
Copyright © 2005-2008 Kpan. All rights reserved.