PowerMops 5.6以降を前提として、メニューの作り方を紹介します。リソースと言っても、今では.nibのことになってしまいますが、ここでは、古典的なリソースフォークの場合と、XMLで書かれた.nibの場合の両方を含みます。準備するべきリソースファイル(パッケージ)が違うという点を除けば、"Create"のメッセージが違うだけで、あとは皆一緒です。
OS Xではクラシック環境がないとリソースフォークリソースをつくるのに、ちょっと面倒かもしれません。日本語対応ではないんですが、Rezillaというオープンソースかつ無料のCarbonリソースフォークエディタがあります。ResEditのようにGraphicalではない(多分、Resourcererがこんな感じ)ですが、なんとなく使い方は解ってきます。英語ですが、ヘルプがあります。有料なら、Resourcererはまだ発売されていると思います。もっと安いのや無料で、他にもあるかもしれません。開発環境をインストールしてあれば、Interface Builderでnibリソースを作ってください。ちなみに、XCodeをインストールするには1.5GBのHD空き容量が必要です。今どき小さいんですかね、これくらい??多分、Interface Builderだけインストールするって選択肢はないんじゃないかという気がしましたが、どうなんでしょう。OS 9、8.6ならもちろん、ResEditはもらっておきましょう。
できたリソースは、PowerMopsのアプリケーションファイルがあるフォルダにいれます。
さて、コードに移ります。まず、メニュークラスのオブジェクトを宣言します。宣言時に、項目数に対応する数値をスタックに置かなければなりません。4アイテムのメニューとすると、
4 MENU myMenu
となります。アイテム数には、区切り線も含まれます。ですから、普通の項目三つの途中に区切り線を一本入れたメニューも、アイテム数は四つになります。アイテム番号は、Carbon APIでは1番から始まりますが、Mopsオブジェクトでは0番から始まり、Mopsの0番がCarbonツールボックスの1番に当たるので、注意してください。
次に、メニューのIDと、各アイテムの動作を設定します。例えば、
xts{ word0 word1 null word3 } 128 init: myMenu
最初に、"xts{"と"}"で囲んで、メニューアイテムを選択したときの動作を定義しているワードの名前を書きます。左から、第0番アイテムを最初として、順にメニューの上から下へと、アクションを代入してくわけです。途中、"Word2"が抜けて"null"になっていますが、これは、ここが区切り線であると想定しています。区切り線の部分に動作を定義しても実行されることはありませんので、何もしないワード"null"をいれておくわけです。
次の"128"はリソースフォークメニューでは、メニューリソースのリソースIDになります。確か、0から32000位まで使っていいはずですが、普通のメニューは128あたりからその付近を使うことが多いような気がします。0とか1とかは、確か、Mopsが使っていますから、実際大体128くらいからがいいんじゃないかと思います。この番号は、メニューを特定するためのメニューIDとしても使われます。nibリソースの場合、リソースIDは関係なくて、リソースインスタンスの名前で特定するので、この番号にリソースを特定する意味はありませんが、メニューIDは必要です。リソースIDと同じような数値を、ここでメニューIDとしてアプリケーションの側から指定してやれば、アプリケーション毎に一意というメニュIDの条件も問題なくクリアできるので、コードは全く同じでいいと思います。
ここまでは、コードの地の部分に書いて、コンパイル時に実行しておいてもかまいません。スタンドアローンとしてインストールする場合でも、コンパイル時に初期化しておけば、ランタイムで実行するようにしておかなくても問題ありません。ランタイムで実行しても、もちろんかまいません。何かのワードの定義の中に書いておいて、スタートアップ時に実行されるワードから呼び出せば、ランタイムイニシャライゼーションになるわけです。
さて、メニューを生成します。これは、スタンドアローンアプリケーションにするなら、ランタイムで実行されるようにしないといけません。Mops環境上で実行するなら、別にどうでもいいことですが。リソースフォークリソースの場合と、nibリソースの場合で、少し手順が違います。
リソースフォークメニュー
リソースフォークの場合、Mops環境で実行する場合には、予め、リソースファイルをロードしておく必要があります。それには、"HOpenResFile()"というCarbon API関数を使います。デモアプリケーションの"grDemo"の終わりの方にある"GO"の定義を見ればやり方が解ります。
0 MopsRsrcDirID " リソースファイル名.rsrc" str255 0 HOpenResFile
です。戻り値としてこのリソースファイルのファイルレファレンスナンバーが残ります。途中で意図的にリソースファイルを閉じたいときには、この番号を変数に確保しておいて、これを使ってファイルを閉じますが、アプリケーション終了と同時に、それによって開かれたリソースファイルは自動的に閉じられるので、放っぽいて置いてかまいません。"grDemo"でも、dropで捨ててますね。引数は、初めがボリュームレファレンスナンバー。起動ディスクが0じゃないかと思います。で次はディレクトリIDですが、このワードはMops内に準備されてあります。次がファイル名の文字列で、それを関数の引数型にあわせるため、str255で、Pascalストリングにしてあります。最後の0がパーミッション。書き換えることがなければ、リードオンリーの"1"でもいいんですが、取りあえず、0でカレントパーミッションにしてあります。ファイルに設定されたパーミッションにあわせるということです。
ご承知のように、OS 9とコンパチブルなPEF/CFMのスタンドアロンのアプリケーションの場合、リソースフォークリソースは、アプリケーションファイルのリソースフォークに貼付けます。そうすれば起動時に自動的にロードしてくれるので、リソースファイルを自分で開いてロードする必要はありません。むしろ、リソースファイルを開こうとしても、発見できず、エラーを吐いてしまうだけに終わります。このために、Mopsは"instld?"という環境変数を準備しています。これは、Mops環境上ではfalse、インストールされたスタンドアロンアプリケーションではtrueになるので、これで条件づけると便利です。
メニューを生成するのは、"getNew:"です。
getNew: myMenu
まだ、メニューは表示されませんが、メニューオブジェクトはもう生成されています。隠れているに過ぎません。
NIBベースメニュー
nibリソースの場合、まず、リソースパッケージの名前を登録しておきます。"Main.nib"を使うと仮定して、
" Main" setNib: myMenu
とします。.nib拡張子は落とします。個々のリソースがその名前だけで(インスタンスレベルで)特定できるときには、このパッケージ名の登録は不要です。決まったサーチパスがあって、その中を適当に捜すようです。ただ、nibパッケージを複数作って、それぞれに含まれた同じ名前の個別リソースをアプリケーションが意図的に使い分けるということもでき、その場合にどのnibパッケージからとるのか特定するために、この登録があるというわけです。
メニューの生成は、"createFromNib:"にインスタンス名(メニューリソースの名前)を与えて行います。"File"という名前と仮定して、
" File" createFromNib: myMenu
となります。nibメニューの場合、デフォルトではこのインスタンス名がメニューバーに表示されるメニュータイトルになってしまいます。もしも、これと変えたい場合には、上のメッセージでメニューを生成した後、"setTitle:"でタイトルを付け替えてください。例えば、
" ファイル" setTitle: myMenu
Mopsウィンドウ上には日本語はうちにくいですね。できないことはないんですが。Quick Editだと、エディタ画面上では字は化けますが、プログラム的には大丈夫です。ちゃんと日本語環境なら日本語で表示されます。フローティングインプットウィンドウがでるので、Qucik Editからの方が、楽な感じがします。
なお、nibリソースは言語環境に合わせて自動的にメニューとかの言語を入れ替えてもらえるのが、一つの長所ですが、インスタンス名を引数にして生成しないといけないので、多分、このメニューのタイトルの部分をストリングリソースしにしておいて、環境によって別のを抜いてきて、CreateMenuFromNibに喰わせるのでしょう。やってみたことはありませんが。
さて、いずれのリソースについても、メニューは生成されています。次はこれを表示するのですが、一番便利なのは、多分、"insert:"です。
insert: myMenu
これを実行した瞬間、PowerMopsのメニューの右端に、もうひとつ新しいメニューが追加されていることでしょう。スタンドアロンアプリケーションでも、これをやっておけば、左から順(アプリケーション(Apple)メニューは除く)に詰めてならべてくれるので、便利です。
関連項目:
最終更新:2018年12月28日 19:23