〜 オブジェクト編 〜
01.listbox,combox,chkboxの選択が変更されたか調べる
08.ボタンのジャンプ先を統一してどのボタンが押されたか判定する
18.オブジェクトを灰色表示(利用不可)にする (要llmod.as)
25.クリップボード履歴をオブジェクトに入れていく (要hspext.dll)
29.キャレットの点滅速度取得・設定モジュール (要llmod.as)
35.llmod拡張オブジェクトIDを後から知る (要llmod.as)
36.変換中の文字列の長さを取得するモジュール (要llmod.as)
37.変換中の文字列を取得するモジュール (要llmod.as)
38.変換中の文字列を取り消すモジュール (要llmod.as)
39.変換中の文字列の読みを取得するモジュール (要llmod.as)
40.指定オブジェクト上にカーソルがあるかを取得するモジュール (要llmod.as)
41.エディットボックスに数値しか入れられなくするモジュール (要llmod.as)
42.エディットボックスのテキスト位置を変更するモジュール (要llmod.as)
43.ボタンに表示するテキスト位置を変更するモジュール (要llmod.as)
01.listbox,combox,chkboxの選択が変更されたか調べる
あらかじめどの項目(インデックス)が選択されているかを記憶させておき、
メインとなる部分をループにして、ループのたびにインデックスをチェックして、
もし記憶したインデックスと異なっていればループを抜けて処理を行います。
(例)リストボックス等で選択項目を変更したかどうかを監視する
listbox lst,100,"項目0\n項目1\n項目2\n項目3"
*set
lst2=lst ; インデックスを記憶する
repeat
wait 1
if lst!=lst2 : break ; 項目が変わったらループから抜ける
loop
dialog "項目"+lst+"が選択されました",2,"監視"
goto *set
こちらも01同様に変数に内容を保存して…としてもよいのですが、
mesbox,input(総称してエディットコントロールと呼ぶ)は常に監視しなくても、「objsend」でチェック出来ます。
書式は「objsend オブジェクトID,$b8,0,0,1」ですがp4は変数で指定しないとダメなので、
0を入れた変数で指定します。p4についての参照はコチラ
もし内容が変更されている場合システム変数「stat」に1が、変更なしの場合は0が入ります。
(例)終了の際に変更されていたら警告を出す
onexit *exit ; 終了間際にexitへジャンプ
buf=""
pos 100,50 : input buf,200,25,64
stop
*exit
a=0 ; p4用の変数
objsend 0,$b8,0,a,1 ; 変更をチェック
if stat==1 : dialog "内容が変更されています"
end
03.ボタンに書かれた文字の変更
ボタン上の文字(キャプション)は必ず文字列で指定し、変数で指定してやることが出来ません。
ですが「objprm」命令を使えばいくらでも変更が出来ます。
(例)ユーザーに好きなボタン名をつけてもらう(01のオブジェクト監視を使用しています)
caption=""
objsize 150,25 ; オブジェクトのサイズを150*25にする
pos 10,10 : button "",exit
pos 10,50 : input caption,200,25,63
*main
caption2=caption
objsel 1 ; inputboxにフォーカスを合わせる
repeat
wait 1
if caption!=caption2 : break ; 項目が変更されたらループから抜ける
loop
objprm 0,caption ; ボタンの文字を指定した文字に変更
goto *main
*exit
end
04.自分で描いた画像をボタンにする(簡易版)
メインのループでマウスのクリックとマウスカーソル位置を取得して、
クリックした位置がボタン上かどうかを監視することによって擬似的にボタンに見せることが可能です。
04は1つのボタン画像(変化しない)とクリックと位置を調べるだけの方法です。
(例)簡易ボタン サンプルボタンダウンロードしてから行ってください
bx=200 ; ボタンのXサイズ
by=32 ; ボタンのYサイズ
buffer 2 ; 仮想スクリーンID2
picload "button.jpg" ; ボタン画像をロード(この時点ではまだボタンは見えない)
gsel 0 ; 描画先をスクリーンID0にする
pos 200,100 : gcopy 2,0,0,bx,by ; 凸ボタン部分のみ表示
*main
repeat
stick key,256 ; 左クリックを監視する
mx=mousex ; マウスのX座標
my=mousey ; マウスのY座標
if key&256{
if (mx>200)&(mx<(200+bx))&(my>100)&(my<(100+by)) : break ; ボタン上でクリックしたらループ抜ける
}
wait 1
loop
; 実際使用する場合はココに処理を書く
end
05.自分で描いた画像をボタンにする
今回はボタン上でクリックしたら凹ボタンを同じ位置に配置し、ボタンを離すまで凹ボタンを保たせて、
離したら再び凸ボタンを配置して処理を行わせるという本物のボタンに限りなく近くしました。
(例)リアル(?)ボタン サンプルボタンダウンロード(04と同じです)してから行ってください
bx=200 ; ボタンのXサイズ
by=32 ; ボタンのYサイズ
buffer 2 ; 仮想スクリーンID2
picload "button.jpg" ; ボタン画像をロード(この時点ではまだボタンは見えない)
gsel 0 ; 描画先をスクリーンID0にする
pos 200,100 : gcopy 2,0,0,bx,by ; 凸ボタン部分のみ表示
*main
repeat
stick key,256 ;左クリックを監視する
mx=mousex ; マウスのX座標
my=mousey ; マウスのY座標
if key&256{
if (mx>200)&(mx<(200+bx))&(my>100)&(my<(100+by)) : break ; ボタン上でクリックしたらループ抜ける
}
wait 1
loop
*button_down ;ボタンを押し続けている状態の処理
pos 200,100 : gcopy 2,0,by,bx,by ; ボタン凹画像部分だけ先ほどの場所に描画
repeat
stick key,256
if key!=256 : break ; マウスのボタンを離したらループ抜ける
wait 1
loop
*button_up ;ボタンを離したときの処理
pos 200,100 : gcopy 2,0,0,bx,by ; 凸ボタン部分のみ表示
; 実際使用する場合はココに処理を書く
end
06.パスワードボックスを作成
input内の数値を人に見られないパスワード用のボックス(***の様な)に変更します。
これもobjsendで実現します。書式は「objsend オブジェクトID,$cc,'使いたいキャラクタ',0,0」
使いたいキャラクタ(*,+,?,!等)は好きな物を選んでください。
02でも説明したたようにp4には直接値を指定出来ないので0の入った変数で指定します。詳しい説明はコチラ。
(例)パスワードボックスの作成
screen 0,250,35,0
pass="" ; パスワードを入れる変数
a=0 ; p4用の変数
pos 5,5 : input pass,170,25,20
pos 180,5 : button "OK",*ok
objsend 0,$cc,'*',a,0 ; パスワードボックスに変更
stop
*ok
if pass=="sample" : end ; 入力内容が「sample」なら終了
dialog "パスワードが違います",1,"エラー"
stop
07.ラジオボタン・3ステートチェックボックスを作成
ラジオボタンとは複数ある項目の中からひとつだけ選択できるオブジェクト。
3ステートチェックボックスは3段階(チェック,灰色表示,なし)のチェックボックスです。
コレもまたobjsendを使用しボタンをそれぞれのオブジェクトに変形させます。
グループボックスも作成できますがそのまま使うとバグった形になるようです・・・。
02でも説明したたようにp4には直接値を指定出来ないので0の入った変数で指定します。詳しい説明はコチラ。
objsize 200,25
button "選択項目1",*radio1
button "選択項目2",*radio2
button "選択項目3",*radio3
button "3ステート",*tchk
button "選択項目チェック",*select
objsend 0,$f4,$09,b,1 ; ラジオボタンに変更
objsend 1,$f4,$09,b,1 ; ラジオボタンに変更
objsend 2,$f4,$09,b,1 ; ラジオボタンに変更
objsend 3,$f4,$06,b,1 ; 3ステートチェックボタンに変更
stop
07を見た方はお分かりでしょうが、ラジオボタンのジャンプ先を一つ一つ書いていくのは面倒ですね。
同じ処理で数値だけが違う時は一つにまとめることができるものもあります。
ボタンは押されるとstatにオブジェクトIDを返します。コレを利用しましょう。
(例)押されたボタンを削除する
objsize 30,30
repeat 5 ; 縦に5個×横に5個ボタンを配置
repeat 5
pos x,y : button "",*click ; ボタンのジャンプ先はすべて*click
x+=30
loop
x=0
y+=30
loop
stop
*click
clrobj stat,stat ; クリックされたボタンのみ削除
stop
listbox,comboxを選択すると数値が返ってきます。
でも「取得したいのは項目の文字列なんだ 」と言う場合は、p3の内容を示す文字列の部分を変数で指定してやり、
その変数を文字列操作命令で取りだしましょう。
(例)押されたボタンを削除する
objsize 200,25
list="ハードディスク\nメモリ\nCPU\nフロッピー\nCD−ROM"
listbox index,150,list
button "選択項目チェック",*chk
stop
*chk
notesel list
noteget name,index
dialog "「"+name+"」が選択されています"
stop
10.エディットコントロールのカーソル位置を記憶
新しくmesboxを作り直したり、objprmで更新するとカーソルの位置はトップに戻ってしまいます。
コレは更新前に現在のカーソル位置を記憶し、更新後にカーソルを元の位置に戻してやることで回避できます。
カーソル位置を取得するのは「objsend オブジェクトID,$b0,0,取得位置を入れる変数,0」で、
カーソル位置を動かす方法は「objsend オブジェクトID,$b1,開始位置,終了位置,0」です。
開始位置と終了位置が違う場合、その間の部分が選択(反転)されます。
しかしカーソル位置に自動でスクロールしてくれないので、変更してやる必要があります。
画面内にカーソルが来るようにスクロールするのは「objsend オブジェクトID,$b7,0,0の入った変数,1」です。
02でも説明したたようにp4には直接値を指定出来ないので0の入った変数で指定します。詳しい説明はコチラ。
(例)無理矢理mesboxを更新
objsize 640,25
sdim buf,64000
pos 0,25 : mesbox buf,640,455,5
pos 0, 0 : button"リフレッシュ",*reflesh
stop
*reflesh
a=0
objsend 0,$b0,0,a,0 ; カーソル位置取得
linenow=a
objprm 0,buf
objsel 0
a=0
objsend 0,$b1,linenow,linenow,1; カーソル位置を戻す
objsend 0,$b7,0,a,1 ; 画面内にカーソルが来るようにスクロール
stop
11.エディットコントロールのカーソル位置を記憶(応用)
pos 160, 0 : button"カーソル位置記憶",*cur
pos 320, 0 : button"戻る",*back
pos 480, 0 : button"進む",*next
stop
*load
dialog "txt",16 ; txt形式を開く
if stat==0 : stop ; キャンセルかエラーが出たらストップ
bload refstr,buf ; 変数にロード
objprm 0,buf
stop
*cur
now=0
objsend 0,$b0,0,now,0 ; カーソル位置取得
repeat 9
b=8-cnt
c=b+1
history.c=history.b ; 1つずつ履歴を移動させる(一番古い履歴は破棄される)
loop
history.0=now ; 今回記憶した位置を入れる
objsel 0 ; mesboxにカーソル戻す
stop
*back
if hist==9 : stop ; 10以上戻れなくする
hist++
goto *move
*next
if hist==0 : stop ; 0以下はないのでとめる
hist--
goto *move ; このすぐ下なのでなくてもよい
*move
a=0
objsend 0,$b1,history.hist,history.hist,1 ; カーソル位置を戻す
objsend 0,$b7,0,a,1 ; 画面内にカーソルが来るようにスクロール
objsel 0
stop
12.mesboxの指定したバイト数で強制的に折り返す
mesboxのp4(スタイル)を5(横スクロール可)から1(横スクロール不可)にすれば見た目上折り返しますが、
一番右端できれいに折り返してくれず、最後の方で折り返すといった感じになることがほとんどです。
ここは見た目だけでなく指定バイトごとに改行コードを入れて実際に折り返してみましょう。
(例)20バイトごとに改行コードを挿入し強制的に改行させる(sprocketさん提供)
sdim buf,32000
sdim buf2,32000
dialog "txt",16
if stat==0 : end
bload refstr,buf
mesbox buf,640,480,1
llen=0 ; 現在の行の長さ
c=0 ; 現在のバイト数
repeat
peek a,buf,c ; 変数bufのc番目の文字を見る
llen++ ; 現在の行の長さを+1する
if a=0 : break ; 文字列データが終わった場合
if a=13 {
llen=0
c+=2
continue ; 改行コードがあった場合
}
if llen>=20 { ; ここの数値の大きさで改行するバイト数を指定
if (a<=159)|(a>=224)&(a>=129)&(a<=252)=0 : c++ ; 全角文字をちぎって改行しないようにする
buf2=buf
memcpy buf,buf2,32000-c,c+2,c
wpoke buf,c,$0a0d ; 改行コードを挿入
continue
}
if (a<=159)|(a>=224)&(a>=129)&(a<=252) { ; 全角文字の場合
llen++
c+=2
continue ; 2バイト目はpeekをスキップ
}
c++
loop
objprm 0,buf
stop
13.TABキーでオブジェクトフォーカスを変更
大概のソフトはTABキーでフォーカスを移動できますね。
別にTABキーではなくてALTキーやSHIFTキーでもよいのですが・・・。
HSPでやるにはTABキーを監視するのとフォーカス移動(objsel)で実現できます。
HSP2.6からobjmode命令を使用してTAB移動できるようになりましたので
2.55以前を使い続ける人以外には無用のものとなりました。
(例)TAB移動を可能にする
pass="input password"
list="data1\ndata2"
input pass,200,25,64
combox com,50,list
chkbox "check",chk
button "EXIT",exit
objsel 0 ; とりあえずID0を選択しておく
repeat
stick key
if key&1024 { ; 1024がtabキーのこと
if sel==3 : sel=0 : else : sel++
objsel sel
}
wait 1
loop
*exit
end
14.エディットコントロールを読取専用にする
mesboxはp4(スタイル)の変更で読取専用(編集不可)にできるのですが、inputはできませんね。
またmesbox配置後に読取専用にすると言ったことまではできません。
しかしコレもobjsendで実現できます。書式は「objsend オブジェクトID,$cf,1,0,1」です。
またp3の1を0に変更すると編集可能モードになります。
02でも説明したたようにp4には直接値を指定出来ないので0の入った変数で指定します。詳しい説明はコチラ。
(例)「その他」を選んだときのみinputを編集可能にする
sonota=""
a=0 ; objsendのp4用の変数
objsize 150,25
pos 50,10 : button"項目1",*radio
pos 50,50 : button"項目2",*radio
pos 50,90 : button"その他",*radio
pos 250,90 : input sonota,200,25,20
objsend 0,$f4,$09,b,1 ; ラジオボタンに変更(TIPSの07参照)
objsend 1,$f4,$09,b,1 ; ラジオボタンに変更(TIPSの07参照)
objsend 2,$f4,$09,b,1 ; ラジオボタンに変更(TIPSの07参照)
objsend 3,$cf,1,a,1 ; inputを編集不可にする
stop
*radio
if stat==2 : objsend 3,$cf,0,a,1 : else : objsend 3,$cf,1,a,1
stop
リストの内容を示す文字列を変数で指定して文字列操作命令で追加させる方法と、
objsendで追加する方法があります。お好きな方を使用してください。
(例)データを追加する
sdim list,256
list="テレビ\n冷蔵庫\nエアコン\nレンジ"
data=""
objsize 200,25
pos 10,10 : listbox index,100,list
pos 10,150 : input data,200,25,20
objsize 100,25
pos 250,150 : button "追加する",*add
stop
*add
if index==10 : stop ; 項目数が合計10まで追加可能にする
notesel list
noteadd data ; 最終行に追加
objprm 0,list ; 更新させないと反映されません
stop
objsendの場合は先程の様にsdimでサイズを確保する必要はありません。
項目に追加するには「objsend オブジェクトID,$181,追加する位置,追加する項目,0」です。
最後の行に追加させるには現在の項目数を調べれば追加する位置を決められますね。
項目数を調べるには「objsend オブジェクトID,$18b,0,0,1」でstatに項目数が返ってきます。
02でも説明したたようにp4には直接値を指定出来ないので0の入った変数で指定します。詳しい説明はコチラ。
(例)データを追加する(objsend版)
data=""
a=0
objsize 200,25
pos 10,10 : listbox index,100,"テレビ\n冷蔵庫\nエアコン\nレンジ"
pos 10,150 : input data,200,25,20
objsize 100,25
pos 250,150 : button "追加する",*add
stop
*add
if index==10 : stop ; 項目数が合計10まで追加可能にする
objsend 0,$18B,0,a,1 ; 現在の項目数を調べる
objsend 0,$181,stat,data,0 ; 最後の行に項目を追加する
stop
15とは逆に項目を削除します。
リストの内容を示す文字列を変数で指定して文字列操作命令で削除する方法と、
objsendで削除する方法があります。お好きな方を使用してください。
(例)データを削除する
sdim list,256
list="テレビ\n冷蔵庫\nエアコン\nレンジ"
objsize 200,25
pos 10,10 : listbox index,100,list
objsize 100,25
pos 100,150 : button "削除する",*del
pos 250,150 : button "全削除する",*all
stop
*del
notesel list
notedel index ; 現在の選択項目削除
objprm 0,list ; 更新させないと反映されません
stop
*all
list=""
objprm 0,list
stop
objsendの場合削除するには「objsend オブジェクトID,$182,削除する項目,0,1」です。
全削除は「objsend オブジェクトID,$184,0,0,1」で出来ます。
02でも説明したたようにp4には直接値を指定出来ないので0の入った変数で指定します。詳しい説明はコチラ。
(例)データを削除する(objsend版)
data=""
a=0
objsize 200,25
pos 10,10 : listbox index,100,"テレビ\n冷蔵庫\nエアコン\nレンジ"
pos 10,150 : input data,200,25,20
objsize 100,25
pos 100,150 : button "削除する",*del
pos 250,150 : button "全削除する",*all
stop
*del
objsend 0,$182,index,a,1
stop
*all
objsend 0,$184,0,a,1
stop
17.オブジェクト配置にこだわる
オブジェクトをただポンと置くだけではつまらない。
そんなヒトにはオブジェクトに演出させましょう。(大した物ではないので気休め程度のTIPSとお考えください)
(例)配置に工夫する
sdim caption,20,6
caption="( ̄∇ ̄)","Σ(゚Д゚|||)","ε=┌( >.<)┘"," ε=ε=┌( >.<)┘"," ε= ε= ε=┌( >.<)┘","完"
objsize 150,30
repeat 50; 左から右へボタンを移動
clrobj 0
x=cnt*13
pos x,100 : button "ヽ( ´ー`)ノ",*exit
wait 1
loop
repeat 30; 段々とボタンを拡大
clrobj 0
x=cnt*5
y=cnt
objsize x,y
pos 100,100 : button "(´-`)y-~~ ",*exit
wait 1
loop
repeat 30; ボタンを縮小していく
clrobj 0
x=145-(cnt*5)
objsize x,30
pos cnt*5+100,100 : button "(´-`)y-~~ ",*exit
wait 1
loop
clrobj 0
objsize 150,30
pos 250,200 : button"顔文字劇場",*exit
repeat 6 ; ボタンの文字を次々と変えて行く
wait 100
objprm 0,caption.cnt
loop
stop
*exit
end
18.オブジェクトを灰色表示(利用不可)にする (要llmod.as)
14でエディットコントロールを読取専用(利用不可)にしましたが、
llmodを使えば、すべてのオブジェクトの利用を禁止にすることが出来ます。
(例)ボタンを押すと1秒間使用不可にする
#include"llmod.as"
pos 0,0 : button"テスト",*enabled
stop
*enabled
mref nwin,67 ; 現在のウィンドウ情報(BMSCR構造体)
param=nwin.41,0 ; オブジェクトIDが0なら41、1なら42。2つ目の数値はモード。0で利用不可、1で利用可能
dllproc "EnableWindow",param,2,1 ; (最後の1は「D_USER」でもよい)
wait 100
param=nwin.41,1
dllproc "EnableWindow",param,2,1
stop
19.アップダウンコントロールを作ってみる
表示ボックスのすぐ隣に上下を押すボタンがついていて、押すと表示ボックスの値が
増減するオブジェクトはllmod.as等を使用すればできますが、標準命令だけでも
擬似アップダウンコントロールは作成することができます。
(例)擬似アップダウンコントロール作成
pos 100,50 : input box,60,26
objsize 20,13
font "",8
objmode 2
pos 160,50 : button "▲",up
pos 160,63 : button "▼",down
stop
*up ; 上向き矢印
box+
if box>100: box=100 ; 最大値を超えたら最大値でストップ
objprm 0,box
stop
*down ; 下向き矢印
box-
if box<0 : box=0 ; 最小値を下回ったら最小値でストップ
objprm 0,box
stop
20.アップダウンコントロール作成 〜上級編〜
19でアップダウンコントロールを作成してみましたがオブジェクト3つも使用しなければ作成できませんでした。
takutoさんがmesboxの縦の長さを縮めるとアップダウンコントロールっぽくなるという話を元に作成してみました。
mesboxだけですのでオブジェクト1つでできるというところがポイントでしょうか。
(例)擬似アップダウンコントロール作成
title "秘技アップダウンコントロール"
a=0
sdim buf,100
buf="1000\n500\n300\n200\n100\n50\n40\n30\n20\n15\n10\n 9\n 8\n 7\n 6\n 5\n 4\n 3\n 2\n 1\n 0"
objsize 60,25
mesbox buf,60,25,0
button "OK",ok
stop
*ok
objsend 0,$ce,0,a,1 ; 現在表示している行を取得
notesel buf
noteget count,stat
dialog"現在 : "+count
stop
21.選択テキスト取得
llmod.asにselget命令というものがあります。それを標準命令だけで実現しようという企画です(^^;
エディットボックスの現在選択(反転表示)しているテキストが何なのかをobjsendを使用して取得できます。
現在のキャレット位置を取得する「objsend ID,$b0,0,ichi,0」で数値型変数ichiにキャレット位置が入ります。
選択している場合はichiに選択しているテキストの終点が入ります。
選択しているテキストの始点は「stat & $ffff」で取得することができます。
(例)文字を数える
buf="abcdefghijklmnopqrstuvwxyz\n0123456789\nあいうえお"
mesbox buf,640,460,1
objsize 640,20
button "選択テキスト取得",catch
tmp=15
objsend 0,$b1,10,tmp,1 ; とりあえずテキストを選択しておく
stop
*catch
tmp=0
objsend 0,$b0,tmp,tmp,0 ; 現在のキャレット位置取得
start=stat & $ffff ; 選択テキストの始点
length=tmp-start ; 選択テキストの文字数計算
strmid catchtext,buf,start,length
dialog ""+catchtext,,"選択しているテキスト"
stop
22.mesbox内の一行を選択するモジュール
「llmod.as」にmesbox内の一行を選択するlinesel命令というものがあります。
でもまぁ標準命令だけでもできないことはないのでobjsendを使ってモジュールとしてみました。
mesbox内の1行を選択する「objsend ID,$c4,行,バッファアドレス,0」というものを使用しています。
(例)mesbox内の一行選択
;************ 概要説明 **********************
;
; selline n1,n2
;
; n1 : mesboxのID
; n2 : 選択する行
;
; 取得した文字列はシステム変数refstrに入ります
;
;********************************************
#module "select"
#deffunc selline int,int
mref result,65
mref sel,0
mref l,1
sdim tmp,256
tmp=" "
objsend sel,$c4,l,tmp,0
result=tmp ; 直接入れても返す事ができないので間接的に代入
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
sdim buf,1024
buf="1234567890\nabcdefghijklmnopqrstuvwxyz\nあいうえお\nかきくけこ\nわ・を・ん"
objsize 540,25
mesbox buf,640,455,5
pos 0,455 : input num,100
pos 100,455 : button "取得",*lineselect
stop
*lineselect
selline 0,num
dialog""+refstr
stop
23.listbox選択項目上下入れ替え
本家掲示板で質問のあったものです。選択項目の上下を入れ替えると選択位置が-1になってしまいます。
(例)選択項目入れ替え
sdim list,128
list="1234567890\nabcdefg\nhijklmn\nopqrstu\nvwxyz"
objsize 200,25
pos 0,0 : listbox index,200,list
button "↑",up
button "↓",down
stop
*up
notesel list
noteget tmp,index
num=index-1
if num<0 : stop
noteadd tmp,num
notedel index+1
clrobj 0,0
index=num
pos 0,0 : listbox index,200,list
stop
*down
notesel list
noteget tmp,index
notemax max
num=index+1
if num=max : stop
if num+2>max : list+="\n" : flg=1
noteadd tmp,num+1
notedel index
if flg : notedel max : flg=0
clrobj 0,0
index=num
pos 0,0 : listbox index,200,list
stop
24.自前のトラックボックスの作成
自分で配色や動かす向き等を自由設定できるトラックボックスを擬似的に作成してみましょう。
(例)トラックボックス作成
buffer 2
color 220,180,180 : boxf : color
line -1,0,24,0
line 0,-1,0,199
line -1,199,24,199
line 24,-1,24,199
line 12,9,12,190
repeat 10
line 5,cnt*20+10,19,cnt*20+10
loop
color 230,200,200 : boxf 25,0,45,10 : color 255,230,230
line 24,0,45,0
line 25,-1,25,10
color
line 24,10,45,10
line 45,-1,45,10
gsel 0
color 255,240,240 : boxf
*main
redraw 0
pos 100,100 : gcopy 2,0,0,25,200
pos 102,ichi*20+105 : gcopy 2,25,0,21,11
redraw
stick key,256,1
if key&256 {
mx=mousex
my=mousey
repeat 10
if mx>101&(mx<124)&(my>(cnt*20+94))&(my<(cnt*20+116)) : ichi=cnt : break
loop
}
wait 1
goto *main
25.クリップボード履歴をオブジェクトに入れていく (要hspext.dll)
質問があったので作成したものですが、クリップボードに入っている文字列をメインループで監視し
変更されたら履歴を取って行く様にしただけですがクリップボード履歴ソフト(?)の完成です。
(例)10回分の履歴を保存しておけるクリップボード履歴ソフト
#include "hspext.as"
#define histnum 20 ; クリップボードの履歴数
gsel 0,2
title "クリップボード履歴"
sdim history,3200,histnum
sdim check,3200
height=winy/histnum ; 全オブジェクトの高さがウィンドウ内に収まるサイズにする
font "MS ゴシック",height-6 ; フォントもオブジェクトサイズが変わってもいける様にする
objmode 2
repeat histnum
pos 0,cnt*height : mesbox history.cnt,640,height
loop
*main
repeat
clipget check,3200
if check!=history : break
wait 1
loop
repeat histnum-1 ; 1つずつ移動
before=histnum-2-cnt
after=histnum-1-cnt
history.after=history.before
loop
clipget history,3200
repeat histnum
objprm cnt,history.cnt
loop
objsel 0
goto *main
26.オブジェクト内の文字列の検索
エディターを作る時に必要になってくる方法でしょう。
エディットコントロール内の文字列であるならばobjsendを使って比較的簡単にできます。
書式は「objsend オブジェクトID,$b1,検索文字始まりのINDEX,検索文字終わりのINDEX」です。
(例)検索文字列を反転表示させる
sdim ken,128 ; 検索したい文字列を入れる変数
sdim buf,32000 ; 検索先の変数
buf="abcdefghijk\nabcdefg123hijk3210\nbca123321xzyx\nabcdefxyz" ; 検索先の内容
pos 0, 0 : input ken,250,25,128
pos 250, 0 : button"検索",*start
pos 0,25 : mesbox buf,640,455,1
stop
*start
objsel 2 ; 検索先のオブジェクトを選択しておく
instr ichi,buf,ken,0 ; ichiに検索する文字列の始まりのINDEXが入る(ない場合-1が入る)
if ichi<0 : dialog "検索文字「"+ken+"」は見つかりませんでした" : stop
strlen len,ken ; 検索する文字列の文字数をlenに代入
ichiend=len+ichi ; ichiend検索する文字列の終わりのINDEXが入る
objsend 2,$b1,ichi,ichiend,1 ; 反転表示
stop
27.オブジェクト内の文字列の置換・挿入
途中までは26の検索と同じやり方です。
検索と同じように置換したい文字列を選択状態にし(反転表示)その部分を入れ替えてやります。
置換の方法は「objsend オブジェクトID,$c2,0,置換文字,0」です。
事前に選択(反転表示)していない場合は現在のカーソル位置に挿入されます。
(例)先ほどのソースを拡張して置換する(「検索」に変更元文字列、「置換」に変更後の文字列を入れる)
sdim ken,128 ; 検索したい文字列を入れる変数
sdim ckn,128 ; 置換したい文字列を入れる変数
sdim buf,32000 ; 検索先の変数
buf="abcdefghijk\nabcdefg123hijk3210\nbca123321xzyx\nabcdefxyz" ; 検索先の内容
objsize 70,25
pos 0, 0 : input ken,250,25,128
pos 250, 0 : button "検索",*start
pos 320, 0 : input ckn,250,25,128
pos 570, 0 : button "置換",*change
pos 0,25 : mesbox buf,640,455,1
stop
*start
objsel 4 ; 検索先のオブジェクトを選択しておく
instr ichi,buf,ken,0 ; ichiに検索する文字列の始まりのINDEXが入る(ない場合-1が入る)
if ichi<0 : dialog "検索文字「"+ken+"」は見つかりませんでした" : stop
strlen len,ken ; 検索する文字列の文字数をlenに代入
ichiend=len+ichi ; ichiend検索する文字列の終わりのINDEXが入る
objsend 4,$b1,ichi,ichiend,1 ; 反転表示
stop
*change
objsel 4
instr ichi,buf,ken,0
if ichi<0 : dialog "検索文字「"+ken+"」は見つかりませんでした" : stop
strlen len,ken
ichiend=len+ichi
objsend 4,$b1,ichi,ichiend,1
objsend 4,$c2,0,ckn,0 ; 検索との違いはこの行だけ
stop
28.DLLを使わずにクリップボードを操作する
標準命令のobjsendでクリップボードに文字列を送る・文字列の取得が可能です。
文字列をカットしてクリップボードに送る 「objsend オブジェクトID,$300,0,0,1」
文字列をコピーしてクリップボードに送る「objsend オブジェクトID,$301,0,0,1」
クリップボードから文字列を取得・貼付 「objsend オブジェクトID,$302,0,0,1」です。
ただし、パラメータ4のlParamには直接数値を入れることができない為、変数で指定します。詳しい説明はコチラ。
(例)クリップボードを操作する
objsize 160,25
sdim buf,32000
pos 0,25:mesbox buf,640,455,1
pos 0,0 : button"読み込み",*load
pos 160,0 : button"コピー",*copy
pos 320,0 : button"切り取り",cut
pos 480,0 : button"貼り付け",past
stop
*load
dialog"txt",16
if stat==0 : stop
bload refstr,buf
objprm 0,buf
stop
*copy
a=0 : objsend 0,$301,0,a,1 ; コピー
objsel 0
stop
*cut
a=0 : objsend 0,$300,0,a,1 ; 切り取り
objsel 0
stop
*past
a=0 : objsend 0,$302,0,a,1 ; 貼り付け
objsel 0
stop
29.キャレットの点滅速度取得・設定モジュール (要llmod.as)
エディットボックスの現在位置を示すキャレットの点滅速度を取得・設定するモジュールです。
このモジュールを使用するとHSPだけでなくのすべてのエディットボックスが変更されます。
変更前の速度を取るようにしてHSPウィンドウが終了する時に戻すようにしておいた方が安全です。
(例)点滅速度を変更する
#include "llmod.as"
;********************** 概要説明 **********************
;
; getblink v1
;
; v1=数値型変数 : 点滅時間取得
;
;
; setblink v1
;
; v1=数値型変数 : 点滅時間設定
;
;*****************************************************
#module "object"
#deffunc getblink val
mref gets,16
dllproc "GetCaretBlinkTime",gets,1,D_USER@
gets=dllret@
return
#deffunc setblink val
mref sets,16
mref stt,64
dllproc "SetCaretBlinkTime",sets,1,D_USER@
if dllret@=0 : stt=1 : else : stt=0
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
font "",25
getblink speed
input speed,350,25
button "変更",change
stop
*change
setblink speed
if stat : mes "設定に失敗しました"
stop
30.コンボボックスを自動で開く
あまり用途がないかもしれませんがコンボボックスにメッセージを送り、
自動でコンボボックスを開かさせてみたいと思います。
SendmessageでCB_SHOWDROPDOWN(0x14F)を送ってやることで開かせられるようです。
HSPではobjsend命令でWin32メッセージの所に$14fをしてやるだけでOKです。
(例)コンボボックスを自動開閉
buf="アイテム1\nアイテム2\nアイテム3\nアイテム4\nアイテム5"
objsize 100,25
pos 100,50 : combox index,100,buf
pos 220,50 : button "開閉",open
stop
*open
objsend 0,$14f,1,zero,0 ; p3に1を入れると開く
wait 100
objsend 0,$14f,0,zero,0 ; p3に0を入れると閉じる
stop
31.配置オブジェクトの位置をD&Dで自由に動かす
以前掲示板であった質問で、オブジェクトを好きな位置に再配置したい、ということで作ってみたものです。
ENTERキーを押すと、現在フォーカスのあっているオブジェクトがクリアされ代わりに疑似オブジェクトが同じ位置に配置されます。
その疑似オブジェクト上でドラッグすることでマウスに従って疑似オブジェクトが移動します。
任意の位置でドロップすると疑似オブジェクトだったものが元のオブジェクトに戻ります。
(例)オブジェクト移動
#define number 3 ; オブジェクト数
sdim string,32,number
dim sizex,1 : dim sizey,1 ; オブジェクトサイズ
dim posx,number : dim posy,number ; 各オブジェクトの位置
dim flg,number ; 現在各入力エリアはオブジェクトを表示しているか
dim mx,1 : dim my,1 ; D&D用マウス位置
dim occup,1 ; 同時にオブジェクトが移動しないようにする為のトラップ
repeat number : posy.cnt=25*cnt : loop
occup=-1 ; アクティブオブジェクト
sizex=100 : sizey=25
repeat number
pos posx.cnt,posy.cnt : input string.cnt,sizex,sizey ; 各オブジェクトを配置する
loop
buffer 2,sizex,sizey*number ; オブジェクト移動用の一時バッファ
gsel 0
onkey *enter
*main
mx=mousex : my=mousey
wait 3
stick key,256
if key&256 {
if occup<0 : occup=0
repeat number,occup
if posx.cnt<mx&(posy.cnt<my)&(posx.cnt+sizex>mx)&(posy.cnt+sizey>my)&(flg.cnt=1) {
posx.cnt=posx.cnt+mousex-mx
posy.cnt=posy.cnt+mousey-my
occup=cnt ; 現オブジェクトが移動権を得る
break
}
loop
} else {
if occup>-1 : if flg.occup=1 : flg.occup=0 : pos posx.occup,posy.occup : input string.occup,sizex,sizey
occup=-1 ; 占有解除
}
redraw 0
color 255,255,255 : boxf
repeat number
if flg.cnt : pos posx.cnt,posy.cnt : gcopy 2,0,sizey*cnt,sizex,sizey
loop
redraw
goto *main
*enter
if wparam != 13 : goto *main
objsel -1
if stat=-1 : goto *main
gsel 2
color : boxf 0,sizey*stat,sizex-1,sizey*stat+sizey-1
color 255,255,255 : boxf 1,sizey*stat+1,sizex-2,sizey*stat+sizey-2
color
pos 0,sizey*stat+3 : mes string.stat
flg.stat=1
gsel 0
clrobj stat,stat
goto *main
32.配置オブジェクトのサイズをD&Dで自由に変更する
31と同時に質問されたもので作ってみたものです。
連携させれば自在に移動・サイズ変更のできるオブジェクトが配置できますよ。
使い方はほとんど同じで、サイズ変更したいオブジェクトにフォーカスを合わせてオブジェクトを疑似オブジェクトにします。
後は疑似オブジェクト上で右クリックのドラッグアンドドロップで伸縮させることが出来ます。
(例)オブジェクトサイズを変更する
#define number 3
sdim string,32,number
dim size,number ; オブジェクトサイズ
dim flg,number
dim mx,1 : dim my,1
dim occup,1
dim limit,1 ; オブジェクトサイズの限界
repeat number : size.cnt=100 : loop
occup=-1
limit=400
repeat number
pos 0,cnt*25 : input string.cnt,size.cnt,25
loop
buffer 2,limit,25*number
gsel 0
onkey *enter
*main
mx=mousex : my=mousey
wait 1
stick key,512
if key&512 { ; オブジェクトサイズ変更
repeat number
if 0
size.cnt=size.cnt+mousex-mx
if size.cnt>limit : size.cnt=limit ; リミッター
mref stt,64
stt=cnt ; statに代入
occup=cnt ; 現オブジェクトが移動権を得る
gosub *dummy
break
}
loop
} else {
if occup>-1 : if flg.occup=1 : flg.occup=0 : pos 0,occup*25 : input string.occup,size.occup,25
occup=-1
}
redraw 0
color 255,255,255 : boxf
repeat number
if flg.cnt : pos 0,cnt*25 : gcopy 2,0,cnt*25,size.cnt,25
loop
redraw
goto *main
*enter
if wparam != 13 : goto *main
objsel -1
if stat=-1 : goto *main
*dummy
gsel 2
color : boxf 0,25*stat,size.stat-1,25*stat+25-1
color 255,255,255 : boxf 1,25*stat+1,size.stat-2,25*stat+23
color
pos 3,25*stat+3 : mes string.stat
flg.stat=1
gsel 0
if key&512 : return
clrobj stat,stat
goto *main
33.65個以上のオブジェクトを扱う
HSPは標準で1つのウィンドウに64個までしかオブジェクトを配置できません。
ちょっとした入力・選択に使用するだけであれば十分に事足りるのですが、
エクセルの表のように使いたいと大量に配置する場合は配置できないことはないのですが、
配置させて値を取得しようとしてもオブジェクトに値が入っていません。
表示だけに使うのであればコレでもいいでしょうが、中の値を使って何かさせることができないのです。
そういったときに31,32の疑似オブジェクトを使えばごまかせますね。
(例)表を作ってみる
#define wx 640
#define wy 480
#define sx 80
#define sy 24
#const num wx/sx*(wy/sy) ; オブジェクト総数
width wx,wy
font "MS 明朝",14
objmode 2
sdim cell,8,num
gosub *draw
*main
stick key,,1
if key&256 : goto *click
wait 1
goto *main
*click
id=mousey/sy*(wx/sx)+(mousex/sx) ; クリックしたセルIDを取得
gosub *draw
pos id\(wx/sx)*sx,id/(wx/sx)*sy : input cell.id,sx,sy ; セルIDを元にオブジェクトを配置
objsel 0
goto *main
*draw
if id!=id.1 : id.1=id : clrobj ; 前回クリックしたセルと違う場合のみ消去
redraw 0
color 255,255,255 : boxf : color
; 枠線の描画
repeat wx/sx
line cnt*sx,-1,cnt*sx,wy
line cnt+1*sx-1,-1,cnt+1*sx-1,wy
loop
repeat wy/sy
line -1,cnt*sy,wx,cnt*sy
line -1,cnt+1*sy-1,wx,cnt+1*sy-1
loop
; 各セルの値を表示
repeat num
pos cnt\(wx/sx)*sx+4,cnt/(wx/sx)*sy+4 : mes cell.cnt
loop
redraw
return
34.エディットボックスの行の前後を入れ替える
エディットボックス内のテキストの行単位での順番を最後に近いほど最初にします。
私としてはホームページの更新状況をプロフィールに移す時前後入れ替える必要がある等でそこそこ使用します。
まぁ上の作業はまだ2回(2年分)だけしかやってないのですけどね…。
(例)終始の入れ替え
sdim buf,3200
sdim tmp,128
notesel buf
repeat 30,1
if cnt>1 : buf+="\n"
buf+="" + cnt + "行目"
loop
objsize 640,30
mesbox buf,640,450,1
button"入れ替え",change
stop
*change
notemax max
repeat max
noteget tmp,max-1
noteadd tmp,cnt
notedel max
loop
strlen len,buf
poke buf,len-2,0 ; 最終行に付く改行を取り除く
objprm 0,buf
stop
35.llmod拡張オブジェクトIDを後から知る (要llmod.as)
llmod版拡張オブジェクトの講座をしていてふと思いました。なぜオブジェクトIDを知る方法がないのだろう、と。
いちいち取っておくのは煩わしい、面倒だという人達の為のモジュールを用意しました。
この命令は連動オブジェクトに対応した拡張オブジェクトを取得するといった使い方はできません。
X番目の拡張オブジェクトIDを知る、といったやり方だけです…。
下に書くTIPSを「HSPdir\common\llmod.as」内に追加してください。
どこに書いても言いというわけではなく、「#module "llmod"」「>#global」間に書かなくてはいけません。
こう書くことで命令が新たに使えるようになり、statにオブジェクトIDを取得することができるようになります。
(例)拡張オブジェクトIDを知る
(省略)
:
;module初め>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#module "llmod"
:
(省略)
:
#deffunc getllobjid int ; ココからllmod.asに追記
mref n1,0
mref stt,64
stt=obj_hnds.n1
return ; ココまで
:
(省略)
:
;module終わり>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#global
; ***** ここまでを追加する ここから下は別スクリプト *****
#include "llmod.as"
#include "progbox.as"
#define num 3 ; プログレスボックスの数
sdim ctrl,128
dim progid,num
; 操作プログレスボックスID
repeat num,1
if ctrl!="" : ctrl+="\n"
ctrl+=""+cnt
loop
pos 100,50 : combox index,100,ctrl
pos 200,50 : button "増加",up
; 配置
objsize 320,30
repeat num
pos 100,cnt*50+100 : progbox
progid.cnt=stat
loop
stop
*up
getllobjid index ; index番目のオブジェクトIDを取得
sel_progbox stat
progset
stop
36.変換中の文字列の長さを取得するモジュール (要llmod.as)
現在変換中のテキストサイズを取得するモジュールです。
何に使うの、という感じですが37や38と一緒にご利用ください^^;
最初に初期化しているimeinit命令は、ime.asにあるものと全く同じです。
ですので、ime.asを下記スクリプトと同時に使用する場合、imeinit命令部分を消して使用してください。
…というか、ime.as内に下記のモジュール内のimemiddlesize命令を移して使用していただければOKです。
取得したサイズはシステム変数statに入りますのでstatを参照してください。
(例)変換中テキストの長さを取得
#include "llmod.as"
;************************** 概要説明 *****************************
;
; imeinit v1,n2
;
; v1 : IME情報を代入する変数
; n2 : エディットボックスのオブジェクトID
;
;
; imemiddlesize v1
;
; v1 : imeinitに使用した変数
;
;****************************************************************
#module "imecontrol"
#deffunc imeinit val,int
mref info,16
mref objid,1
mref bmscr,67
if ime=0 : ll_libload ime,"imm32"
var=objid
_is_wnd var : if stat=0 : var=var+41 : var=bmscr.var
dllproc "ImmGetContext",var,1,ime
info=dllret@
return
#deffunc imemiddlesize val
mref himc,16
mref stt,64
dim size,1
prm.0=himc
prm.1=$8
getptr prm.2,size
prm.3=0
dllproc "ImmGetCompositionStringA",prm,4,ime
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
sdim string,128
input string,320,30
imeinit objid,0 ; 上記inputオブジェクトIDを指定する
*main
imemiddlesize objid ; imeinitのp1で指定した数値型変数を指定する
title "現在変換中の文字列の長さは"+stat+"バイトです" ; statにサイズが返る
wait 30
goto *main
37.変換中の文字列を取得するモジュール (要llmod.as)
本家掲示板で質問されたものに答えてみたものをモジュール化&バグ修正したものです。
最初に初期化しているimeinit命令は、ime.asにあるものと全く同じです。
ですので、ime.asを下記スクリプトと同時に使用する場合、imeinit命令部分を消して使用してください。
…というか、ime.as内に下記のモジュール内のimemiddle命令を移して使用していただければOKです。
また、モジュール内部で変換中テキストを代入する変数を一旦初期化するのに変数のサイズを知る必要があり、
TIPSその他編の変数情報を取得するモジュールと同等のものを使用しています。
コレは何?という方はその他編の14をご覧ください。
(例)変換中の文字列を取得する
#include "llmod.as"
;************************** 概要説明 *****************************
;
; imeinit v1,n2
;
; v1 : IME情報を代入する変数
; n2 : エディットボックスのオブジェクトID
;
;
; imemiddle v1,v2
;
; v1 : imeinitに使用した変数
; v2 : 取得したテキストを入れる変数
;
;****************************************************************
#module "imecontrol"
#deffunc imeinit val,int
mref info,16
mref objid,1
mref bmscr,67
if ime=0 : ll_libload ime,"imm32"
var=objid
_is_wnd var : if stat=0 : var=var+41 : var=bmscr.var
dllproc "ImmGetContext",var,1,ime
info=dllret@
return
#deffunc imemiddle val,val
mref himc,16
mref string,25
mref pval2,1025
if pval2.0=2 : size=pval2.2*4 : else : size=pval2.2 ; コレと1行上がその他編16と同じもの
prm.0=himc
prm.1=$8
getptr prm.2,string
prm.3=size
dllproc "ImmGetCompositionStringA",prm,4,ime
poke string,stat,0
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
sdim string,128
sdim nowstring,128
input string,320,30
imeinit objid,0 ; 上記inputオブジェクトIDを指定する
*main
imemiddle objid,nowstring
title "現在変換中の文字列:"+nowstring
wait 30
goto *main
38.変換中の文字列を取り消すモジュール (要llmod.as)
現在変換中の文字列を取り消します。
つまり、全角文字が押された時の未確定表示をなくすことが出来るわけです。
入力可能なエディットボックスがないような時、例えばタイピングソフト等のゲーム画面を表示中に、
直接入力ではない変換可能状態の文字が画面に表示されるのは嫌ですね?
そういうのを防ぐのに結構重宝できると思いますよ。
ただ、まぁ…imeinit命令を使用するためにはエディットボックスを指定しなければなりませんので、
どこか見えないところにエディットボックスを配置しておかなければならないというのが面倒です^^;
最初に初期化しているimeinit命令は、ime.asにあるものと全く同じです。
ですので、ime.asを下記スクリプトと同時に使用する場合、imeinit命令部分を消して使用してください。
…というか、ime.as内に下記のモジュール内のimemiddle命令を移して使用していただければOKです。
(例)半角文字しか入力させられなくする
#include "llmod.as"
;************************** 概要説明 *****************************
;
; imeinit v1,n2
;
; v1 : IME情報を代入する変数
; n2 : エディットボックスのオブジェクトID
;
;
; imeclose v1
;
; v1 : imeinitに使用した変数
;
;****************************************************************
#module "imecontrol"
#deffunc imeinit val,int
mref info,16
mref objid,1
mref bmscr,67
if ime=0 : ll_libload ime,"imm32"
var=objid
_is_wnd var : if stat=0 : var=var+41 : var=bmscr.var
dllproc "ImmGetContext",var,1,ime
info=dllret@
return
#deffunc imeclose val
mref himc,16
prm=himc,$15,$4,0
dllproc "ImmNotifyIME",prm,4,ime
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
sdim string,128
mesbox string,640,480,5
imeinit objid,0 ; 上記inputオブジェクトIDを指定する
*main
imeclose objid ; 全角文字の入力を禁じる(ただしこれだけだとコピーで入っちゃう...)
await 1
goto *main
39.変換中の文字列の読みを取得するモジュール (要llmod.as)
現在変換中の読みを取得します。
例えば、未確定テキストが「入門」だと「ニュウモン(半角カナ)」という読みが返ります。
ココでは機種により文字化けの恐れがありますので全角文字で書いていますが、実際は1バイトカナです。
最初に初期化しているimeinit命令は、ime.asにあるものと全く同じです。
ですので、ime.asを下記スクリプトと同時に使用する場合、imeinit命令部分を消して使用してください。
…というか、ime.as内に下記のモジュール内のimemiddle命令を移して使用していただければOKです。
使用はいろいろな所で出来ますね。例えば、以前の入力ワードを再度入力する時のオートコンプリートとかですね。
今回のモジュールには、38のモジュールを使っています。
(例)読みを取得する
#include "llmod.as"
;************************** 概要説明 *****************************
;
; imeinit v1,n2
;
; v1 : IME情報を代入する変数
; n2 : エディットボックスのオブジェクトID
;
;
; imeyomi v1,v2
;
; v1 : imeinitに使用した変数
; v2 : 取得した読みを入れる変数
;
;****************************************************************
#module "imecontrol"
#deffunc imeinit val,int
mref info,16
mref objid,1
mref bmscr,67
if ime=0 : ll_libload ime,"imm32"
var=objid
_is_wnd var : if stat=0 : var=var+41 : var=bmscr.var
dllproc "ImmGetContext",var,1,ime
info=dllret@
return
#deffunc imeyomi val,val
mref himc,16
mref string,25
mref pval2,1025
if pval2.0=2 : size=pval2.2*4 : else : size=pval2.2
prm.0=himc
prm.1=$1
getptr prm.2,string
prm.3=size
dllproc "ImmGetCompositionStringA",prm,4,ime
poke string,stat,0
return
#deffunc imeclose val
mref himc,16
prm=himc,$15,$4,0
dllproc "ImmNotifyIME",prm,4,ime
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
sdim ttl,256
sdim string,128
sdim nowstring,4
sdim kouho,9,7
sdim start,2,7
kouho="ドーナツ","レモン","皆","ファイト","空","ラッパ","幸せ"
start="ト","レ","ミ","フ","ソ","ラ","シ"
repeat 7
ttl+=""+start.cnt+"は["+kouho.cnt+"],"
loop
title ""+ttl+"になる"
mesbox string,640,480,5
imeinit objid,0 ; 上記inputオブジェクトIDを指定する
*main
gosub *check
wait 10
goto *main
*check
imeyomi objid,nowstring
strmid nowstring,nowstring,0,1 ; 先頭1文字を取り出す
repeat 7
if nowstring=start.cnt {
objsend 0,$c2,0,kouho.cnt,0
imeclose objid
break
}
loop
return
40.指定オブジェクト上にカーソルがあるかを取得するモジュール (要llmod.as)
他所での掲示板で返答したものです。
現在、マウスカーソル(ポインタ)が指定のオブジェクトの上に来ているか知るための命令は用意されていません。
オブジェクト上に来るとmousex,mouseyは正常に動いてくれません。
ginfo命令のスクリーン座標でのカーソル位置は常に取得可能なので、
コレと今まで他の箇所で使用したいくつかのTIPSを組み合わせて実現させましょう。
p1で指定したオブジェクトIDのオブジェクト上にカーソルが来ているとstatに1が、そうでなければ0が返ります。
(例)カーソル下のボタンテキストをタイトルバーに表示する
#include "llmod.as"
;************************** 概要説明 *****************************
;
; objoverchk n1
;
; n1 : オブジェクトID
;
;****************************************************************
#module "component"
#deffunc objoverchk int
mref objid,0
mref bmscr,67
mref stt,64
dim rect,6
dim prm,2
objid+41
getptr prm.1,rect
prm=bmscr.objid
dllproc "GetWindowRect",prm,2,D_USER@
ginfo.1
if prmx>rect&(prmx<rect.2)&(prmy>rect.1)&(prmy<rect.3) : stt=1 : else : stt=0
return
#global ; ***** ここまでがモジュール ここから下がサンプル *****
#define num 3
sdim name,12,3
name="HSPBC","ULTIMATE","SATOSHI"
objsize 200,50
repeat num
pos 150,cnt*80+50 : button name.cnt,exit
loop
repeat
flg=0
repeat num
objoverchk cnt
if stat : title "カーソルは現在「"+name.cnt+"」ボタン上にあります" : flg=1 : break
loop
if flg=0 : title ""
wait 5
loop
*exit
41.エディットボックスに数値しか入れられなくするモジュール (要llmod.as)
エディットボックスに金額等の数値のみを入れられるようにしてみましょう。
API(Windows標準の機能)で実現しているのですが、
通常の文字以外にマイナス符号であるハイフンや、桁区切りのカンマも入れられないんですねぇ。
それでもいいという人は是非ご利用ください。
(例)数値テキストのみを入れられるようにしてみる
#include "llmod.as"
#define ES_NUMBER $2000
;************************** 概要説明 *****************************
;
; numonly n1
;
; n1 : オブジェクトID
;
;****************************************************************
#module "object"
#deffunc numonly int
mref id,0
mref bmscr,67
id+41
prm=bmscr.id,-16 ; -16:現行スタイル
setwndlong prm,1 ; GetWindowLong
prm.2=stat+ES_NUMBER@ ; 新スタイル設定
setwndlong prm,0 ; SetWindowLong
return
#global
pos 300,50 : input number,100,25
numonly 0
stop
42.エディットボックスのテキスト位置を変更するモジュール (要llmod.as)
エディットボックスのテキストは通常、左揃えとなっています。
コレを「中央」や「右」の方向へずらしてみようと思います。
中央揃えはどうかと思いますが、右揃えは数値の桁揃えで需要がありそう。41と併せてご利用ください。
で、コッソリ言いますが、実は…これ、41と同じロジックなんですね。まぁ目的が違うということで別にしてみました。
ソレと補足で、モジュール内で行っているのであまり意識する必要はありませんが、
スタイル変更後にオブジェクトを更新する必要があります。
(例)ボタンキャプション位置を変更させる
#include "llmod.as"
#define ES_LEFT 0
#define ES_CENTER 1
#define ES_RIGHT 2
;************************** 概要説明 *****************************
;
; txtstyle n1,n2
;
; n1 : オブジェクトID
; n2 : 揃える位置(0:左 1:中央 2:右)
;
;****************************************************************
#module "object"
#deffunc txtstyle int,int
mref id,0
mref x,1
mref bmscr,67
dim align,3
if (x<0)|(x>2) : return
align=ES_LEFT@,ES_CENTER@,ES_RIGHT@
id+41
; スタイル変更
prm=bmscr.id,-16 ; -16:現行スタイル
setwndlong prm,1 ; GetWindowLong
prm.2=stat+align.x-rev ; 新スタイル設定
rev=align.x ; 次回実行した時に一旦戻す
setwndlong prm,0 ; SetWindowLong
; スタイル更新
objprm id-41,msg@
return
#global
objsize 80,20
pos 150,50 : mes "横"
pos 180,50 : combox yoko,100,"左\n中央\n右"
objsize 50,25
pos 300,50 : input msg,100,25
pos 400,50 : button "変更",*change
stop
*change
txtstyle 1,yoko
stop
43.ボタンに表示するテキスト位置を変更するモジュール (要llmod.as)
はい、これも42と同じロジックです^^;
分けるほどでもなかったのですが、一応は別にしておいたほうがいいかな、と。
コチラは42と違って縦位置の変更もできます。
横は「左」「中央」「右」のいずれか、縦は「上」「中央」「下」のいずれかの計9通りです。
42と同じように初めから任意の位置に表示させるのではなく表示後に、また何度も変更させるためには
キャプションを変更した後にオブジェクトを更新させる必要が出てきます。
更新自体は42と同じでobjprmで可能ですが、ボタンのキャプションが何であったかを知る必要が出てきます。
サンプルでは「スタイル変更」と決まっているのですが、何であってもOKな汎用的な作りにするため、
今まで使用していなかったキャプション取得処理も走っていますがココでは説明しません。
(例)ボタンキャプション位置を変更させる
#include "llmod.as"
#define BS_LEFT $100
#define BS_RIGHT $200
#define BS_CENTER $300
#define BS_TOP $400
#define BS_BOTTOM $800
#define BS_VCENTER $C00
#define WM_GETTEXT $D
;************************** 概要説明 *****************************
;
; btnstyle n1,n2,n3
;
; n1 : オブジェクトID
; n2 : 横(0:左 1:中央 2:右)
; n3 : 縦(0:上 1:中央 2:下)
;
;****************************************************************
#module "object"
#deffunc btnstyle int,int,int
mref id,0
mref x,1
mref y,2
mref bmscr,67
sdim txt,16 ; ボタンキャプション入れ
dim align,3
dim valign,3
if (x<0)|(x>2)|(y<0)|(y>2) : return
align=BS_LEFT@,BS_CENTER@,BS_RIGHT@
valign=BS_TOP@,BS_VCENTER@,BS_BOTTOM@
id+41
; スタイル変更
prm=bmscr.id,-16 ; -16:現行スタイル
setwndlong prm,1 ; GetWindowLong
prm.2=stat+align.x+valign.y-rev ; 新スタイル設定
rev=align.x+valign.y ; 次回実行した時に一旦戻す
setwndlong prm,0 ; SetWindowLong
; スタイル更新
getptr p,txt
prm=bmscr.id,WM_GETTEXT@,16,p ; キャプション取得準備
sendmsg prm ; SendMessage
objprm id-41,txt
return
#global
objsize 80,20
pos 150,50 : mes "横"
pos 180,50 : combox yoko,100,"左\n中央\n右"
pos 150,80 : mes "縦"
pos 180,80 : combox tate,100,"上\n中央\n下"
objsize 200,80
pos 300,50 : button "スタイル変更",change
stop
*change
btnstyle 2,yoko,tate
stop