イベント初心者講座 その8 または The Compleat Angler For Kiri 桐V8の釣魚大全

「かっこう」掲示板の投稿記事から、主に藤野さんとONnojiの問答集を作りました。何か役に立つ話が見つかるカモ?

トップページに戻る あらすじ その1 その2 その3 その4 その5 その6 その7 その8 その9

フォームでテキスト文字列を選択状態(反転)にするには? - ONnoji 2002年02月27日 15時43分
pokoponさん、今回のはいかがでしょうか? - ONnoji 2002年02月27日 17時10分
Good!! - pokopon 2002年02月28日 02時18分
pokoponさん、呼び出してすいません。m(__)m - ONnoji 2002年02月28日 10時20分
Re:さまざまに応用可能ですね - pokopon 2002年02月28日 10時30分
続 フォームでテキスト文字列を選択状態(反転)にするには? - ONnoji 2002年02月28日 13時14分
Re:先に言われた!! - pokopon 2002年02月28日 13時55分
「表引き」ダイアログが閉じた後でもOK! - ONnoji 2002年02月28日 13時30分
「ちょいタイマー」発生のタイミング - ONnoji 2002年02月28日 16時27分
じっくり試してみます。 - 藤野 2002年02月28日 22時12分

フォームでテキスト文字列を選択状態(反転)にするには? - ONnoji 2002年02月27日 15時43分

フォームでデータを編集しているとき、
移動先のテキストボックスで、カーソルを出す替わりに、
あらかじめ文字列を範囲選択した状態にしたいことありますよね。

とても簡単な方法をご紹介します。(^^ゞ

■材料
<イベント>
・イベントハンドラ名:フォーム::タイマー1( )
 ※1回しか実行しないように仕掛けをするのがコツ!

<一般手続き>
・手続き名:prcSelectAll( )
 ※フォーム::タイマー1( )をキックする

<コマンドボタン>
・オブジェクト名:cmdすべて選択
  機能名
[1]すべて選択  ※編集グループから選びます。
[2]なし
[3]なし
[4]なし

■利用方法

[入力前]イベントハンドラで prcSelectAll( ) を呼びます。

以下は利用例です。

※なお、オブジェクト名の"フォーム"、イベント名の"タイマー"は半角カタカナです。
-----------------------------------------------------------------------
名札 メイン
 変数宣言 局所,文字{ &mObjCmd }         /* コマンドボタンのブジェクト名 */
 オブジェクト操作 @フォーム.タイマー1 = "0"    /* タイマー1をoffにします */
 オブジェクト操作 @フォーム.タイマー値1 = "0.01"
 *

手続き定義開始 t住所::入力前(参照 文字列 &編集文字列)
  :
 *いろいろします。
  :
 手続き実行 prcSelectAll( )  /* このように利用します */
手続き定義終了

手続き定義開始 フォーム::タイマー1( )
 オブジェクト操作 @フォーム.タイマー1 = "0" /* 直ちにoffにします */
 メソッド呼び出し &mObjCmd.実行( )      /* コマンドボタンを実行 */
手続き定義終了

手続き定義開始 prcSelectAll( )
 &mObjCmd = "cmdすべて選択"           /* コマンドボタンのオブジェクト名を変数に代入 */
 オブジェクト操作 @フォーム.タイマー1 = "1"  /* タイマー1をonにします */
手続き定義終了

-----------------------------------------------------------------------

入力前イベント → prcSelectAll( ) で
「ちょいタイマー」=フォーム::タイマー1( )をキックするというものです。
「ちょいタイマー」はそれ自身をOFFにするので1回実行して終わりです。

pokoponさん、今回のはいかがでしょうか? - ONnoji 2002年02月27日 17時10分

pokoponさん、こんにちは。

ONnojiもpokoponさんも、今までいろいろ悩んできたテキストボックスの選択ですが、
今回のはいかがでしょうか?

Good!! - pokopon 2002年02月28日 02時18分

ONnojiさん、藤野さん お久しぶりです。
最近、「人付き合いが悪いと噂される」pokoponです。
(ふぇ〜ん、単に忙しいだけなのに!)

さて、今回のこの手法はいけます。(^o^)vv

以前に他のBBSで話題になった方法は、同じくタイマイベントを使っていますが、「フォーカス取得」イベントで、タイマをキックするものでした。
これでは、訂正モードでなくともタイマが動く事になります。

今回ご紹介いただいた方法は、入力前イベントですので、確実に訂正モードに入る直前に「タイマをキック」し、1度しか実行されないということです。
こちらが、基本的にスマートですね。

ただ、ファミリに指定できないという欠点があります。
入力項目が少ない場合には、それぞれイベントを作成すれば解決できますので、こちらの方がスマートです。事前に入力データの加工もできますので。
加工後に、おまじないとしてこのイベントをCallすればよい訳ですしね。

桐の仕様というか(当たり前といえば当たり前)、エディタに入ってからは外からイベントで手も足も出ませんので、やはり「タイマ」イベントによる迂回技が必要になってきます。

さて、「全て選択」を実行するのに、他のBBSでは
>method &focus.編集選択位置設定(1,-1)
なんて方法を使っていました。ONnojiさんは、ここであえてダミーのコマンドボックスを仕掛け、機能名で「全て選択」を実行しています。
初心者に優しい設計ですね。さすがです。これなら、仕掛けやすく理解しやすいですので。

ついでに、機能名に「編集制御」なんてものもあります。
右側にカーソルを移したり、右から2文字目にカーソルを移すなど、木目の細かい指定が可能です。
理屈が分かれば、初心者でも使える簡単なコマンドかと思います。

pokoponさん、呼び出してすいません。m(__)m - ONnoji 2002年02月28日 10時20分

pokoponさん、呼び出してすいません。m(__)m

> ONnojiさん、藤野さん お久しぶりです。

こちらこそ、ご多忙のところ誠に恐れ入ります。m(__)m

> さて、今回のこの手法はいけます。(^o^)vv
> 以前に他のBBSで話題になった方法は、同じくタイマイベントを使っていますが、「フォーカス取得」イベントで、タイマをキックするものでした。
> これでは、訂正モードでなくともタイマが動く事になります。
> 今回ご紹介いただいた方法は、入力前イベントですので、確実に訂正モードに入る直前に「タイマをキック」し、1度しか実行されないということです。
> こちらが、基本的にスマートですね。

些細なことですが…
おそらく、すでに訂正モードに入っているから[入力前]イベントが発生しているのだと思います。(^^ゞ
訂正モードでエディタへ進入する直前、つまりエディタの外で[入力前]イベントが発生するということですね。

> ただ、ファミリに指定できないという欠点があります。

これは残念ですが、それほど大きな欠点ではないと思います。(^^v

> 入力項目が少ない場合には、それぞれイベントを作成すれば解決できますので、こちらの方がスマートです。事前に入力データの加工もできますので。
> 加工後に、おまじないとしてこのイベントをCallすればよい訳ですしね。

そうですね、メリットがたくさんありますね。

> 桐の仕様というか(当たり前といえば当たり前)、エディタに入ってからは外からイベントで手も足も出ませんので、やはり「タイマ」イベントによる迂回技が必要になってきます。

エディタに進入した直後に発生するイベントが用意されていれば、[タイマー]イベントは使わなくていいのですが、残念ながらそういうイベントは用意されていません。
そうそう、某BBSではこのようにタイマーを使うことを「迂回」と表現していましたね。
私は、「遅延する」という意識の方が強かったです。まあ同じような意味ですけれど…
エディタに進入した後で、何かするにはタイマーで時間差を利用すればいいのではないかという発想です。

> さて、「全て選択」を実行するのに、他のBBSでは
> >method &focus.編集選択位置設定(1,-1)
> なんて方法を使っていました。ONnojiさんは、ここであえてダミーのコマンドボックスを仕掛け、機能名で「全て選択」を実行しています。
> 初心者に優しい設計ですね。さすがです。これなら、仕掛けやすく理解しやすいですので。

いえいえ、今回の手法は「カーソルが左にありますが一番右にしたいのです」という藤野さんのリクエストが発端で考えたものです。
試してみたところ、「文字列の末尾にカーソルを移動すること」、「すべて選択すること」等などが可能だと分かりました。
したがいまして藤野さんの一言がなければ、考えもしなかったというのが本当のところです。
藤野さん、どうもありがとうございます。m(__)m

Re:さまざまに応用可能ですね - pokopon 2002年02月28日 10時30分

> 些細なことですが…
> おそらく、すでに訂正モードに入っているから[入力前]イベントが発生しているのだと思います。(^^ゞ
> 訂正モードでエディタへ進入する直前、つまりエディタの外で[入力前]イベントが発生するということですね。

そのとおりです。訂正モードでない場合に「空振りがない」と言う意味で使いました。

また、エディタに入る前の制御(文字位置など)をコマンドボタンで設置できるということから、編集制御も使えるかと思います。
いずれにせよ、応用ができます。
コマンドボタンでの設定なら(ダミーで結構)、初心者でも設置しやすですので。

藤野さんも是非この技術を使えるようになれば、さらに入力しやすいフォームが作れますので、頑張りましょう。

続 フォームでテキスト文字列を選択状態(反転)にするには? - ONnoji 2002年02月28日 13時14分

続 フォームでテキスト文字列を選択状態(反転)にするには?

※オブジェクト名の"フォーム"、イベント名の"タイマー"は半角カタカナです。

<タイマーイベントのこと>

いわゆる[タイマー]イベントは、正確には[タイマー1]と[タイマー2]のふたつがあります。
ここでは[タイマー1]を例に挙げますが、[タイマー2]も同じです。
このイベントはフォームのイベントです。

オブジェクト名.属性名(プロパティ)は次のようになります。

[フォーム.タイマー1] … オフの値は "0",オンの値は "1"
[フォーム.タイマー値1]… 任意の秒数 ※最小値は "0.01"

これらの値を変更するには[オブジェクト操作]コマンドを用います。

オブジェクト操作 @フォーム.タイマー1 = "0"    /* タイマー1をoffにします */
オブジェクト操作 @フォーム.タイマー値1 = "0.01" /* インターバルを0.01秒にします */

<いろいろなタイマーイベント>

(a)常時実行するタイマー

フォームの初期値として[フォーム.タイマー1]の値を "1"(オン)にしておくと、
タイマーイベントは指定されたインターバルでフォームが終了するまで発生します。

例えば[フォーム.タイマー値1]の値を "1" にすると1秒のインターバルでこのイベントが発生します。
このことを利用すると時刻表示することができます。すこし凝ればアナログ時計も作れます。
あるいは、1秒ごとに何かを監視することもできます。

(b)一定の時間実行するタイマー

1.あるイベントの発生を起点として、またはフォームの初期値として、
2.[フォーム.タイマー1]の値を "1"(オン)にして、タイマーイベントを発生させて、
3.一定の時間経過したら[フォーム.タイマー1]の値を "0"(オフ)にするという使い方もあります。

(c)1回だけ実行するタイマー

1.あるイベントの発生を起点として、、
2.[フォーム.タイマー1]の値を "1"(オン)にして、タイマーイベントを発生させて、
3.1回だけ実行して[フォーム.タイマー1]の値を "0"(オフ)にするという使い方もあります。


<ちょいタイマー>

今回ご紹介した方法は、「(c)1回だけ実行するタイマー」を利用したものです。
この利用法はタイマーを1回しか実行しないので風変わりな方法に感じられると思います。
私はこの方法を「ちょいタイマー」と呼んでいます。

もっと良い名前があるかもしれません。(^^ゞ
例えば、チョットタイマー、単発タイマー、手続き型タイマー、う〜んなかなか難しいなぁ〜。

1回だけ実行してすぐに停止してしまう性質から、
[通常のイベントハンドラ]や[一般手続き]とよく似ているわけなんですね。

例えば、[マウス移動]イベントのように次々に発生するイベントもあります。
[タイマー1]イベントも基本的には次々に発生するイベントです。
しかし、「ちょいタイマー」は次々に発生しないという意味で[通常のイベントハンドラ]や[一般手続き]とよく似ているのです。

<ちょいタイマーの形態>

「ちょいタイマー」の基本形は次のような格好をしています。

手続き定義開始 フォーム::タイマー1( )
 オブジェクト操作 @フォーム.タイマー1 = "0"
手続き定義終了

上の例では何も実行しないので実際には次のような形になります。

手続き定義開始 フォーム::タイマー1( )
 オブジェクト操作 @フォーム.タイマー1 = "0"
 メソッド呼び出し &mObjCmd.実行( )
手続き定義終了

ところで、「オブジェクト操作 @フォーム.タイマー1 = "0"」の位置はどこでも構いません。
上の例では[ちょいタイマー]であることを強調したかったので、最初の行においてある次第です。

<「ちょいタイマー」をキックする>

「ちょいタイマー」を実行するには、あるイベントを起点にして、
「オブジェクト操作 @フォーム.タイマー1 = "1"」コマンドを実行すればいいことになります。
このことを「キックする」と表現しましたが、おそらくご理解いただけると思います。

今回ご紹介した方法は、[入力前]イベントを起点にしていますが、
少し工夫をして、実際には一般手続き:prcSelectAll( )で「ちょいタイマー」をキックしています。

手続き定義開始 prcSelectAll( )
 &mObjCmd = "cmdすべて選択"
 オブジェクト操作 @フォーム.タイマー1 = "1"
手続き定義終了

これは、&mObjCmd の値を変えることで実行するコマンドボタンを変更できるようにするためです。
なお、実験した結果「オブジェクト操作 @フォーム.タイマー1 = "1"」の位置はどこでも構わないようです。
上の例では[ちょいタイマー]であることを強調したかったので、最後の行においてある次第です。

例えば、コマンドボタン:cmdすべて選択 の替わりに、コマンドボタン:cmd文末へ を実行したい場合には、
別途、一般手続き:prcLineEnd( )を用意して、「ちょいタイマー」をキックするのがいいです。

手続き定義開始 prcLineEnd( )
 &mObjCmd = "cmd文末へ"
 オブジェクト操作 @フォーム.タイマー1 = "1"
手続き定義終了

なお、コマンドボタン:cmd文末へ は次のような機能が登録されています。

オブジェクト名:cmd文末へ
  機能名    機能パラメータリスト
[1]編集制御  8 ← これは行末へ
[2]なし    ※"編集制御" は "その他"グループから選びます。
[3]なし
[4]なし

<「ちょいタイマー」のインターバル>

「ちょいタイマー」のインターバルは速い方が望ましいので、最速の0.01秒を指定します。

オブジェクト操作 @フォーム.タイマー値1 = "0.01" /* インターバルを0.01秒にします */

問題はこのインターバルでタイミングがうまく取れるかですね。
実験したところ、0.01秒の指定で問題はないようです。

そこで[名札 メイン]で次のように指定します。

名札 メイン
変数宣言 局所,文字列{ &mObjCmd }
オブジェクト操作 @フォーム.タイマー1 = "0"  /* タイマー1をoffにします */
オブジェクト操作 @フォーム.タイマー値1 = "0.01" /* インターバルを0.01秒にします */


[名札 メイン]で「オブジェクト操作 @フォーム.タイマー1 = "0"」とするのは、
「ちょいタイマー」の初期値はoffだからです。

もしも、タイミングが取れない場合(未確認)は、
(1)[名札 メイン]でインターバルの値を大きくする
(2)「ちょいタイマーをキックする一般手続き」でインターバルの値を大きくする
といいですが…たぶんその必要はなさそうです。

<ファミリーのこと>

[ファミリー]では[入力前]イベントは使えません。
だからといって複数のテキストボックスのオブジェクト名を同じ名前にするのは良くないです。
オブジェクト名は重複してはいけない約束なのでこれは止めましょう。(^^ゞ

Re:先に言われた!! - pokopon 2002年02月28日 13時55分

> <ファミリーのこと>
>
> [ファミリー]では[入力前]イベントは使えません。
> だからといって複数のテキストボックスのオブジェクト名を同じ名前にするのは良くないです。
> オブジェクト名は重複してはいけない約束なのでこれは止めましょう。(^^ゞ

先に言われましたね。
これって、意外と使っていたりして (^^ゞ
今のところエラーはないんだけど、相手がタイマイベントだしな〜。
自主規制かな?

「表引き」ダイアログが閉じた後でもOK! - ONnoji 2002年02月28日 13時30分

pokoponさんリプライどうもありがとうございます。

ところで…
「ちょいタイマー」のタイミングでご心配の方へ面白い結果をお知らせします。

テキストボックスのソースが項目で、
その項目が表の定義で項目属性「表引き」が指定してあるとします。

従って一般的には、このテキストボックスを入力するとき、
「表引き」のダイアログボックスが現れます。

このテキストボックスの[入力前]イベントを起点にして、
「ちょいタイマー」をキックする一般手続き:prcSelectAll( )を呼んだらどうなるか実験しました。

なんと、「表引き」ダイアログが閉じた後、文字列が選択されます。(^^)vv

タイミングはバッチシです。

是非、お試しください。(^^ゞ

「ちょいタイマー」発生のタイミング - ONnoji 2002年02月28日 16時27分

タイマーイベントがどのタイミングで発生しているのか興味があったので、
[トレース出力]ウィンドウで確認してみました。

・コマンド実行状況をトレースする

┌ 一括実行:手続き"t住所::入力前("あああ")"を実行開始しました
│┌ 一括実行:手続き"prcSelectAll( )"を実行開始しました
│└ 一括実行:手続きを実行終了しました
└ 一括実行:手続きを実行終了しました
┌ 一括実行:手続き"フォーム::タイマー1( )"を実行開始しました
└ 一括実行:手続きを実行終了しました

・イベント実行状況をトレースする

┌ 一括実行:イベント粛t住所::入力前"を実行開始しました
└ 一括実行:イベント粛t住所::入力前"を戻り値=1で実行終了しました
┌ 一括実行:イベント粛フォーム::タイマー1"を実行開始しました
└ 一括実行:イベント粛フォーム::タイマー1"を戻り値=1で実行終了しました

ということで、[入力前]イベントが終了するまで、
「ちょいタイマー」は実行されないということが分かりました。

じっくり試してみます。 - 藤野 2002年02月28日 22時12分

Pokopon さん今晩は、お久しぶりです
 3月になるので超いそがしいことと思いますが・・
 時々お声がけよろしくお願いします。
 私も少しはレベル上がっていると思いますが (^^ゞ
 かなり勘違いして覚えていたことがボロボロでて来ています。
 頑張ります。

ONnojiさん今晩は
 早速、試してみましたがもう少しいろいろやってみます。
 2.3日試したらこの件はまた書き込みます。


トップページに戻る あらすじ その1 その2 その3 その4 その5 その6 その7 その8 その9