あまつぶ

8.6 【Navigation Servicesとカスタムコントロール】

 組み合わせ、浜田高校は選抜準優勝の水戸商との対戦だそうな。試合は6日目の第4試合らしいからまだまだ先だけど。

 血液型の件については、教えていただいたページをいろいろと拝見させていただいたが、特にぼくに書けそうなことはなかったのでこの件はこれにて終了。気になる方は、集団遺伝学講座ABO FANを参照のこと(改めて情報ありがとうございます>杉崎さん)。

 QT-QのNavigation Servicesへの対応はなんとかうまくできた。OpenとSaveについてはほとんどそのまま使うだけだからたいしたことはなかったが、やはりカスタムコントロールの追加はなかなかややこしかった。
 Exportダイアログでは、「ファイルの種類」と「オプション」ボタンを追加したいが、最初、「ファイルの種類」についてはNavigation Servicesのポップアップメニューを使わせてもらえばいいかなと考えた。ポップアップメニューの拡張はIconPartyでやったことがあるからすぐにできたのだが、メニューを選んだ時に拡張子を変更したり「オプション」ボタンの更新をしたりするところではたと行き詰まってしまった。メニューを選択した時にはメニューに設定されているファイルタイプなどはわかるが、順番はわからない。オプションが使用できるかどうかなどのフラグは順番をもとに設定してあるからこれはちょっと使いづらい。また、NavPutFileを読んだ時に設定したファイルタイプのメニューもデフォルトで追加されてしまうからなんだか具合が悪い……。
 結局、「オプション」ボタンはカスタムコントロールで実現するしかないのだから両方ともカスタムコントロールでやることに決定。ドキュメントを読むとカスタム領域は横400ドット、縦40ドットが最小らしいから、Navigation Servicesのポップアップメニューとカスタムのボタンにするとデザイン的にもいまいちだということがわかった。

 カスタムコントロールを追加するためには、ポップアップメニューの拡張と同様、イベント処理関数を書いておかなくてはならない。そして、コントロールの追加などはすべて、そのイベント処理関数で行うらしい。NavPutFileを呼ぶ前に設定しておくのかと思ったらそうではないらしい。
 まず、カスタム領域を設定するためにkNavCBCustomizeメッセージに対応する必要がある。NavCBRec構造体のcustomRectパラメータにカスタム領域の左上が設定されているから、右下に適当な値を設定して戻る。すると領域確保が行われ、指定した領域が確保できれば終わり、できなければ確保できたRectが設定されてもう一度kNavCBCustomizeメッセージが送られてくる。これをくり返して、領域を確保する(ドキュメントにはあまり詳しく書かれていないが、最初に呼ばれた時には右下の点に{0,0}が設定されているらしい)。
 領域が確保されたら、次にkNavCBStartメッセージが送られてくる。これは「ダイアログが用意できたよ」という意味のもので、ここで'DITL'リソースなどを使用してカスタムコントロールを追加してやる。具体的な方法についてはドキュメントを参照のこと。
 カスタムコントロールを追加した場合には、ダイアログが閉じられる前にコントロールを破棄する必要がある。kNavCBTerminateメッセージが来た時に、'DITL'リソースやコントロールを破棄してやる。

 さて、これでコントロールを追加することができたが、追加しただけでは全く意味がない。コントロールが操作された時になにか処理を行うにはどうしたらいいんだろうか。
 それには、mouseDownイベントを調べて通常のダイアログと同様にFindDialogItem()でクリックされたダイアログをチェックする。通常のダイアログと異なるのは、自分で用意したアイテムだけでなく、Navigation Servicesが用意したアイテムもあるということ。自分で用意したアイテムが何番から始まっているのかを調べるにはNavCustomControl()にkNavCtlGetFirstControlIDメッセージを送る。ぼくのやった場合では、「10」という値が得られた。これに1を足した11番目からが、自分で追加したアイテムの番号になる。
 ここまでくればあとはたいしたことはない。FindDialogItem()がクリックされたアイテム番号から1を引いたものを返すことに注意して、通常のダイアログと同じような処理をしてやるだけ。ファイル名を変更したければNavCustomControl()にkNavCtlSetEditFileNameを、ファイル名を選択したい時はkNavCtlSelectEditFileNameを送ればいい。
 あ、そうだ。ここまでの処理で「ほぼ」ちゃんと動作してくれるのだが、ダイアログの大きさを変更した場合に自分で追加したアイテムが正しく再描画されないことがある。Jeditでも同じ症状が起こっていたのでおそらくNavigation Servicesのバグではないかと思うのだが、うち以外の環境でも再現するのかどうかは不明。とりあえず、updateEvtが来た時にダイアログ自身のアップデートであれば、DrawControls()を呼んでやることによって解決。なんだかややこしいが、仕方ない。

 こちらについてももう少し動作テストしてからリリースの予定。Phutの方は、パレットの色をいくつかのパターンから選択可能にするつもり。

to August 5, 1999 ↑ to August index → to August 11, 1999