apple.png

六色林檎のお部屋

Let's Enjoy Macintosh Lifeのページ

この文書はすでに歴史的なものになっているので役に立たないと思われるけれども記念に残しておく

Macintosh

レインボーアップルが白抜きになってしまった・・・
個人的にはやっぱり六色の方がいいと思う
アップル・ジャパンのホームページはこちら
Macintosh関連情報入手にはこっちもいいかも

The Macintosh C Programming with MPW

Macintosh C Programmingを勉強中。
MPWというすばらしいもののおかげでお金の問題は解決!
でもPowerBookのハードディスク容量も足りなくなってきた・・・
はたして作品を公開できるのか?!
(一応あるゲームを作ったのだが、どうしようか?)

About MPW...

MPW (Macintosh Programmer's Workshop) とは何か?
MPWは、Appleが提供する「無料」の開発環境です。
Macintoshの開発環境と言えばMetroWorksのCodeWarriorが主流ですが、結構お値段が張るので(アカデミック版は半額になりますがマニュアルがオンラインマニュアルのみです。)お遊びでプログラムをやるにはちょっと・・・と思う方々もいらっしゃるでしょう。そんな方々のためにあるのがMPWです。
注意:ソフト自身は無料とはいえ、20MB近いファイルをダウンロードするので電話代、接続料等がかなりかかります。
とはいえど、安かろう、悪かろうでは?? ご安心を、性能は高いのです(多分・・・)。が、CodeWarriorなどと違ってユーザーインターフェースがとっつきにくい形なのは確かです。UNIXのshellやWindowsのMS-DOSモードに近いものがあります(というより、もともとMPWもMS-DOSもUNIXのshellを参考につくられたものです)。しかし、Macintoshのソフトだけあってメニューバーやダイアログを使った入力も可能です。一方でエイリアスやスクリプトの使用等、UNIXのshellのようなことも可能です。
コンパイルできる言語はC, C++, Pascal, アセンブラです。

MPWでのプログラミングに必要なもの

最低限、以下の2つは必要です。
 MPW-GMはAppleのデベロッパー(:開発者のこと)向けのftpサイトにあります。ftpサイトの中の「MPW-GM_images」というディレクトリの中にあります。一ファイルにまとめられているものと、1MBずつに分割されているファイル(「Segmented-image」というディレクトリの中にあります)がありますのでダウンロード環境に応じていずれかを選んで下さい。また余裕がある方は「Documentation」ディレクトリの中にある「Introduction to MPW」と「Building_Progs_In_MPW」というPDFファイルもダウンロードしておくと良いでしょう。これらのPDFファイルを読むにはAdobe社のAcrobat Readerが必要です(あとは多少の英語力:そんなに難しい文章ではない)。
 ResEditはAppleの普通の ftpサイトにあります。どちらもDiskCopyというソフトで圧縮されているので展開にもそのソフトが必要になります。これもAppleの普通のftpサイトにあります(なお、MacOS 8.1のインストールCDの中にも入っていました)。ダウンロードしたファイルはまず Stufflt Expanderで展開して、次にDiskCopyで展開します。すると「ディスクイメージ」が作成されるので、これの中身をハードディスクに用意した新規フォルダに全部コピーすればOKです。
 なお、MPW-GMのとなりにMPW-PRというのがありますが、こちらはMPW-GMをアップデートするためのものです。このアップデートの方法は「Introduction to MPW」に書かれています。(GMはGolden Masterの略、PRはPreReleaseの略です。)

Hello, MPW World !!

 とりあえず、お決まりのプログラム(Hello World)の作り方です。これをやってみれば一応MPWの使い方のアウトラインが分かるでしょう。最初に書いたとおり、ここではC言語を使用します。C言語についてお勉強したい方は、いろいろ書籍がでていますのでそちらをあたると良いでしょう。
1. まず、プログラム用にフォルダを一つ作っておきます。
2. MPWの中の「MPW Shell」を起動します。
3. はじめて起動すると、Helpの出し方が延々と書かれているWorkSheetが開くと思います。このWorkSheetがコンパイルなどの命令を入力し、その結果が出力されるウィンドウです。
4. 重要:MPW Shellは「Returnキー」と「Enterキー」を区別します。「Returnキー」は単純に改行するだけです。「Enterキー」は入力された文字列をShellへの命令と認識して実行します。(なお、Optionキーを押しながらReturnキーを押す = Enterキーを押す)
5. Helpの出し方はとりあえずいらないので「コマンド+A(またはEditメニューからSelect All)」「DELキー(またはEditメニューからClear)」で消してしまっても良いでしょう。また見たくなったら「Help」と入力し、「Enterキー」を押せば同じものが表示されます。
6. さて、はじめにすることは作業ディレクトリの設定です。「Directoryメニュー」から「Set Directory」を選びます。するとフォルダを選択するダイアログが出るので1. で作成したフォルダを選択し、Directoryボタンをクリックします。(なお、ソースファイルをダブルクリックしてMPW Shellを起動した場合には、ディレクトリは自動的にそのソースファイルのあるフォルダにセットされます。)
7. 次に「コマンド+N(またはFileメニューからNew)」を入力します。ファイル名はHello.cとします。すると新しいウィンドウが開きます。これがソース入力用のウィンドウです。他のテキストエディタ(Simple Text等)でソースを書いておき、それを読み出すことも可能です。この場合は「コマンド+O(またはFileメニューからOpen)」を入力し、そのファイルを開きます。
8. 次のソースを入力します。(注意:記号\はMPW Shellで入力するとバックスラッシュ=右下がりの斜線で表示されます。)
#include<stdio.h>
void main()
{
printf("Hello, MPW World !! \n");
}
9. 入力を終えたら保存します。「コマンド+S(またはFileメニューからSave)」を入力します。
10. 続いてMakeFile(コンパイルの条件等を記述してあるファイル)を作成します。「BuildメニューからCreate Build Command」を選びます。そして、ダイアログに次のものを入力していきます。
 これでMakeFileがつくられます。ファイル名はHello.make(ダイアログで入力したProgram Name+.makeになります)です。
11. いよいよコンパイルです。「コマンド+B(またはBuildメニューからBuild)」を入力します。作成するプログラム名を聞いてくるのでHello(10.のダイアログで入力したProgram Name)と入力します。
12. 無事コンパイルが終了すればHelloというアプリケーションができているはずなので、実行すると良いでしょう。コンパイルエラーが出た場合はMPWのフォルダが正しくインストールされているか、作業用Directoryが正しく設定されているか、プログラムが間違いなく入力されているかをチェックして下さい。(なお68KではFile was not needed for linkという警告が出ますが気にしなくてもよいです。)
おまけ:アップルメニューからAbout MPW...を選んでみましょう。感動もの・・・

ToolBox

 さて、とりあえずコンパイルはできるようになったけれども、普通のMacintoshのソフトとは大分違う(まるでテキストエディタのような)ものができてしまいました。これでは市販されているような、いかにもMacintoshっぽいアプリケーションを作るにはちょっと無理がありそうです。「Macintoshっぽいアプリケーション」をつくるにはどうしたらよいのでしょう?
 普通の「Macintoshっぽいアプリケーション」が(目や耳に感じられる範囲内で)どんなものから構成されているかを考えてみますと、次のようなものが挙がると思います。
 しかし、これらを管理するプログラムを一から作るのは並大抵の労力ではありません。
 例えばウィンドウに限っても、ウィンドウのどこにクローズボックスがあるのか、サイズボックスがあるのか、スクロールバーがあるのか、ウィンドウには何が描かれているのか、それぞれをクリックしたら何が起きるか、ドラッグしたらどうなるか、サイズボックスでウィンドウのサイズを変えるなら画面の大きさより大きくなったり、作業できないほど小さくなったりしてはいけないし、そのためには今のウィンドウの大きさを常に管理しなければならないし、他のアプリケーションのウィンドウがクリックされたらどうするか、といったようにです。
 また、それぞれのプログラマーによって違うものが作られてしまっては、使う側には不便です(たとえば作ったプログラマーによってクローズボックスの位置が右上だったり左下だったり、メニューバーが左にあったり下にあったり)。アプリケーションがどれも同じような操作で使えるというのがMacintoshの魅力でもあるわけですから。
 そこでAppleはこれらの管理を行うためのルーチンを(Macintosh内部のROMとして)提供しており、それを使用することを推奨しています。これがMacintosh User Interface ToolBox(普通は略して単にToolBox)というものです。そしてFinderをはじめとするアプリケーションは実際にToolBoxを使用してウィンドウを開いたり、メニューバーを管理したりしているわけです。
 ToolBox には数千のルーチンがあります。これらはInside Macintoshという本またはCD-ROMに解説されています(一部はアップルのサイト上にもあります:英語ですが)。が、はじめからこれに手を出すのは極めて無謀ですので、まずは書籍等を参考にすることをお勧めします。(このページでもある程度は解説する予定ではありますが・・・)

リソースエディタ ResEdit

 リソースとは先に挙げたウィンドウ、グラフィック、アイコン、ダイアログ、メニューバー、サウンドなどといったユーザーインターフェースを構成するものをリソースと言います。ToolBoxを使う場合に避けられないのがリソースの作成・編集です。そしてリソースの作成・編集を行うためのアプリケーションがResEditです。アピアランス機能拡張をResEditで編集してゴミ箱の絵柄を変えたりする人もいます(私もその一人ですが)。また英語ソフトの文字列リソースを翻訳した日本語に置き換えることで日本語化したりすることもできます(実際はそんなに簡単な話でもないが)。まあ、そういうふうにアプリケーションの外観を作成・修正するのがResEditです。

Macintoshっぽいアプリケーションの作成

 さて、Macintosh Programmingの本題はここからです。結局のところMacintoshの アプリケーションの中身は次のようなものになります。
 一応補足しておきますと、用意したリソースを呼び出すのにもリソースを呼び出すためのToolBoxルーチンを呼び出します。マウスのクリックがあったかどうかを確認するのにもToolBoxルーチンを呼び出します。結局、あらゆることにToolBoxが使われるわけです。
 また、リソースとプログラムは独立に作成することができます。つまりリソースを全く作らないで、プログラムだけを先に完成させたり、その逆が可能です。ただし、プログラムから呼び出したリソースが存在していない場合、プログラムは実行してもクラッシュしてしまうので注意が必要です。

MacintoshっぽいHello, World !

 今度もHello, Worldですが、前回のようにMPWが提供してくれるSIOWは使用しません。つまり我々が独自にウィンドウを用意し、そこにHello, Worldを書き込みます。また、このウィンドウの表示と消去はマウスクリックを合図にします。プログラムは次のようになります。
 また、使用されるリソースとしてウィンドウ1つとHello, Worldの文字列を用意する必要があります。

リソースの準備

 必要なリソースが明らかなので先にこちらを作ってしまいます。
1. まず、プログラム用にフォルダを一つ作っておきます。
2. 「ResEdit」を起動します。
3. びっくり箱(?)ピエロの起動画面が表示されます。クリックするとこれは消え、自動的にファイルを開くダイアログが立ち上がります。
4. ここでNewボタンを選んで、先ほど作ったフォルダの中にMacHello.rsrcを作成します。(.rsrcはこれがリソースファイルであることを明示する拡張子です。)するとMacHello.rsrcという名前のウィンドウが開きます。
5. まず最初に「ResourceメニューからCreate New Resource(またはコマンドキー+K)」を選びます。ダイアログが表示されるのでResource Typeの中から「WIND」を選択します。(直接入力しても可。ただし必ず大文字で。)WINDはウィンドウの情報を持つResource Typeです。
6.するとウィンドウについて設定するウィンドウが2つ(WINDs from MacHello.rsrcとWIND ID=128 from MacHello.rsrc)開くのでWIND ID=128 from MacHello.rsrcウィンドウで設定を行います。
7. 設定が終わったらWIND ID=128 from MacHello.rsrcウィンドウを閉じます。もう1つのWINDs from MacHello.rsrcウィンドウを見るとID 128番のリソースができていることが分かります。一般にIDは128から順番に大きくなるようにつけていきます。なお、特別な用途であることを明示したいなどでIDを変えたりコメントを入れたい場合、そのリソースIDを選択した(反転表示)状態で「ResourceメニューからGet Resource Info」を選びます。するとIDとリソース名の設定ができます。
8. WINDs from MacHello.rsrcウィンドウを閉じます。次に4.で開いたMacHello.rsrcウィンドウを最前面(アクティブ)にします。WINDとwctbの2つのリソースが表示されているはずです。
9. 「ResourceメニューからCreate New Resource(またはコマンドキー+K)」を選びます。ダイアログが表示されるのでResource Typeの中から「STR#」を選択します。(直接入力しても可。ただし必ず大文字で。)STR#は文字列の情報を持つResource Typeです。
10.すると文字列について設定するウィンドウが2つ(STR#s from MacHello.rsrcとSTR# ID=128 from MacHello.rsrc)開くのでSTR# ID=128 from MacHello.rsrcウィンドウで設定を行います。
11. 設定が終わったらSTR# ID=128 from MacHello.rsrcウィンドウとSTR#s from MacHello.rsrcウィンドウを閉じます。次に4.で開いたMacHello.rsrcウィンドウを最前面(アクティブ)にします。STR#リソースが加わったはずです。
12. さらにもう一度だけ「ResourceメニューからCreate New Resource(またはコマンドキー+K)」を選びます。ダイアログが表示されるのでResource Typeの中から「SIZE」を選択します。(直接入力しても可。ただし必ず大文字で。)SIZEはプログラムの大きさの情報を持つResource Typeです。(Finderの情報を見るコマンドで表示される、最小サイズと推奨サイズを設定します。)
13.すると設定するウィンドウが2つ(SIZEs from MacHello.rsrcとSIZE ID=128 from MacHello.rsrc)開くのでSIZE ID=128 from MacHello.rsrcウィンドウで設定を行います。
15. 設定が終わったらSIZE ID=128 from MacHello.rsrcウィンドウを閉じます。次にSIZEs from MacHello.rsrcウィンドウでID=128の今作ったリソースを選んだ(反転表示)状態で「ResourceメニューからGet Resource Info」を選びます。そして表示されたウィンドウでIDを128から-1に変更して下さい。これは最小サイズ等を設定しているリソースはID=-1でなくてはならないためです。
16. SIZEs from MacHello.rsrcウィンドウを閉じます。次に「FileメニューからSave(またはコマンドキー+S)」を選んで保存します。
以上でリソースの設定は終わりです。なお、手順12-15(SIZEリソースの設定)はやらなくてもプログラムは動くのですが、Finderから情報を見るコマンドでアプリケーションの使用メモりの大きさの設定ができなくなってしまいます。

Program of MacHello

次が、プログラムソースです。
1. MPW Shellを起動します。
2. 作業ディレクトリをMacHello.rsrcの入っているフォルダに設定します。(「Directoryメニュー」から「Set Directory」を選んで設定します。)
3. ファイル名MacHello.cで新規ソースファイルを作成します。(「Fileメニュー」から「New」を選ぶ。)
4. 以下のソースを入力して保存します。(長い)
#include<MacWindows.h>
#include<Dialogs.h>
#include<Strings.h>
#include<Fonts.h>

#define REMOVE_EVENTS 0
#define SLEEP_TICKS 0L
#define MOUSE_REGION 0L
#define WINDOW_ID 128
#define IN_FRONT (WindowPtr)-1L
#define STR_ID 128
#define HELLO_STR_ID 1

void init_toolbox( void );
void wait_mouse_click( void );
void draw_window( void );

QDGlobals qd;
WindowPtr one_window;
EventRecord one_event;

void main()
{
init_toolbox();

one_window = GetNewCWindow ( WINDOW_ID, nil, IN_FRONT );

wait_mouse_click();
draw_window();
wait_mouse_click();
DisposeWindow( one_window );
}

void init_toolbox()
{
InitGraf( &qd.thePort );
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs( nil );
FlushEvents( everyEvent, REMOVE_EVENTS );
InitCursor();
}

void wait_mouse_click()
{
Boolean proceed;

proceed = false;
while(proceed == false)
{
WaitNextEvent( everyEvent, &one_event, SLEEP_TICKS, MOUSE_REGION );

if( one_event.what == mouseDown )
proceed = true;
}
}

void draw_window()
{
Str255 hello_str;

SetPort( one_window );
ShowWindow( one_window );
GetIndString ( hello_str, STR_ID, HELLO_STR_ID );
MoveTo (30,30);
DrawString ( hello_str );
}

コンパイル

1. まずリソースファイルをMPWが理解できる形に翻訳します。これはリソースファイルを更新するたびに行う必要があります。「DeRez MacHello.rsrc > MacHello.r」と入力し、「enterキー」を押します。(もしくは「DeRez」と入力し、「optionキー+enterキー」を押しダイアログを表示させて、そこでDecompileファイル名とOutputファイル名を設定する方法もあります。)
2. 次にMakeFileを作成します。「BuildメニューからCreate Build Command」を選びます。そして、ダイアログに次のものを入力していきます。
 これでMakeFileがつくられます。ファイル名はMacHello.make(ダイアログで入力したProgram Name+.makeになります)です。
3. いよいよコンパイルです。「コマンド+B(またはBuildメニューからBuild)」を入力します。作成するプログラム名を聞いてくるのでMacHelloと入力します。
これでコンパイルされるはずです。68KではFile was not needed for linkという警告が出ますが気にしなくてもよいです。
注:実行すると、まずマウスクリックを待っているのですが、ここでデスクトップや他のアプリケーションのウィンドウをクリックしてしまうと制御が他のアプリケーションにうつってしまいます(メニューバー上とかでクリックすれば大丈夫)。その場合はアプリケーションメニューからMacHelloを選んで制御を戻してやって下さい。

ソースコード解説

#include
 MPWではすべてのヘッダファイルを明示的にincludeしなければなりません。プリコンパイラヘッダを作成する方法もあるのですが、いまいちどこのファイルを取り込めばいいのかよく分からないというのもあってまだやっていません。
#define
 ここでは種々のToolBox関数が使用する定数とリソースのIDを定義しています。
init_toolbox();
 ToolBox関数を初期化します。ToolBoxを使用するプログラムには、このルーチンが必要です。関数の呼び出しもここに書かれている順番で行う必要があります。nil, everyEventは定数としてヘッダファイルの中で定義されています。QDGlobal型(これもヘッダファイルの中で定義されています)この型も構造体qdはQuickDrawからdefaultの定数が渡されてきます。なお、nilは0を指すポインタで、普通C言語ではNULLと記述されます(これはMacintoshの開発言語がPascalだったことの名残です。NULLも使用できます。)。
one_window = GetNewCWindow ( WINDOW_ID, nil, IN_FRONT );
 GetNewCWindow()はWINDOW_IDのIDを持つWINDリソース(とwctbリソース)を(まだ読み出されていなければ)読み出して、そのデータを保持する WindowPeek型構造体を作成します。そしてその構造体へのポインタをone_windowに格納します。なお、第2引数はこの構造体のメモリ上での作成位置を指定するものですが、ここではnilを渡してMacintoshにその位置の指定を任せます。また第3引数はその作成したウィンドウを最前面に置くかどうかを指定するもので、IN_FRONT=(WindowPtr)-1Lなら最前面へ、(WindowPtr)0Lなら最前面以外に置かれます。なお、GetNewCWindow()はWINDリソースが最初から見えるように指定してある場合には表示も行います。
wait_mouse_click();
 マウスクリックがあるまで何もしないで待ち続ける関数です。核になる関数が
WaitNextEvent( everyEvent, &one_event, SLEEP_TICKS, MOUSE_REGION );です。この関数はイベントが起こったかどうかを調べるためのものです。第1引数は調べるイベントの種類でここではeveryEventです(なお、起こったイベントの種類が第1引数と一致すると返値がtrueになります。)。第2引数はEventRecord型構造体で、ここにどんなイベントがいつどこで起こったのかが格納されます。第3因数はWaitNextEvent実行時にどれだけバックグラウンドで他のアプリケーションを実行する時間を確保するかを1/60秒単位で指定します。ここでは0Lなので必要最小限ということになります。第4引数はある画面領域を指定しそこからマウスポインタ出た場合にイベントを発生させるというものですが、通常は特に領域指定しませんので、0Lを与えます。なお、定数 everyEventと型宣言EventRecordはヘッダファイルの中で定義されています
if( one_event.what == mouseDown )で構造体 one_eventの要素whatにマウスボタンが押されたイベントが入っていたらブール代数型の変数proceedをtrueにしてループを抜けます。なお、型宣言Booleanや定数true、falseはヘッダファイルで定義されています。
draw_window();
まず、Str255 hello_str(これはヘッダファイルでの定義によりchar hello_str[256]と等価です。)でウィンドウに書く文字列用の配列を確保します。
次にSetPort( one_window )で猫画するウィンドウを先にGetNewCWindowで呼び出したウィンドウに指定します。さらにShowWindow( one_window );で今まで見えなかったウィンドウを表示します。GetIndString ( hello_str, STR_ID, HELLO_STR_ID );は配列hello_strにIDがSTR_IDのSTR#リソースの中のHELLO_STR_ID番目の文字列をコピーします。MoveTo (30,30);はウィンドウでの猫画位置をウィンドウの左上角から左から30ピクセル、上から30ピクセルの位置に移動します。DrawString ( hello_str );は先ほど移動した猫画位置からhello_strに格納されている文字列を猫画します。
DisposeWindow( one_window );
DisposeWindow()はGetNewCWindowで確保したウィンドウを閉じ、その情報を解放します。

より詳しい情報が得られるサイトへのリンク