Last Update : 2006/11/xx
combox命令で設置できるコンボボックスオブジェクト。このページでは、このコンボボックス関連の発展的なサンプルソースを掲載しています。基礎的な説明は、combox命令の解説を参照。
ちなみに、コンボボックスコントロール全般についての詳細な説明として、Delphi言語向けですがHalbow資料館さんの該当ページをチェック!
※注意!
Windows XP以降で、combox命令の第2パラメータで指定できる縦方向サイズ(ドロップダウンリストの高さ)は、HSP2と違って特定の数値しか反映されないバグ(?)があります。フォントサイズやオブジェクトの大きさの違いで、反映可能な数値がコロコロ変わって・・・。(?_?;
combox命令は、第3パラメータに項目として表示する文字列をあらかじめ指定しておきます。もし設置後に文字列の追加や削除を行うには、note系命令+objprm命令を利用して、項目全体を変更する方法が1つ。ここでは、sendmsg命令でいじってみることにします。
; コンボボックス項目追加&削除サンプル (by Kpan) objsize 100 combox a, , "あー\nかー\nさー\nたー\nなー\nはー" ; コンボボックスのハンドル取得 hCombox = objinfo (stat, 2) button "追加", *add_item button "挿入", *ins_item button "削除", *del_item stop *add_item ; 最後部に項目を追加 (CB_ADDSTRING) ; 第4パラ(lparam値)に追加する文字列を指定。 sendmsg hCombox, $143, , "★最後部に追加" stop *ins_item ; 現在選択中のインデックス番号を取得 (CB_GETCURSEL) ; statに選択状態のインデックス番号(0〜)が返ります sendmsg hCombox, $147 ; 特定位置の項目に挿入 (CB_INSERTSTRING) ; 第3パラのwparam値に挿入するインデックス番号(0〜)を指定 ; ここでは選択項目の真下に挿入されます sendmsg hCombox, $14A, stat + 1, "●特定項目に挿入" stop *del_item sendmsg hCombox, $147 ; 特定の項目の削除 (CB_DELETESTRING) ; 第3パラのwparam値に削除するインデックス番号(0〜)を指定 sendmsg hCombox, $144, stat stop
コンボボックス内の特定項目に表示されている文字を取得します。あらかじめ配列変数に用意しておいた文字列を、note系命令で取り出す方法もありますが、sendmsg命令の項目指定で取り出すことができます。
; コンボボックス項目文字列取得サンプル (by Kpan) ; 文字列が返る変数用の領域をあらかじめ確保。 sdim combox_text objsize 100 combox a, 60, "蟷螂\n甲虫\n蟋蟀\n蜻蛉\n飛蝗\n蜘蛛" hCombox = objinfo (stat, 2) button "こんちゅう", *check stop *check ; 特定の項目の文字列を取得 (CB_GETLBTEXT) ; 第3パラのwparam値にインデックス番号(0〜)、 ; 第4パラのlparam値に取得した文字列を入れる変数ポインタ ; statには文字列の長さ(バイト単位)が返ります。 sendmsg hCombox, $148, a, varptr (combox_text) mes ""+combox_text+" ["+stat+"byte] ; <別手法> 現在選択中の文字列を取得 (WM_GETTEXT) ; 第4パラのlparam値に取得した文字列を入れる変数ポインタ ; statには文字列の長さ(バイト単位)が返ります。 sendmsg hCombox, $D, 64, varptr (combox_text) mes ""+combox_text
combox命令は、第1パラメータの変数を確認することで、選択されているインデックス番号(0〜)を取得できます。HSP2の場合、これをリアルタイムで監視するには、スクリプト内でループさせて、この変数を変化をチェックする手段をとったでしょうが、HSP3からはoncmd命令のお世話になりましょう。
具体的には、コンボボックス内に変化があるとウィンドウメッセージ WM_COMMAND が通知されます。リストボックス(listbox命令) も同じ。
; コンボボックス監視サンプルスクリプト (by Kpan) ; WM_COMMAND oncmd gosub *command, $111 objsize 100 combox a, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" hCombox = objinfo (stat, 2) stop *command ; lparamにはコンボボックスのハンドルが返る if lparam = hCombox { ; wparamの上位ワードには通知コードが返る wNotifyCode = wparam >> 16 & $FFFF ; 通知コード1の場合は選択状態変化 if wNotifyCode = 1 { ; 現在選択中のインデックス番号取得 (CB_GETCURSEL) ; (変数aは利用しません) sendmsg hCombox, $147 title "インデックス番号: "+stat } } return
コンボボックスは、実は2つのコントロールから成り立ってます。選択されている文字列を表示しておくエディットコントロールと、マウスクリックするとドロップダウンリストが表示されるリストボックスコントロールです。
文字色を変更するには、この2つのコントロールの色をそれぞれ変更する処理を用意しなくてはなりません。それぞれのウィンドウメッセージについては、WM_CTLCOLOREDITのサンプル、WM_CTLCOLORLISTBOXのサンプルを参照〜。少々面倒ですが、HSP3のoncmd命令の登場でそれなりに楽に実現できるようになりました。
エディトコントロール部分のハンドル値は、コンボボックス自体のハンドル値と全く同じです。一方、リストボックスコントロール部分のハンドル値は、GetComboBoxInfo関数(Windows 98以降)を呼んで、COMBOBOXINFO構造体を見ることになります。
オブジェクト | ハンドル値の取得方法 |
コンボボックスコントロール | HSPのobjinfo関数 |
- エディト部 | (上と同じ & 同じ値) |
- リストボックス部 | GetComboBoxInfo関数 |
; コンボボックスの文字色変更サンプルソース (by Kpan) ; !要Windows 98以降 #uselib "gdi32" #func SetTextColor "SetTextColor" int, int #uselib "user32" #cfunc GetSysColorBrush "GetSysColorBrush" int #func GetComboBoxInfo "GetComboBoxInfo" int, int ; RGBマクロ (RRGGBB -> BBGGRR) #define ctype RGB(%1,%2,%3) (%1 | %2 << 8 | %3 << 16) objsize 100 ; COMBOBOXINFO構造体用 dim COMBOBOXINFO, 13 COMBOBOXINFO = $34 ; 1つ目のコンボボックス combox a, , "赤と青\nレッドとブルー\nあかとあお" hCombox.0 = objinfo (stat, 2) ; COMBOBOXINFO構造体からリストボックス部のハンドル取得 GetComboBoxInfo hCombox.0, varptr (COMBOBOXINFO) hComboxList.0 = COMBOBOXINFO.12 ; 2つ目のコンボボックス combox b, , "黄色と水色\nイエローとライトブルー\nきいろとみずいろ" hCombox.1 = objinfo (stat, 2) GetComboBoxInfo hCombox.1, varptr (COMBOBOXINFO) hComboxList.1 = COMBOBOXINFO.12 ; ウィンドウ背景色のブラシを取得 (コンボボックス自体の背景色用) hBrush = GetSysColorBrush (5) ; ウィンドウメッセージ WM_CTLCOLOREDIT oncmd gosub *ctlcoloredit, $133 ; ウィンドウメッセージ WM_CTLCOLORLISTBOX oncmd gosub *ctlcolorlistbox, $134 stop *ctlcoloredit ; lparamにエディットコントロール部分(=コンボボックス)の ; ハンドルが返る。 if lparam = hCombox.0 { SetTextColor wparam, RGB ($FF, $00, $00) return hBrush } if lparam = hCombox.1 { SetTextColor wparam, RGB ($FF, $FF, $00) return hBrush } return *ctlcolorlistbox ; lparamにリストボックスコントロール部分のハンドルが返る。 if lparam = hComboxList.0 { ; 2つのコントロールから成り立っていることが分かるよう、 ; あえて色違いにしています。 SetTextColor wparam, RGB ($00, $00, $FF) return hBrush } if lparam = hComboxList.1 { SetTextColor wparam, RGB ($00, $FF, $FF) return hBrush } return
コンボボックスは、上の文字色変更でも触れているように、2つのコントロールから成り立っているのですが、objsize命令でコンボボックスの横幅サイズを指定すると、リストボックスコントロール部分はそのままエディットコントロール部分と同じ横幅になります。
もし、項目として用意した文字列が長い場合、すべてが表示されません。そこで、リストボックスコントロール部分に当たるドロップダウンリストの横幅サイズだけ広げてしまいましょう。
; ドロップダウンリスト部分の横幅サイズ変更サンプル (by Kpan) message = "どーも\nHot Soup Processor\nLet's HSP!" ; 通常 combox a, , message combox b, , message hCombox = objinfo (stat, 2) ; 横幅サイズの設定 (CB_SETDROPPEDWIDTH) ; 第3パラのwparam値に横幅サイズ(ピクセル単位)を指定 sendmsg hCombox, $160, 150
コンボボックス内に項目として表示できるのは、基本的に文字列だけです。ここでは「オーナードロー」(HSP開発wiki参照)という処理を行って、項目として各種カラーで塗りつぶした四角形と文字列を持った色選択コンボボックスを作成してみます。(「拡張コンボボックス」というパワーアップ版コントロールもあるけど・・・
HSP3のoncmd命令の登場により一応実現できるようになりましたが、Windows APIを駆使して項目をすべて自前で描画しないといけません。標準のcombox命令は使えないので、winobj命令でコンボボックスを設置し、ウィンドウメッセージWM_DRAWITEMが通知されたら、DRAWITEMSTRUCT構造体を見て、項目内部を描画していきます。
モジュール+サンプルソースはこちら。モジュールになっているのは、winobj命令で空っぽのオーナードローコンボボックスを設置する部分だけです。Windows APIを使った描画まわりの説明は、ほとんど用意していませんので、あしからず・・・。(^o^;
<< オブジェクト 4 | HSP3 オブジェクト | オブジェクト 6 >>
Copyright © 2005-2012 Kpan. All rights reserved.