第12回 広がる世界〜共有ライブラリを使ってみよう「2.見た目が派手な奴 プログレスダイアログ」

12−2 見た目が派手な奴 プログレスダイアログ

 さて、今回使おうとするNSBSystemLibは、Palmなお部屋の1周年記念として、NS Basic社公開のライブラリの説明を私の方で訳させて頂いたものなのですが、実際に、よく分からない所もあって、今読むと恥ずかしい感じもします。
具体的なリファレンスは、http://www.nsbasic.com/palm/Japanese/technotes/TN14.htmこちらを参照して下さい。

では、早速、眺めてみることにしましょう。
結構多くの関数が用意されていて、何から試そうか迷ってしまいますが、とりあえず、最初に使ってみようと思ったのが、プログレスマネージャ、と呼ばれる機能です。
これは、要するに「処理中 xx%」という状態をグラフ化したダイアログを画面上に表示させる御馴染みのものですが、これをNS Basicの関数だけで作るのは大変な作業になります。しかし、これらの機能を使うことで、とても簡単に実現できます。
まずは、お約束。ライブラリを使う時は、最初に LoadLibraryで読み込みをしておきます。
        Sub main()
            LoadLibrary "NSBSystemLib", "NSL"
        End Sub
これをStartupに入れておけば準備完了です。
さて、どういう風に使うかよくわからないので、ProgressStartDialogのサンプルコードをそのまま使ってみましょう。よく理解していないコードをそのまま使うのは、結構勇気が必要ですが、適当にボタンを貼って、サンプルコードを貼りつけてみることにします。

	Sub object1004()
		Dim title as String
		Dim message as String
		Dim stage as Integer
		Dim error as Integer
		Dim force as Integer
		Dim canceled as Integer
		Dim strValue as String
		Dim resolution as Integer
		Dim completeChar as String
		Dim incompleteChar as String
		Dim percent as Integer
		Dim count as Integer

		completeChar = "|"
		incompleteChar = "."
		resolution = 5
		count = 100

		title = "Progress Test..."
		NSL.ProgressStartDialog title
		Delay 1
		error = 0
		stage = 1
		Do While stage <= count
		    canceled = NSL.ProgressUserCancel()
		    If canceled = 1 Then
		        Exit Do
		    End If
		    percent = NSL.ProgressPercent(stage, count)
		    strValue = NSL.ProgressPercentString(percent, resolution, completeChar, incompleteChar)
		    Message = strValue + Chr(10) + Str(percent) + "% complete" + Chr(10) + "stage = " + Str(stage)
		    NSL.ProgressUpdateDialog error, message
		    stage = stage + 1
		    Delay 0.25
		Loop

		force = 0
		Delay 1
		NSL.ProgressStopDialog(force)
	End Sub
さて、実行してみましょう。NSBSystemLib.prcも忘れずにインストールして下さい。

   → 

どうでしょうか?簡単にプログレスダイアログが使えましたね。では、このサンプルプログラムを見ながら、その機能を見ていくことにしましょう。

まず、手順を見ると、最初にプログレスダイアログを表示する必要があるようです。
Do〜Loopの外にある部分がそれに相当しそうです。
	NSL.ProgressStartDialog title
このコマンドを実行すると、1つの「キャンセル」ボタンをもったダイアログが表示されます。
タイトル(title)は、ダイアログのタイトルのようです。スクリーンショットでも、ダイアログのタイトルと変数titleの内容が同じですね。ちなみに、日本語もOKのようです。
じゃ、
	NSL.ProgressStartDialog "ダイアログのテスト"
のように、わざわざ、変数に入れなくてもいいジャン、と思うかもしれませんが、このライブラリというのは、関数に渡す引数の型に厳格なので、型が明らかになっている宣言された変数に代入してから使うのが安全です。
文字列の時は、あまり問題ないのですが、例えば、数値を指定する場合、
	NSL.ProgressStopDialog(force)
この場合、変数forceが 0か 1しかないのに、わざわざ変数に入れています。しかし、直接 0 や 1を指定したら、この数値が実数なのか整数なのか、または、LongかIntergerか分かりませんので、forceというInteger型の変数を用意しておき、引数が「Integer型」であることを明示しているわけです。
単にNS Basicを使っているときに比べ、共有ライブラリを使う場合は、その引数の型が重要になってくる事を覚えておきましょう。

さてさて、進行状況を表すグラフはよく出来ているなぁ、と思いませんか?さすがライブラリ!とプログラムを見てみると、このグラフは文字で表現しているように見えます。プログラムこの部分でしょうか?
		completeChar = "|"
		incompleteChar = "."
確かに進行済みのキャラクタが「|」、未進行の部分が「.」で表示されていますね。そう、これはグラフィックではないのです。
実際にこの変数を使っているのが、
	strValue = NSL.ProgressPercentString(percent, resolution, completeChar, incompleteChar)
という部分ですが、これは、表示用の棒グラフ文字列を作成する関数です。
変数percentで指定された割合に対して、進行度を変数completeCharと変数incompleteCharの組み合わせで棒グラフを作成します。percentはそのままパーセントで指定しますので、0〜100の数値になります。ただ、この変数は整数ですので、45.3%のような数値を表す事は出来ません。とは言え、使う上では整数で十分ですね。
さて、この棒グラフのキャラクタは文字ですから、別の文字に変更できるのではないか、と思いませんか?
もちろん、この変数の値を変えるだけで、別のグラフを表示する事が出来ます。例えば、
		completeChar = "@"
		incompleteChar = "-"
とすることも可能です。
でも、実行すると...

  

ありゃりゃ、はみ出ちゃいましたね。実は、リファレンスには「進行済み、未進行のキャラクタは同じ幅で2ピクセル幅の方が適当」という表現があります。そういうことで「|」や「.」のようなキャラクタが妥当なわけです。
でも、棒グラフに必要な文字数が少なければ、収まりますね。このサンプルでは、横に20文字並んでいるのですが、これは、resolutionという引数で指定します。正確には(100÷resolution)文字の長さになります。このサンプルでは、100÷5で20個の長さになっていますが、これを変更すれば、横幅の広い文字でも収まるはずです。
		resolution = 10
		completeChar = "@"
		incompleteChar = "-"
この場合は、

  

横に10文字ですから、何とか収まりそうです。ちなみに、resolutionは「解像度」です。

さて、実際の進行度を表すpercentですが、
		percent = NSL.ProgressPercent(stage, count)
で計算する事が出来ます。もちろん、percent = stage / count * 100 でも構いません。どうやら、とりあえず用意された関数のようですね。一連のセット品として(笑)
また、percentで指定する範囲は 0〜100ですが、0以下を与えてもエラーになりません。ただし文字化けを起すようです。一方、100を越える値を与えると無視されます。

ダイアログを終わらせるには、
		NSL.ProgressStopDialog(force)
を実行します。これは、forceの値によって、すぐに終わるか、終了確認をしてから終わるかの選択になるようですが、実際はキチンと動作しませんでした。現時点では、表示を消すために使う命令という程度の認識でよいでしょう。
一方、途中で止めるには、ダイアログのキャンセルボタンをタップします。すると、自動的にキャンセルされて、NSL.ProgressUserCancel()という関数の戻り値が、1 になります。
したがって、これでチェックし、1 になった時点で終了する処理を行えばOKです。
途中で中断したら、「処理はユーザーにより中断されました。」というダイアログが表示したいところです。こういう場合にも、ダイアログの表示は使えます。
この文で、
		NSL.ProgressUpdateDialog error, message
error=1にすれば、[キャンセル]ボタンが[OK]ボタンに変りますので、messageに適当なメッセージを入れて実行すれば処理は出来るでしょう。ただ、こちらも動作したりしなかったりと不安定なので、ちょっと不満の残る所です。

このように、やや不備な点も幾つか見受けられますが、このプログレスダイアログについては、思った以上に使える機能だと思います。
注意するのは、処理中は、このダイアログが、モーダルなフォームになる点でしょう。
そもそも、待ち時間に進行度を伝える目的で使いますから、その間に何らかの操作をする前提で作られてはいません。しかし、フォーム上のフィールドやリストボックスなどのオブジェクトへのアクセスは可能なので、例えば、データベースから読み込みながらリストボックスに流し込むような処理に使うことが出来ます。
ただし、実際の表示はプログレスダイアログを消してから、Redrawで再描画するのが正解のようです。試していて、フォーム上のフィールドに描画しているつもりが、モーダルになっているダイアログに描画されてしまったこともありました。 ま、実際の描画データは、最終的には目的のオブジェクト上に描かれていますけど、あまり気分良くないでしょうからね。

さて、グラフ文字列「||||||....」等を返す ProgressPercentString()という関数がありましたね。実は、これは、ダイアログの使用とは無関係に単独で使うことが出来ます。つまり、フォーム上のラベルなどに、進行度を表す文字列を表示させる事も可能なのです。ま、それだけのために、ライブラリを読み込むのはどうかなと思いますが、覚えておいても良い方法でしょう。
1つの関数が単体で使える、ということは、実は、このプログレスバーを表示しているダイアログというのが、単なるキャンセルボタンの付いたモーダルなメッセージボックスであることがわかります。もちろん、プログラム中から内容の更新ができるので、プログレスバーとして使う以外の使い方が出来る事も付け加えておきます。



前へ     目次へ     次へ

第12回 広がる世界〜共有ライブラリを使ってみよう「2.見た目が派手な奴 プログレスダイアログ」