〜 オブジェクト編 〜

01.listbox,combox,chkboxの選択が変更されたか調べる

02.mesbox,inputの内容が変更されたか調べる

03.ボタンに書かれた文字の変更

04.自分で描いた画像をボタンにする(簡易版)

05.自分で描いた画像をボタンにする

06.パスワードボックスを作成する

07.ラジオボタン・3ステートチェックボックスを作成する

08.ボタンのジャンプ先を統一してどのボタンが押されたか判定する

09.listbox,comboxの選択項目の文字列取得

10.エディットコントロールのカーソル位置を記憶

11.エディットコントロールのカーソル位置を記憶(応用)

12.mesboxの指定したバイト数で強制的に折り返す

13.TABキーでオブジェクトフォーカスを変更

14.エディットコントロールを読取専用にする

15.listbox,combox作成後にデータを追加する

16.listbox,combox作成後にデータを削除する

17.オブジェクト配置にこだわる

18.オブジェクトを灰色表示(利用不可)にする (要llmod.as)

19.アップダウンコントロールを作ってみる

20.アップダウンコントロール作成 〜上級編〜

21.選択テキスト取得

22.mesbox内の一行を選択するモジュール

23.listboxの選択項目上下入れ替え

24.自前のトラックボックス作成

25.クリップボード履歴をオブジェクトに入れていく (要hspext.dll)

26.オブジェクト内の文字列の検索

27.オブジェクト内の文字列の置換・挿入

28.DLLを使わずにクリップボードを操作する

29.キャレットの点滅速度取得・設定モジュール (要llmod.as)

30.コンボボックスを自動で開く

31.配置オブジェクトの位置をD&Dで自由に動かす

32.配置オブジェクトのサイズをD&Dで自由に変更する

33.65個以上のオブジェクトを扱う

34.エディットボックスの行の前後を入れ替える

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

TOPへ戻る

02.mesbox,inputの内容が変更されたか調べる

  こちらも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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

07.ラジオボタン・3ステートチェックボックスを作成

  ラジオボタンとは複数ある項目の中からひとつだけ選択できるオブジェクト。
  3ステートチェックボックスは3段階(チェック,灰色表示,なし)のチェックボックスです。
  コレもまたobjsendを使用しボタンをそれぞれのオブジェクトに変形させます。
  グループボックスも作成できますがそのまま使うとバグった形になるようです・・・。
  02でも説明したたようにp4には直接値を指定出来ないので0の入った変数で指定します。詳しい説明はコチラ

  (例)ラジオボタン+3ステートチェックボックスを配置

 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

*radio1
 rad=1
 stop

*radio2
 rad=2
 stop

*radio3
 rad=3
 stop

*tchk
 if chk==2 : chk=0 : else : chk++
 stop

*select
 dialog "選択項目"+rad+"\n3ステート "+chk
 stop

TOPへ戻る

08.ボタンのジャンプ先を統一してどのボタンが押されたか判定する

  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

TOPへ戻る

09.listbox,comboxの選択項目の文字列取得

  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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

15.listbox,combox作成後にデータを追加する

  リストの内容を示す文字列を変数で指定して文字列操作命令で追加させる方法と、
  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

TOPへ戻る

16.listbox,combox作成後にデータを削除する

  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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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 0mx)&(cnt*25+25>my)&(flg.cnt=1) {
    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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

36.変換中の文字列の長さを取得するモジュール (要llmod.as)

  現在変換中のテキストサイズを取得するモジュールです。
  何に使うの、という感じですが3738と一緒にご利用ください^^;
  最初に初期化している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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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

TOPへ戻る

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