GC / Win への道

- MS BASIC から Visual BASICへの移植ノート

愛知教育大学数学教室 飯島康之


目次

  1. はじめに
  2. まずはエディタ作り
  3. 落書き機能
  4. 簡単な関数描画ソフト
  5. 点・線・円の構造体を使えるようにする(GC/win ver.0.0)
  6. 変形の実装
  7. 「点の選択」の実装
  8. テスト版公開のための「セットアップ」作成(ver.0.1)
  9. DLL,OCXなど,どこまで配布可能なのか(1)
  10. DLL,OCXなど,どこまで配布可能なのか(2)
  11. 「作図の継続」や「測定」の実装
  12. 幾何的対象の「選択」
  13. 開発環境としてのVBの便利さ(1)
  14. 「数値の選択」
  15. 例外的な作図手続き
  16. バグ取りの実際
  17. こんなことってあるんだろうか。(1)
  18. こんなことってあるんだろうか。(2)
  19. 組み込まれるDLL,OCXは削減できないか(ver.0.2.7)
  20. 残念ながら,一休み
  21. と思いつつ,ついつい ver.0.2.8 を
  22. セットアップ用のフロッピィディスクの作成
  23. しばらくの間沈黙の秘密?
  24. ネットワーク対応にしようと思って起きたトラブル
  25. マシンのトラブル等で,長期休憩
  26. コントロールのフォーカスを設定するのは,「load」ではなく,「activate」にて
  27. tab index は便利
  28. 自動組み込みするファイル群を設定するには,swtファイルを直接編集
  29. VBのセットアップを使うには,「同一名のファイルはだめ」
  30. プログラムマネージャーなどの利用(shell, sendkey,..)とタイマーコントロールの利用
  31. プログラムマネージャーなどの利用(shell)で生じた問題点とその解消(ファイル/パスのロングネーム)
  32. WindowsAPI利用による上記の問題の解消
  33. 直交座標/極座標の切り換え
  34. ver.1.1.5 から B 版の廃止
  35. げ。1.1.4にはなかったバグ。

はじめに

学校で使えるマシンはまだまだDOSが多いとはいえ,そろそろWindowsへの移植を考えなければならなくなってきました。
そこで,ここでは,その移植への道を探りながら,自分なりのVisual BASICへの移植ノートを作ってみようと思います。
ただ,移植への時間をどれだけ確保できるかは未定ですので,結構時間がかかるのかもしれません。
また,文章というよりも,思いつきノートのような体裁になるかと思いますが,ご了承ください。

まずはエディタ作り


落書き機能


簡単な関数描画ソフト

今度は,数学向きのグラフィックをするための最初の練習。x-y座標を設定して,2次関数のグラフを描くっていうやつ。

点・線・円の構造体を使えるようにする(GC/win 0.0)

さて,これからが本格的な移植になる。最初の目標は,GCの簡単なファイルを読み込んで,描画できるようにすること。その前段階として,GCでの基本的な構造体を実装すること。これをver.0.0の目標としよう。

  • 描画の属性設定は簡単

    MBのときは,たとえば,線の太さを変えることはできないので,自分でそういうコードを作る必要があった。VBでは,プロパティを変えるだけで,OKである。コードがかなりシンプルになる。

    ファイルを読み込んで,簡単な図形の描画を行えるようにする(GC/win 0.1)

    ver.0.0は,組み込むコードはそれほど多くなかった。上記のような,いくつかの発見はあったが,まあ,何とかクリアである。
    さて,いよいよ最初の目標の,GCの簡単なファイルを読み込んで,描画できるようにすることを実装しよう。これをver.0.1とする。

  • かなりの数のプロシージャ

    今回は,まずかなりの数のプロシージャを組み込まないと動きださない。というのも,描画を支えるすべてのプロシージャが組み込まれていないと動かないからであり,その数が結構なものになるからである。しかし,たとえば数学的な関数のようなもの,作図の手続きを実行するようなもの,つまりユーザーからの入出力を必要としないコードは, あまり手を加えずに済むものが多い。逆にユーザーインターフェイスを作ったり使ったりするものは,ほとんどだめである。そういうものは,まずかなり削除してしまい,必要に応じて,作りなおすという形になった。

  • DEF***はお払い箱

    小さなことだが,DEF***は使えなくなった。エラーが表示されるたびに消せばほぼokだが,宣言に関する部分での変更は,変数名は同じでも,型が違うことから別変数として認識される危険性などを考えると,ちょっと不安である。いずれ,すべての変数を explicit に宣言する必要があるかもしれない。

  • 配列の宣言方式の変更 - DIM と REDIM -

    MBでは,
    (1)グローバル変数については,
    common shared x()
    dim x(100)
    ..
    redim x(200)
    
    のように,宣言部分で common文で宣言し,大きさを dim 文で宣言し,大きさの変更では redim を使うという方法を使った。
    これが,VBでは,静的配列であれば,モジュールレベルで
    public x(100) と宣言すれば,おしまいである。また,動的配列であれば,
    public x()
    redim x(100)
    ..
    redim x(200)
    
    と,以前のように,1回目は DIM で 2回目以降は REDIM という使い分けをする必要はなくなった。
    「なんで(RE)DIMなの」という,素朴な命名への疑問は残るけれども,とてもすっきりした。実際,これまでは,
    SUB SetX(n)
    static passed
    if static = 0 then
       dim x(n)
    else
       redim x(n)
       passed = -1
    end if
    END SUB
    
    のような書き方をいたるところでしていたが,こんな不自然な書き方をしなくて済むのだから。
    (2)ローカル変数についても, 以前は,上記のような使い方をしていたが,今回からは,
    DIM 文は,宣言の役割になったので,
    DIM x(199) : 静的配列の宣言
    DIM x() : 動的配列の宣言
    ということになった。このため,動的配列を使い方場合には,不思議の書き方だが,
    DIM x()
    REDIM x(199)
    
    のような書き方をすることになった。

    変形の実装

    実は,「変形」の実装そのものは,あまり難しくなかった。98やFMR50では二つの画面を切り換える工夫をしていたが,R60やDOS/Vでは一つの画面しか使っていない。基本的に後者のプロシージャを多少手直しする程度で対応できた。しかし,問題は別のところにあった。「どの点を動かすか」の選択である。MSのときは,
  • 変形のプロシージャ
  • 変形の処理
    というような構造になっていた。しかし,VBの場合は,イベントドリブン型のプログラミングなので,たとえば,「選択のプロシージャ」の中で inkey$ などによって入力を待つというスタイルのプログラミングはできない。そちらは, Form_KeyDown などのイベントプロシージャが駆動されることになる。
    要するに,ちょっとした修正ではなく,少しきちんと考えて修正しなければならないのである。
    そこで,暫定的に InputBoxを使って,「何番目の点を動かすか」を入力させるようにした。最初は10回分上に動かすようにした。
    しかし,それでは面白くないので,Form_KeyDownイベントを使って,矢印キーによって動かせるようにした。

    ここまでやって,実は約半年が過ぎる。「ちょっと面倒」ということと,もう一方で,WWWの充実や論文の作成や授業の準備など,いろいろなことが必要になってきてしまったからである。

    その間に,GSPのWindows版が届いたり,またWWWを覗いてみると,たとえばドイツではいろいろなソフトが公開されている状況などが目に入った。また,川崎市総合教育センターに伺った折りに,国立教育研究所の堀口先生と偶然お会いし,ソフト作りについて,ちょっと元気が出てきたりした。....そんな経緯を経て,「また少しやってみるか」という感じで再開である。

    「点の選択」の実装

    上記のように,「点の選択」をするためには,イベントドリブン型のプログラミングスタイルに切り換える必要がある。Geometric Constructor(DOS)のときも,状況関知のための変数として, Status という変数を持っていた。ある状況がどう変わったか,またそれが終わったかを把握するためには,主として,
    SUB ***
    OldStatus = Status
    Status = ***
    ...
    Status = OldStatus
    call PrintStatus
    END SUB
    
    というコーディングをしていた。プロシージャを呼ぶことによって,スタックがたまって行き, END SUB を通過すると,そのスタックが解消されるという構造なので,これでOKだったのだ。しかし,今回はそれは使えないことになった。そして,「点の選択」などのプロシージャは,流れを把握する状況関知変数を使って,イベントを中心としたいくつかのプロシージャに分割することになった。
    状況関知に関しては,次のような手段を取る事にした。
    まず,状況関知変数とそれに関するプロシージャを次のように設定した。
    public Status as integer
    SUB StatusSet(n as integer)  : 状態 n を設定, -1 のときは,スタックを一つ減らす
    FUNCTION StatusGet           : 状態を取得
    SUB StatusPrint              : 状態をステータスバーに表示
    
    イベントとして基本的に生じるのは,
    Form_KeyDown
    Form_MouseDown
    Form_MouseMove
    などである。そこで,それぞれの中で,状態に応じて分岐することにした。つまり,
    SUB Form_KeyDown
    select case StatusGet
    case ***
      call Deform_KeyDown
    case ***
      call Select_KeyDown
    end select
    
    などである。MSのときの方が,「ここでこういう情報を取得して,こういうことをこうする」という思考はしやすい。しかし,たとえばイベントの側から見ると,同じキー取得でも,一体どこのinkey$なのかは分かりにくい。また,思わぬところで,プロシージャの呼び出しが入れ子になってしまっている可能性もある。VBの場合,イベントの側からは見やすい。そのようないろいろなことを考えると,双方一長一短があるんだろうなあ,と思った。

    また,ここまでは,キーボード中心のコーディングになっていたが,マウスイベントにも「変形」にしろ,「選択」にしろ,対応できるようにしてみた。こういうのも,そういうフログラミングスタイルに慣れてしまえば,それほど難しいものではないことを感じた。


    テスト版公開のための「セットアップ」作成(ver.0.1)

    例の読み込み・変形・軌跡が実装できると,今までのファイルを使って作業することができる。普通の授業では,この3つでも十分なことが多い。そういう意味で,このあたりの実装段階から,仲間に公開することを検討してみようと思った。ファイルはせいぜい230KB程度である。「これは簡単だ」と思った。

    しかし,現実は違った。VB5ではネイティブコンパイラ搭載なんだからDLLが不要なのかなという私の考えは全くの誤解だった。自分の研究室では,gcw-01.exeはエクスプローラで選択するだけで稼働した。しかし,コンピュータ室のFMVでは「○○.DLLがありません」と言われて動かない。VB5をインストールしてあるマシンでならば動く。「VB5をインストールしている人じゃないとだめっていうことはないはずだけど」

    マニュアルを読んでみると,「セットアッププログラムの作成」に関して,「セットアップウィザード」のことなどが記述されていた。使ってみた。これは便利である。市販のソフトのセットアップとほぼ同様のことをしてくれる。レジストリに登録までしてくれて,いたれりつくせりである。しかし,気がついたことが一つあった。「結構容量が必要なんだ」
    GC/Winの本体はせいぜい230KBなのだが,それを支えるDLLやOCXなどの総計は,圧縮前で10MB,圧縮後で 5MB。フロッピィでは4,5枚必要。あるいは,CD-Rの方がいいかもしれない。ネットワーク経由でも, 230KBだったら,ほとんどなんともない容量だが,5MBとなると,SINET内部などでは,ほとんど問題ないけど,外部からのアクセスでは,「時間がかかるぞー」ということもありそうだ。
    まあ,こういう感じで,いろいろなプログラムに分散させながら,一つの総体を作るっていてのが,Windowsでのプログラミングっていうわけね。


    DLL,OCXなど,どこまで配布可能なのか

    セットアップを配布するようにしたら,一つの問い合わせがあった。
    DLLやOCXも配布してしまったいいのか,という問い合わせである。
    VBのマニュアル(プログラミングガイド,p.804)では,「17.2 配布が許諾されているファイル」という項目で,次のような記述がある。
    この文面からは,「\Graphics と \ODBC 以外のファイルは自由には配布できない」と読めるのではないかということである。解釈の可能性は二つありうるだろう。一つは,上記のように,「それ以外は原則としてできない」という考え方である。難癖を付けられないようにするためには,賢明な解釈かもしれない。
    しかし,そうだとすると,一切のdllやocxは許諾が必要になる。標準コントロールしか使わないアプリでさえということだ。そうだとすると,VBを持っている人には使えるけれども,そうでない人には,原則としては,使えないようなアプリしか開発できないという妙なことになる。そんなことは,常識的にも考えにくい。たとえば,VBマガジンでの酒井氏の「ActiveX Controlは開発スタイルを変える」という文章(1997-7月号,p.65)の中では,ActiveXコントロールの形式として,次の3つを挙げている。
    1.UserControlのみ
    2.UserControl + Visual Basic内蔵コントロール
    3.UserControl + ActiveX
    そして,「3」の場合は,著作権,配布におけるライセンスなどを述べている。逆に,「2」に関しては,「Visual Basic内蔵コントロールは,実際にはほとんどWindows自体が持っているコントロールであるから,...」というような内容である。このような文脈で書かれる事や,これまでのランタイムライブラリは配布自由であったこと,それが標準のdllやocxに発展したものであること,また,もし許諾が必要だとすると,それを行う事務自体があまりに多くなり,Microsoft自体はそういうことなどしないだろうということ,また,もし有料でするのであれば,かなりの収入源になる上,これまではしなかった手続きを要求するのであるから,マニュアル等でかなり明確に記述すると思える。
    そういう面で考えると,個人的には,次のように考えている。
    ちなみに,次のような文章もある。

    関連するところ


    DLL,OCXなど,どこまで配布可能なのか(2)

    VB5の「使用許諾契約書」には,次のような記述があった。

    なお,REDIST.TXTの中で,dll,ocxのみを抽出したものが以下である。
    ということで,一応は一見落着である。
    そこで,結論を簡単にまとめておこう。

    結論
    関連資料
  • MSのFAQでの記述
  • VB4での再頒布可能なファイルのリスト

    著作権表示に関して (上記のFAQでの記述より)


    「作図の継続」や「測定」の実装

    ver.0.1では,「作図ができないじゃないか」ということで,次のステップは「作図の継続」等の実装です。しかし,これが簡単そうに見えて,そんなに簡単じゃない。というのも,プログラミングスタイルがMBとVBで違うからで,点の選択の実装でもかきましたけど,今までであれば,「垂直二等分線の作図」に関しては,こういう流れでこういう作業をしてねというのを,そのままコーディングできたわけです。いわば,
    メイン →  入力待機 ------+ 分岐   +-->処理A -> ・・・ -> 処理終了 --> メインへ
                                       +-->処理B -> ・・・
    
    という感じでしょうか。いずれにしても,メインでの分岐に戻るまでは,それぞれの処理の中にいることが確保された中で,どこで入力を得るのかそれをどう使うのか等を記述できるわけです。しかし,VBでは,イベントドリブンであり,私が感じる印象としては,
    メイン(イベントを関知可能な状態)
      キーボード------>
      マウス---------->各イベントプロシージャ
      その他---------->
    
    (今までの処理 A 全体に該当していたこと)
    処理A1 - ・・・(内部処理のみ) ・・->メイン (入力が必要なときは戻らないといけない)
    処理A2 - ・・・(内部処理のみ) ・・->メイン
    処理A3 - ・・・(内部処理のみ) ・・->メイン
    処理A4 - ・・・(内部処理のみ) ・・->メイン
    
    というように,「入力が必要な場合」によって,今までまとまっていた処理を分断しなければなりません。しかも,今まではプロシージャの中で,ある入力を求める場合は,そのときの状態は,そのプロシージャのテンポラリな内部変数が使えたわけですけど,今回は,処理を「終了させてイベント監視に渡す」必要があるので,今までのテンポラリな変数の中のかなりの部分の可視性を広げなければなりません。つまり,モジュールレベルの変数やグローバルレベルの変数にしなければなりません。
    こういう点は,MSコードをVBに移植するにあたっては,結構面倒です。
    ただ,そうは言っても,今まででも,コーデングの大変なかなりの部分は,インターフェイス作りの部分なので,それをコンポーネントをそのまま使えばいいという省力化を考えると,楽になる部分も大きいですけど。
    また, 今まででの「処理 A 」という流れを,分断したいくつかのプロシージャの流れとして交通整理しなければならないので,「状態」を把握する変数を,かなり緻密に作らないといけないことになります。プログラミング全体としては,ある意味で,わけのわからない長いプロシージャが減り,状態を変数群で把握可能にするというのは,いいことなのかもしれませんが。

    幾何的対象の「選択」

    イベントは,基本的にはキーボードとマウスから得られますが,例えば,Geometric Constructorの場合の基本的な入力は,「どの直線を選択するの」というようなことです。つまり,オブジェクトの選択です。そういう「オブジェクトの選択」をどう作るかが,ソフトにとっては,結構重要なことじゃないかと思います。Geometric Constructorの場合は,DOS版のときから,
    点・直線系・円 : マウス・キーボードによる選択プロシージャを使う
    変数 : メニューからの選択
    だったので,前者に関しては,そのプロシージャをうまく分割・整理することによって,代替プロシージャを作りました。そして,それが作れると,後はかなりスムーズに,コーディング・デバッグを進めることができました。しかし,たとえば,状況によって,選択可能な対象の種類が変わったりするのだけれど,そういうのを,同一のイベントプロシージャの中で記述する必要があるので,それを制御するための変数をいろいろ工夫することが,結構面倒でした。
    なお,変数の方に関しては,今までのメニュープロシージャは使えないので,工夫し直さないといけないので,先送りになりました。そういう意味で,現状では,「変数を選択」するような作図メニューは使えません。

    開発環境としてのVBの便利さ(1)

    今まではVBはせいぜいテスト的にしか使っていなかったので,本格的に利用したのは今回が初めてと言ってもいいのですが,多少遅い部分はあるものの(5100,32Mのノートパソコンなので),かなり快適であることを感じています。いくつか挙げてみましょう。このことについては,またいつか追加したいだろうから,とりあえず,(1)ということにしましょう。

    「数値の選択」

    作図の関係で,今までにできていたのは,「いくつかの幾何的対象(点,直線,円)を元にした基本的な作図手続き」です。次の目標は,「数値」も利用する作図手続きの実装です。GC/DOSのときは,メニューを使って入力していました。しかし,GC/Winでは,この自作のメニューモジュールは使えません。そのため,インターフェイスを作り直す必要が出てきたわけです。新しいフォームを作り,今までの変数から選択する場合と新しく変数を作る場合を分け,作図手続きによって,何種類かの初期化ができるようにしました。GC/DOSと比べると,「数式」がまだないのですが,これは,また次の版での課題として残して置く事にしました。まずは,基本的な機能を実装して,ある程度「使えるものにする」ことが目標だからです。

    例外的な作図手続き

    基本設計に則しているものから,順番に作成したわけですが,「例外的」なものが残って行きました。代表的なものは,
    です。冒頭の「新しく点を取る」ことは,これがないと「最初から作図する」ことができないため,焦眉の課題でした。また,「多角形」もできないと結構面倒です。n等分や角のn等分は,上記ほどの必要性はないのですが,特に「中点」はよく使う機能なので,なんとかしたいというものです。
    基本設計に合わないので,「例外処理」的な扱いをすることにしました。そういうものを付け加えれば付け加えるほど,コードが複雑になり,扱いにくくなってしまいますが,こういうことは,多くの場合についてまわるものです。(そして,そういう例外処理の積み重ねに限界が目に見えて大きくなってくると,基本設計からやりなおし,メジャーの版の変更ということになります。)

    バグ取りの実際

    このような例外処理を付け加える作業では,基本設計の実装のときと比較すると,「バグ取り」の時間と複雑さが大きくなります。ある機能を実装するとき,基本的な線のみでコード化する場合,単純なバグは,最初の段階ですぐに分かります。しかし,そのときには起こらなかったような現象が,「例外的な処理」を加えると出てくることが多いのです。最初は,その例外的な処理に関するコードの不適切性かと思い,分析し,可能な場合は対処するのですが,それではうまく直らないことも出てきます。こういうときは,「それまでうまく動いていたコードに潜在してきたバグの顕在化」がほとんどです。Aという変数で書くべきだったのに,Bという変数で書いていたのだが,基本設計の場合には,実質的にどちらも同じ値を取るので問題はなかったのだが,例外処理ではそれが違う値をとるので,うまくいかなくなってくるなど,そういう現象です。
    GC/Winの場合,典型的にそういう現象が生じたのは,「対象の選択」でした。マウスとキーボードでの選択を可能にしているのですが,片方でうまく動くことを確認していたら,他方で思わぬ現象が起きてきて,その協調性を探るということが多々ありました。
    やはり,このようなところでも,MS-Basicのように,ある処理の中で,「どういう入力があったら,どう処理するか」というのを,別々に書いている場合は,バグの原因等を把握しやすいのに,イベント中心になっているために,複数のプロシージャを眺めないといけないというのは,事情をややこしくしているように思います。

    こんなことってあるんだろうか。(1)

    さて,いろいろな紆余曲折はあったものの,なんとか,ver.0.2として満足するものができました。ver.0.2.4です。しかしながら,実行ファイルを作ってみて,驚くようなことが起こりました。開発環境の中ではきびきび動いていたGC/Winがとっても遅いのです。常識的には,開発環境の中では,p-codeかなにかで,しかもデバッガが動きながらの動作なのだから,ネイティブコンパイラを使って作った実行ファイルの方が速いのが当たり前です。しかし,実際にはそれが逆になっている。正直言って,目の前が真っ暗になりました。
    こんなことってあるんだろうか。
    じつは,その前にも,同様のことが一つありました。それは,コモンダイアログで,Cancelをうまく認識してくれないことです。しかし,それはおそらく,コモンダイアログocx自身の問題なので,自分では直せない。あるいは,ocxを入れ換えることで対応すればいいと,諦めました。しかし,今回は事情が全く異なります。正直言って,これでは使い物にならない。呆然とした気持ちになりました。
    しかも,確認してみると,ver.0.0では,そういう現象は起こっていないのです。また,統合環境内ではうまく動作するということは,論理的には,問題はないのです。VB自体の問題なんだろうか。....

    こんなことってあるんだろうか。(2)

    まずは,VBの問題ではないかと,次のような順序で対処してみました。
    ところが,事情は変わりません。呆然とした気持ちになりました。
    ここから先はもう時間的な問題からやらないことにしようかと思っていたのですが,「ちょっとだけ」という気持ちで,次のような仮説を立て,対処してみました。
    なぜ,統合環境の中では,うまく動作していたのでしょう。よく分かりません。おそらく,統合環境の中では,「変更できれば変更するが,他の処理に追いつかないのならばやらない」というような処理がなされているのに対して,exeでは,実直に実行するような設計になっているのではないかと思います。「4角中点」の100回変形に関して,ver.0.2.4では27秒程度かかっていましたが,それがこの処理で,5秒から6秒程度に削減されました(5100,32M,ちなみに,5133,48MのFMVでは,2秒以内になった)。
    こういうような現象は,いわゆる「バグ」ではありません。しかし,だからこそたちが悪い現象でもあります。VBでのコンパイルはかなり時間がかかるので,そういう意味でも,問題の同定の解消は大変でした。しかしまあ,そういうことが生じるのが,プログラミングの実際であり,そういう現象の同定を自分の「嗅覚」(のようなもの)を頼りに行って行くのが,(大変ではありますが,)ちょっとした推理小説なんかよりも,ずっと面白いプロセスでもあります。

    組み込まれるDLL,OCXは削減できないか(ver.0.2.7)

    よく観察してみると,実際には,GC/Winで使っていないOCXやDLLが組み込まれていることに気づきました。GC/Winで使うOCXから呼び出しているとか,VBランタイムで必要という可能性もありますが,どう考えてもそうでないものもありそうでした。そこで,まずVB環境の中で,削除可能なコンポーネントを探してみました。いくつかのものは削除できました。「後で使うかもしれないから」と入れておいたので入っていたわけです。セットアップウッザードを使ったら,またそれらも入っていましたが,項目から削除してみました。その結果,やく1MBのDLL/OCXを削除することができました。(それでも全体で圧縮した状態で4MB程度ありますが)


    残念ながら,一休み

    さて,まだまだ続きを作りたいのですが,他の仕事がたまってきてしまったので,ちょっと一休みです。うまくいけば11月中旬。へたをすると,12月までお預けかもしれません。この一カ月弱の間(集中した時間が取れたのは,週2日程度。その他の日は「ちょっとずつ」です。まあ,大学の教官が開発に取れる時間なんて,その程度ではないでしょうか。),VBでの開発を行ってきましたが,なるほど「RAD」の定番という感触です。次の「格闘」までのお預けは残念ですが,少し面白そうなことでも考えながら,他の仕事をこなすことにしたいと思います。


    と思いつつ,ついつい ver.0.2.8 を

    なんていうことを書いたら,次の仕事に頭が切り替わると思っていたのですが,だめですねえ。いつもそうなんだけど,プログラミングを本格的に始めると,作業をしていないときも,自然に何か考えているようで,いろいろなことを思いついてしまいます。そして,「もうちょっと,あれをやっておこう」なんていうことが,ついつい続いてしまいます。
    それに,今回は,公開講座の方で,「次回(11/8)までには,○○程度のところまでは持って行けるでしょう」なんて言ってしまったものだから,ついつい気になって。
    ということで,DOS版での基本的なことはある程度できるようにしたいという感じで,次のことを追加しました。
    まだ追加すべき機能としては,
    あたりが,DOS版と同じ程度のレベル(ver.1)に持って行くのに必要です。
    しかし,まあ,優先順位としては,上記のものがまず自分で使いたいものとして選択しました。
    上記の3つの作業も,簡単というわけではなく,どれもそれなりの工夫やデバックを伴う作業なのですが,大体やるべきことは分かっていることを,実際に「実施する」という感じの仕事でした。編集的な機能の実装というのは,そういうものかもしれません。

    セットアップ用のフロッピィディスクの作成

    ついでに行ったのが,これ。ネットワーク経由でのインストールには不要ですけど,これも必要に迫られて。というのが,明日からの授業で使おうと思ったときに,Win95マシンでありながら, Win3.1からの格上げマシンで,CD-ROMもないし,ネットワークにも繋がっていない。ということで,頼みの綱はFDのみだからです。これもセットアップウィザードを使う分には,非常に簡単に作れます。

    しばらくの間沈黙の秘密?

    上記までを書いてから,続きを書くまでの間に,約2週間が経ったでしょうか。「ついつい」なんて書いていましたが,その後「とうとう」作業を再開するまでに,あまり時間はかかりませんでした。上にも書いたように,「公開講座」がやってくるという状況と,その次の公開講座までは2週間しかないというタイムスケジュールと,11/22は最終回だから,それまでには,目標とするところまで到達しておきたい。そのときには,情報処理センターの機器でネットワーク対応の形で利用したい。しかし,センターの機器では,Netscapeなどは,ワークステーション経由(X サーバ)で使うことになっているので,Winアプリとの連動はできない。しかも,セルフメインテナンスシステムになっているので,自分でインストールできないから,もっと早く仕上げないといけない...などの理由で,「仕上げるまでの時間がないぞー」状態になったわけです。
    ということで,作業は結構しているんだけど,「ドキュメントまで書けない」という状態でした。また,一つには,VBでのプログラミングにも結構慣れてきたという面で,「最大の読者である自分自身」にとって,それほど刺激的な内容がなく,むしろ,「地道に作業を続ける」という状態であったことも一つの理由でしょう。
    しかし,こういうことは,本来はあまりいいことではありません。勢いに任せていろいろと作り上げたときは,その場でいろいろなノウハウを身に付けながら作業していますが,時間とともに,そういう知識は少しずつ忘れて行きます。後で改良したいと思ったときに,「えーっと,どういう事だったっけ」と,また一からやり直し。ときには,改悪することだってありえます。やはり,できることならば,コーディングとドキュメント作りはある程度並行して行うというのが,スジというものでしょう。

    さて,じゃあ,どうして今こうして書いているかというと,二つの理由があります。一つは,DOS版の機能の実装および,ネットワーク対応のために,しておきたいと思っていたことを一応実現したということです。ここらで,ちょっとまとめておこうかという気分になったといっていいでしょう。もう一つは,そのネットワーク対応のための工夫に関連して,一つトラブルが生じたことです。

    ネットワーク対応にしようと思って起きたトラブル

    まず,「ネットワーク対応」というのが,どういう意味かを明らかにしておく必要がありますが, それは別のところでまとめることにしましょう。 ここでは,どういうことをどうやると,どういうことが起こったかということを中心にまとめます。

    まず,Geometric Constructor / Win の中に,簡易ブラウザを組み込みました。これは,VBのアプリケーションウィザードで「インターネット」がどうのこうのという項目を選択すると,自動的に組み込まれるものをそのまま組み込むことにしました。
    そして,ソフトができました。その中では, WebBrowser コントロールを使っています。コンポーネントとしては, Microsoft Internet Controls (c:\windows\system\SHDOCVW.DLL)を使っています。
    そして,セットアップウィザードを使いました。すると,SHDOCVW.DLLの依存ファイルがないというメッセージが出ました。VBのマニュアルの中では,「依存ファイルは添付するように,強く推奨します」というようなことを言っている割には,自前のDLLでこんなことも起こるわけ?なんて思いつつ,そのまま進みました。
    出来上がったものを別のパソコンにインストールしました。しかし,SHDOCVW.DLLの何かがどうのこうのというメッセージが出て,起動できません。
    VBのアプリケーションウィザードで生成されるアプリでのブラウザは IE のサブセットのようなものだから, IE があれば動くかなと, Internet Explorer 3.02 をインストールしてみました。すると,Geometric Constructor / Win もうまく動作しました。

    何か変だなと思いました。次のようなことを思い出したり,してみたりしました。


    さて,では一体, SHDOCVW.DLLとは何者なのでしょう。そして,どうしてVB環境の中の標準的な機能である「アプリケーションウィザード」で普通に作ったアプリにそのようなDLLが使うことがありうるのでしょう。

    私は次のように解釈してみました。


    マシンのトラブル等で,長期休憩

    1998/1前後に発生した,HDのトラブルと予算の欠乏で,「げっ」。
    やはり,仕事で使う環境は,「壊れることがある」のを当然という形で,「まさかのときの対処」を確立しておく必要性を感じました。
    いずれにしても,そんな事情で,開発の方はストップした期間がちょっと続きました。

    コントロールのフォーカスを設定するのは,「load」ではなく,「activate」にて

    以前から,フォーム上のコントロールに対して,起動時のフォーカスを設定したいとおもいつ,setfocusを使うと実行時エラーが生じるということに悩まされ,使えないままでした。何かの記事や会話等からヒントを得て,「load」時では,まずいようだということを認識し,「activate」イベントに書いてみました。そしたら,問題は解消。
    なんだ,分かってみたら,そういう簡単なことだったわけね。

    tab index は便利

    ついでに,フォーム上で,タブキーを押したときのフォーカスの移動順序を変更しました。これは,実行時でも,デザイン時でも設定できるようです。
    書いてしまう方が速いようにも思いましたが,デザイン時のコントロールパネルで修正してみました。
    この機能も,なかなか便利です。

    自動組み込みするファイル群を設定するには,swtファイルを直接編集

    サンプルなど,セットアップ時に追加して組み込んでおきたいファイルは,swtファイル,つまり,テンプレートファイルを直接編集する方が,ウィザード内で行うよりも,簡単です。ウィザードでは,テンプレートファイル内にあるものは参照しないため,毎回すべてを設定しないといけませんから。
    詳しい文法は分からないけど,その前にウィザードが生成したファイルを参考に,ま,適当に直せば,それなりに動くというわけです。

    VBのセットアップを使うには,「同一名のファイルはだめ」

    ウィザードで設定すれば問題なくクリアしてくれるのかもしれません。上記のように,直接編集していたら,問題が発生しました。それは,
    組み込むファイルのディレクトリィ名が違っていても,ファイル名が同一だと,問題が生じる
    ということです。
    実際に問題になったのは,
    の3種類のファイルを組み込むように設定したのに,2つめ以降が組み込まれないということです。
    swtファイルをどう修正してもだめ。セットアップ用のディレクトリィを見ると,圧縮されたファイル名は,
    index.ht_
    ということで,同一名のものが3つあっても,やはり一つしかない。
    つまり,ウィザードを使えば回避するのかもしれないけど,手作業で適当にやるときには,おそらく,
    末尾以外の文字が一致するファイルが2つ以上あるとだめ
    ということではないかと思います。

    プログラムマネージャーなどの利用(shell, sendkey,..)とタイマーコントロールの利用

    VBマガジン(98-5)の付録「Visual Basic 101 Q & A」(日向俊二)を見ていたところ,「HTMLファイルの表示方法」というのがありました。
    その手の一つとして,「プログラムマネージャーを利用して,アプリケーションの関連づけがされているソフトでHTMLを呼び出す方法」がつかれわていました。つまり,
    shell ("programan" + File$)
    という感じです。ver.1.0.8 では,簡易ブラウザではなく,この方法を使うことによって,Netscape あるいは, IE でヘルプファイルを開くようにしてみました。

    解消された問題点

    新たに生じた問題点

    じつは,安易の解消方法として,「プログラムマネージャのみをその後閉じる」という手を考えた。そのためには, SendKeyによって,プログラムマネージャに「Alt + F4」を送ればいいはずだ。しかし,結果的にはうまくいかなかった。想像するに,片方でブラウザを起動させようとしているタイミングとあわないのではないかと思う。
    だから,一つの解消方法として,タイマーでSenkdKeyを使うタイミングを少し遅らせるということが考えられるのだが,今までタイマーを使ったことがなかったので,それあえず,ver.1.0.8では,その手は試さないままでいる。後日対策を考えるというところである。

    と書きながら,ついついそのままにするのはしのびなく,まずテストを行って,次にGC/Winの中でも,実装した。思ったよりも簡単に実装できた。要するに,Activateできる状態であれば,そのために,タイマーで多少の時間を稼ぐことができれば,処理することはできるということだ。

    今回,初めてタイマーコントロールを使ったのだが,なかなか面白い存在だ。あまり臆せず,機会を見つけて,活用してみよう。


    プログラムマネージャーなどの利用(shell)で生じた問題点とその解消
    (ファイル/パスのロングネーム)

    上記を GC/Win 1.1.0 で実装してみたところ,開発環境ではうまく動作したのに,それ以外でうまく動作しなかった。「ゲッ」ということになったのだが,結果的に,その原因は,shell つまりコマンドライン上でファイル/パスの名前に Prgram Files などのロングネームを使っていることが問題だということが判明した。
    VB環境の中で使う場合は問題ないのだが, shell 経由で行うから発生するわけだ。開発環境では,安全のために 8+3 以内にしているので,問題が生じていないということだった。

    ロングネームを使えるようにするための一つの常套手段は,ダブルクォーテーションで囲むということらしい。実行ファイル名はそれでうまくいった。そして,いろいろと試した結果,次のようなことが分かった。

    そこで,ロングネームはショートネーム(?)に変換して扱うようにした。汎用ルーチンを作ればよかったのだが,時間と余裕がないので,間に合わせのもので妥協した。まあ,いいでしょ。とりあえず動くんだから。


    WindowsAPI利用による上記の問題の解消

    上記のようにして対応してみたものの,結局「インストールした環境によってトラブルがある」ことがあった。「とりあえず動く」のはいいけれど,やっぱり「とりあえず」ということには変わりない。
    で,そんなことを頭の済に置きながら,あるとき VB Magazine (98 Summer別冊)を見ていたら,酒井氏の記事があった。「インチキ霊を呼び出そう : パソコン狐狗狸さん」という,いかにもふざけた記事である。タイトルはふざけているが,中身はなかなか渋い。けっこう「目からウロコ的」なTIPSが盛り込まれている。そして,その中の一つに「拡張子に関連づけられたプログラムを起動する方法」というのがあった。WindowsAPIのShellExecute関数を使うという手である。「やっぱりいい方法があるんじゃない」と,気分がすーっとして,定価の980円がとても安く感じられた。

    さて,早速,そのコードの一部を使って,あるHTMLファイルをブラウザで呼び出す試作版を作り,それが動作することを確認して, GC の機能として盛り込み, ver.1.1.2 とした次第である。


    直交座標/極座標の切り換え

    上記からかなり経過した。続きを書くのは久しぶりである。「テスト版」という名前に対して,「いつになったら完成するのか」という問い合わせをときどき頂いていた。ver.1.1.4になって,自分が要求することのかなりの部分が取り敢えず実現でき,あまりトラブルが生じていないので,個人的には,「ver.1.1.4 のままでいいかな」と思っていた。しかし,いい改善案があったときにはやはり前向きに対応する姿勢は継続するわけだし,テスト版→市販版という変化が必要なわけではないので,とりあえず,「テスト」という名前はそのままにしている。(しかし,ユーザーの方の印象としては,そろそろ削除した方がいいのかもしれない)
    さて, そんな思いでいたのだが,98/8/19-20の松江の講座の中で,東海南高校の斉藤先生から,「複素数平面の例を考えるときには,極座標の座標軸を表示した方がいいのではないか」という意見を頂いた。確かにそういう場合もあるかもしれない。しかも,大した作業ではないので,「ユーザーからの希望があってこそ,ソフトは成長する」のを,目の前で実感していただこうと,この機能を付け加えたものを,ver.1.1.5としてみた。
    このあたりの経緯は,こちらに書いている。


    ver.1.1.5 から B 版の廃止

    ver.1.1.4のときから,すでに簡易ブラウザは不要になっていたので,いずれ B版は廃止し,A版のみを残そうと思っていた。実際, こちらで問題にしていた SHDOCVW.DLL を使う必要がない。また,htmlファイルに関連づけられているブラウザを起動するので,機能的にもほとんど問題ない。


    げ。1.1.4にはなかったバグ。

    講座が終わってから,きがついたのですが,前にクリアしたはずと思っていたバグがありました。ver.1.1.4ではクリアされていて,1.1.5では関連するコードは一切触っていないのに...。どうしてだろう。
    悪夢を見た雰囲気のまま,修正した次第です。