MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

プログラマーに興味がある方なら誰でも入会いただけます。
MOSA Multi-OS Software Artists
===SINCE 1995===

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSADenバックナンバー 2004年5月発行分

  • MOSA Developer News[MOSADeN=モサ伝]第114号

    2004-05-25

    目次

    • Cocoaでいこう! Macらしく  第51回  Yoshiki(DreamField)
    • 小池邦人の「Carbon API 徒然草」
    • 「Behind the WebObjects」  第20回  田畑 英和
    • ニュース・解説
    • MOSAからのお知らせ

    Cocoaでいこう! Macらしく  第51回 Yoshiki(DreamField)

    First Responder(後編)

    前回は、「Show Info」メニューがAppControllerに投げていたアクションメッセージを、 First Responder に投げるようにnibファイルを変更しました。でも、動作は変わりませんでした。これは何故でしょうか。
     実は、First Responderに投げたメッセージは、ある順番に従って、そのメッセージを受け付けるオブジェクトが見つかるまで、様々なオブジェクトにメッセージを投げて行くのです。Cocoa Document-Based Applicationの場合、その順番は次の通りです。

    (1)キーウィンドウの選択されているビュー
    (2)(1)のsuperビュー(これはキーウィンドウになるまで繰り返す)
    (3)キーウィンドウ
    (4)キーウィンドウのdelegate
    (5)キーウィンドウのNSWindowController
    (6)メインウィンドウの選択されているビュー
    (7)(6)のsuperビュー(これはメインウィンドウになるまで繰り返す)
    (8)メインウィンドウ
    (9)メインウィンドウのdelegate
    (10)メインウィンドウのNSWindowController
    (11)NSDocument
    (12)NSApplication
    (13)NSApplicationのdelegate
    (14)NSDocumentController

     キーウィンドウというのは、現在選択されているウィンドウのことです。メインウィンドウというのは、現在選択されているドキュメントのウィンドウのことです。あるドキュメントのウィンドウを選択した場合は、キーウィンドウとメインウィンドウは同じですが、パネルを選択した場合は、キーウィンドウはパネルになり、メインウィンドウはそれまで選択していたドキュメントのウィンドウになります(パネルはメインウィンドウになれません)。上記の順番で受け付けるオブジェクトが見つかるまで、メッセージが投げられますので、メニューは適切なオブジェクトに対してメッセージを投げることができるというわけです。もちろん、メニュー以外がこの仕組みを使ってもかまいません。今回の「Show Info」メニューの場合は、showInfoPanel:メッセージを順番に投げて行き、NSApplicationのdelegateであるAppControllerにたどり着いた時受け付けられ、showInfoPanel:メソッドが実行されたというわけです。つまり、AppControllerに直接メッセージを投げたのと同じ動作になったのです。
     このShow Infoの例では、First Responderのメリットは、あまり見えないかもしれません。ですが、Copy、Paste等、選択しているビューに作用しなければならないメニューや、Save、Close等、選択しているウィンドウやそのドキュメントに対して作用しなければならないメニューの場合はどうでしょうか。この場合は、MainMenu.nibの中にはそのオブジェクトが無いので、直接接続することはできませんし、何よりその時々の状況に応じて投げるべき相手のオブジェクトが変化してしまいます。これを管理するのはとても面倒なことです。ですが、CocoaではFirst Responderに投げるだけで良いのです。これは非常に優れた仕組みだと思います。
     First Responderについては、次の本が詳しいです。もっと詳しく知りたい方は、一読することをお勧めです。

    Mac OS X Cocoa プログラミング
    アーロン・ヒレガス(著)
    村上雅章(訳)
    ピアソン・エデュケーション
    ISBN4-89471-440-X

    画像を拡大するモードを付けよう(その1)

     今回説明したFirst Responderの応用として、各ウィンドウの表示に作用するようなものを実装してみましょう。内容は、メニューから画像の表示サイズを、x0.5、x1、x2から選べるようにすることとします。なお、この値は横幅や縦幅に対する掛け算としますので、面積比で言えば1/4、1、4です。
     それでは、まずはメニューを作りましょう。メニューの実装は第41回でやっていますが、今回は既にあるプルダウンメニューに付加するのではなく、新たにプルダウンメニューを増やします。とは言え、やり方は想像がつくと思います。いつも通り、TinyViewのプロジェクトを開き、MainMenu.nibをInterface Builderで開いてください。パレットウィンドウから「Submenu」を選び、「Edit」メニューと「Windows」メニューの間にドラッグ&ドロップします(fig.01)。すると、メニューバーに「Submenu」が追加されます(fig.02)。このプルダウンメニューのタイトルを「View」とし、Itemを追加してそれぞれのタイトルを「x0.5」、「x1」、「x2」として下さい(fig.03)。itemの追加方法やタイトルの変更方法を忘れてしまった方は、第41回を見てください。さらに、infoパネルを開き、「x0.5」、「x1」、「x2」の各メニューアイテムのTagを、それぞれ0、1、2として下さい(fig.04)。これでメニューは出来ましたので、一度ビルドして実行してみましょう。まだ、メニューは選べません。続きは、次回です。

    [fig.01] 「Submenu」を「Edit」と「Windows」の間にドラッグ&ドロップ
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/51/images/fig01.jpg

    [fig.02] メニューバーに「Submenu」が追加される
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/51/images/fig02.jpg

    [fig.03] 「Submenu」の内容を変更する
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/51/images/fig03.jpg

    [fig.04] infoパネルから各メニューのTagの値を変更する
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/51/images/fig04.gif

    小池邦人の「Carbon API 徒然草」(2004/05/21)

    Apple Eventとドキュメントアイコン

    今回はApple Eventの話の続きです。前回紹介したmyOpenApp()とは別のもうひとつのイベントハンドラ、myOpenDoc()を解説したいと思います。

    AEInstallEventHandler()にパラメータとしてkAEOpenApplicationを指定し、Finderでドキュメントがダブルクリックされた時に呼ばれるイベントハンドラ、myOpenDoc()をインストールします。このハンドラは、Finder上でドキュメントアイコンを選択し、ファイルメニューから「開く」を選んだ時や、アプリケーションアイコン上にドキュメントアイコンをドロップした場合にも呼ばれます。また、Dock上でドキュメントアイコンがクリックされた時にも呼ばれます。

    以下が、ドキュメントオープン用イベントハンドラであるmyOpenDoc()ルーチンです。実際にその処理を実装する場合には、このハンドラが呼ばれるのは「アプリケーション起動時とはかぎらない」という点に注意しておいてください。

    pascal OSErr myOpenDoc( const AppleEvent *event,AppleEvent *reply,long refcon )
    {
        WindowRef    wptr1,wptr=NULL;
        FSSpec       fsc,fsc1; // ドキュメントファイル保存場所はFSSpecで得られる
        long         len,i,ct;
        AEDescList   dolist;  // Eventパラメータのリストが入る
        short        ret=0;
        DescType     rtype;
        OSType       type;
        FInfo        info;      // Finderが保持するファイル情報が入る
        AEKeyword    key;
    
        if( ! AEGetParamDesc( event,keyDirectObject,typeAEList,&dolist ) )
           // Eventパラメータのリストがあるかどうか調べる?
        {
            AECountItems( &dolist,&ct );  // 受け取るパラメータの個数を調べる
            for( i=1;i<=ct;i++ )
            {
                if( ! AEGetNthPtr( &dolist,i,typeFSS,&key,&rtype,(Ptr)&fsc,
                                                    (long)sizeof(FSSpec),&len ) )
                   // Eventパラメータから対象ファイル(フォルダ)のFSSpecを得る
                {
                    FSpGetFInfo( &fsc,&info ); // 対象となるファイル情報を得る
                    type=info.fdType;          // ドキュメントタイプを調べる
                    if( type==MY_DOC )         // これは私のドキュメントだ!
                    {
                        if( ret=openCatalogWindow( &fsc,&wptr1 ) ) // 新規オープン
                            break;
                    }
                    else                       // これは画像ファイルかフォルダだ!
                    {
                        if( ! wptr ) // もしカタログウィンドウが開いてなければ...
                        {
                            if( ret=newCatalogWindow( &wptr ) ) // 先んじてオープン
                                break;
                        }
                        navCheckImportExtention( fsc.name,&type ); // 拡張子を調べる
                        if( ! navImportCheckTypeList( type ) ) // 表示可能な画像か?
                        {
                            if( ! addImageFile( wptr,1,&type,&fsc ) ) //カタログ登録
                                ret=0;
                        }
                        else // ファイルでなければ対象はフォルダと判断する
                        {
                            getFolderFSSpec( &fsc,&fsc1 ); // フォルダのFSSpecを得る
                            ret=addImageFolder( wptr,&fsc1 ); // フォルダ内容を登録
                            break;
                        }
                    }
                }
            }
            AEDisposeDesc( &dolist ); // Eventパラメータリストを削除する
        }
        return( ret );
    }
    

    まずは、AEGetParamDesc()によりApple Eventに添付されている情報(AEDescList)を入手します。オープンを要求されているドキュメントは一度にひとつとはかぎりません。複数の情報がある場合には、それらはリスト形式にまとめられて送られて来ます。続いて、AECountItems()で添付情報がいくつあるかを調べ、その個数を得たら、forループを使いAEGetNthPtr()でリストから順次個別情報を抽出します。Finderから送られてきたドキュメントに関する情報は、ファイルの保存場所を示すFSSpec構造体そのものです。FSSpec構造体の詳しい内容についてはFiles.hを参照してください。

    FSSpecが入手できたら、FSpGetFInfo()でファイル情報を得て、先んじてそのファイルタイプを調べます。その後、タイプの種類により以下の3つの処理に分岐させます。

    (1)ファイルタイプがアプリケーションのドキュメントならばそれをオープンする
    (2)ファイルタイプがリストに登録可能な画像ファイルならばカタログに登録する
    (3)それ以外はフォルダがドロップされたと判断し内部ファイルをすべて登録する

    最初にファイルタイプと比較しているMY_DOCは、MOSA.hで'MosD'と定義されています。もしこれであれば、本アプリケーションが保存するドキュメントファイルです。よって、カタログウィンドウをオープンし、そこへファイルを読み込みます。それ以外であれば、対象は画像ファイルかフォルダと推測できます。よって、newCatalogWindow()により新規ウィンドウを開き、ファイル登録の準備をします。ちなみに、すでに開いているカタログウィンドウにファイルを登録したい場合には、ハンドラの処理内容を少し変更する必要があります(チャレンジしてみてください)。

    続いて、navCheckImportExtention()ルーチンにより、ファイル名の拡張子からファイルタイプ推測します。これは、そのタイプを拡張子からしか判断できないファイルが、Mac OS X環境では多数存在するためです(ファイルタイプには「ゼロ」が代入されてる)。次のnavImportCheckTypeList()では、その画像ファイルがQuickTimeのAPIでオープン(表示)可能なタイプかどうかを判断しています。できるのであれば、addImageFile()により、それを新規カタログウィンドウへ登録します。

    それ以外のファイルタイプであれば、対象は「フォルダ」だと判断し(ちょっと手抜きなのですが...)getFolderFSSpec()でフォルダ自身のFSSpecを得てから、addImageFolder()により、その内部に保存されているすべての画像ファイルをカタログウィンドウへと登録しています。addImageFile()やaddImageFolder()に加え、navCheckImportExtention()、navImportCheckTypeList()、getFolderFSSpec()などは、本連載で順次解説していく予定の自作ルーチンです。最後に入手した添付リスト情報(AEDescList)をAEDisposeDesc()により削除し、ハンドラでの作業はすべて終了します。

    Mac OS 9のFinderでは、ドキュメントアイコンを選択しファイルメニューから「プリント」を選ぶと、対応するアプリケーションが起動しそれを印刷できました。加えて、アイコンをデスクトッププリンタへドロップしても印刷が可能でした。これらもApple Eventで実現されている機能のひとつです。対応させるためには、AEInstallEventHandler()にkAEPrintDocumentsを渡し、myPrintDoc()などと名付けたイベントハンドラをインストールしておきます。この時のハンドラ側の処理は、ファイル情報を受け取り指定ドキュメントを印刷した後に、アプリ自身を終了させることです。しかし何故か、Mac OS XのFinderからこの機能が外されてしまいました。この機能を使うユーザや対応アプリケーションが少なかったからでしょうか? ついでに(関係ないと思うが)Finderのウィンドウ印刷ができなくなったのも大変不便です(笑)。はてさて、将来的には元に戻る可能性はあるのでしょうか?

    次回は、オープン可能なファイルをFinderに認識させるために行うアプリケーション側の手続きについてお話します。具体的には、アプリケーションパッケージのContentsフォルダに保存しておく「Info.plist」についての解説となります。

    つづく

    「Behind the WebObjects」  第20回  田畑 英和

     これまでDirectActionの解説をしてきましたが、今回からは話題を変えてみたいと思います。Project WONDERというWebObjects関連のオープンソースプロジェクトがありますが、これからしばらくこのProject WONDERについてご紹介していきます。

    まずProject WONDERとはそもそもなんであるかですが、これはWebObjects向けに開発がおこなわれているオープンソースプロジェクトです。SourceForge上で運営がおこなわれていまして、URLは以下のとおりです。

    ・Project WONDER SourceForge URL
    http://wonder.sourceforge.net/
    http://sourceforge.net/projects/wonder

     ここの説明によりますと、Project WONDERのWONDERはWebObjects Nodes for Distributing E-Resourcesの略ということになっていますが、このプロジェクトはもともとeResource社の社内プロジェクトから発展してきたものです。
     eResource社は現在はすでに解散してしまっているのですが、そこでの成果がオープンソースプロジェクトとなって現在でも引き継がれているわけです。ちなみにeResource社は途中で社名がNetStruxr社に変わりましたが、クラス名のPrefixとしては旧社名に由来するERを使い続けています*。

    ではProject WONDERの中身な具体的にどのようなものかといいますと、コアとなる部分はフレームワークです。Project WONDERでは機能別に複数のフレームワークが開発されており、そこには様々な再利用可能コンポーネントが収められています。またフレームワークだけではなくサンプルアプリケーションや他の開発者が寄贈したものなども含まれています。
     Project WONDERが最初にOpenSource化されたのは2001年のことで、この年のWWDCでOpenSource化の発表がおこなわれました。2001年の時点ではWO4.5向けのバージョンで、名称もNetstruxr frameworksなどと呼ばれていました。その後バージョンアップを続け、2002年の2月にはWO5.1向けにProject WONDERとしての開発がスタートしています。
     最初のPublic Releaseが行われたのが2002年の7月で、このときのバージョンはVer 0.9でした。その後Ver1.0がリリースされ、最新バージョンは2003年4月にリリースされたVer 1.0.1となっています。現在は、2.0のリリースに向けての作業がおこなわれています。

    フレームワークですが、Ver 1.0.1では11個のフレームワークが提供されていて、その中にあるコンポーネントの総数はWebObjectsのコンポーネント数を上回るほどの量になっています。具体的にどのようなフレームワークがあるかは次回以降に詳しく解説していく予定ですが、主要なフレームワークの概要をまとめますと以下のようになります。

    ・ERExtensions
      WebObjects(WOF/EOF)の機能拡張
      アプリケーションの多国語化、Log4jを利用したロギング、
      実行中アプリの動的再コンパイル、JUnitを利用したUnit Test
      JavaScriptコンポーネント
    ・ERDirectToWeb
      Direct To Webの機能拡張
      ルールキャッシングシステム、追加テンプレート
      ローカリゼーションサポートの統合、Validationハンドリングの改善
    ・ERJars
      Log4jやJUnitのラッパーフレームワーク
    ・ERChangeNotificationJMS
      JMSを用いたインスタンス間でのEOの自動同期
    ・ERJavaMail
      E-mail送信フレームワーク
      ファイル添付、日本語サポート

     また、もともとはProject WONDERで開発が始まったわけではなく、他のデベロッパーからよせられたプロジェクトが含まれるようにもなってきていて、フレームワークをオープンソース化して公開する場を提供するといった役割もはたしています。
     さらにソースコードが公開されているWebObjectsのWebサーバアダプタを改良して、デフォルトのパラメータをチューニングしたり、標準では対応していないプラットフォーム向けのビルド済みアダプタの提供などもおこなっています。

    ・Project WONDER HTTP Server Adaptor URL
    http://wonder.sourceforge.net/WOAdaptor.html

     以上がProject WONDERの概要になりますが、実際に開発に利用しようとなると色々とノウハウも必要になってきますので、次回からはProject WONDERの機能を紹介しつつ、具体的にどのような使い方をするのかということを紹介していこうと思います。Project WONDERを使いこなせば、ただでさえ開発効率のよいWebObjectsがさらに強化されますので、ぜひご期待ください。

    *NSに変更すると某フレームワークと衝突してしまいますね(笑)

    ニュース・解説

     今週の解説担当:新居雅行

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃オーディオエンコードのAMRやACCはラインセンスが必要
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Technical Q&Aに掲載された文書によると、Windowsで稼働するQuickTimeを利用して、ConvertMovieToFile関数を使ってMPEG-4や3GPP、あるいは3GPP2ファイルへの書き出しをしても、ビデオは正しく出力されているがサウンドがなくなるという症状になる。これは、オーディオのエンコーディング方式のAMRやACCはライセンスを取得したアプリケーションでないと出力できないからである。Windowsでは、QuickTime Playerがライセンスを受けたアプリケーションとなっているので、QuickTime Proを購入すればQuickTime Playerで、サウンドが正しく組み込まれたムービーを出力する事ができる。

    QA1347: Movie export with AAC or AMR audio formats
    http://developer.apple.com/qa/qa2001/qa1347.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃OpenBase開発者向けのカンファレンスがマウイ島で開催
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    OpenBase Developers Conferenceが、2004年9月2〜6日の日程で、ハワイのマウイ島にある「シェラトン・マウイ」で開催される。6月1日までの申し込みなら、カファンレンスチケットに、ホテル代金と食事を含めた参加費が$829となっている(それ以後は$929)。SQLデータベースのOpenBaseについての詳細な情報をカンファレンスで得られると当時に、各方面で活躍している開発者との交流も深める事ができる。OpenBaseの管理やプログラミング、OpenScript、REALbasic、JDBC、ODBC、PHP、Qlian、Cocoa、WebObjectsといったテーマが予定されている。セッションのスケジュールは下記のサイトに掲載されている。なお、前記の価格は宿泊を2人が一つの部屋を使う場合で、一人で一部屋を使う場合には$1219となる(通常価格は$1319)。

    OpenBase Developers Conference
    http://www.openbase.com/maui2004

    MOSAからのお知らせと編集後記は割愛します

    MOSA Developer News   略称[MOSADeN=モサ伝]
    Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    http://www.mosa.gr.jp/
    Copyright (C)2004-2006 MOSA. All rights reserved.

  • MOSA Developer News[MOSADeN=モサ伝]第113号

    2004-05-18

    目次

    • Cocoaでいこう! Macらしく  第50回  Yoshiki(DreamField)
    • 藤本裕之のプログラミング夜話 #45
    • 高橋真人の「プログラミング指南」 第44回
    • ニュース・解説
    • MOSAからのお知らせ

    Cocoaでいこう! Macらしく  第50回 Yoshiki(DreamField)

    First Responder(前編)

     パネルの表示の説明は前回で終わりましたが、この時、メニューに項目を追加したのを覚えていますでしょうか。これは第41回と第42回で行いました。
    Interface Builderで「Edit」メニューの一番下に「Show Info」メニューを作り、Actionを接続しています(fig.01)。忘れてしまった方は、もう一度読み直して下さい。

    [fig.01] 「Show Info」はAppControllerに接続した
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig01.jpg

     さて、この時は一つのnibファイルの中でActionを接続すれば良かったのですが、他のnibファイルの中のオブジェクトに接続したい場合は、どうすれば良いのでしょうか。例えば、「Save As…」や「Close」メニューは、接続する先はそれぞれのドキュメントですが、これはMainMenu.nibの中にありません。それにドキュメントは複数開けますから、その時々の状況に応じて接続先を変えないといけなくなってしまいます。では、こういったメニューはどこに接続されているのか、実際に確かめてみましょう。
     いつものようにTinyViewのプロジェクトを開いてから、MainMenu.nibをInterface Builderで開いてください。そして、デザインウィンドウの中のメニューから「File」メニューを選び、「Save As…」を選びます(fig.02)。選んだままでinfoウィンドウを開いてConnectionsに切り替え、Target/Actionタブを選ぶと、「saveDocumentAs:」が接続されているはずですので、これを選択してください。その上で再度クリックしてください(ダブルクリックにならないように気をつけて下さい)。すると、接続されている線が表示されるはずです(fig.03)。

    [fig.02] デザインウィンドウの「Save As…」を選ぶ
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig02.gif

    [fig.03] 「Save As…」の接続が表示される
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig03.jpg

     接続先は、First Responderになっています。これは一体何なのでしょうか? ここで一つ実験をしてみましょう。
     まず、「Show Info」が何に接続されているのかを確かめてください(自分で接続したのですから覚えているとは思いますが、念のために)。今は、AppControllerの「showInfoPanel:」に接続されているはずです(fig.04)。

    [fig.04] 「Show Info」の接続を確かめる
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig04.jpg

     これと同じ物をFirst Responderに追加しましょう。nibファイルウィンドウでFirst Responderを選んでから、Classesタブでクラスの一覧に切り替えてください(fig.05)。そしてInfoパネルをAttributesに切り替え、Actionタブを選んでください(fig.06)。First Responderで使えるActionの一覧が出ますから、ここで右下のAddボタンを押します(fig.07)。すると、「myAction:」という名前のActionが追加されますので、これを「showInfoPanel:」という名前に書き直します(fig.08)。書き直したら、returnキーを押して確定してください。確定すると名前の順番にソートされますので、「showInfoPanel:」を見失っても慌てないように。

    [fig.05] First Responderを選んでからClassesタブを選択
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig05.jpg

    [fig.06] InfoパネルでAction一覧を表示
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig06.jpg

    [fig.07] Addボタンで「myAction:」が追加される
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig07.jpg

    [fig.08] 「showInfoPanel:」に書き直す
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig08.gif

     次に、「Show Info」メニューの接続を、今登録した「shwoInfoPanel:」に切り替えます。nibファイルウィンドウを再びInstancesに切り替えてください。デザインウィンドウから「Show Info」メニューを選び、Infoパネルをconnectionsに切り替え、Target/Actionタブを選びます。「showInfoPanel:」を選んで、右下のDisconnectボタンを押してください(fig.09)。これで従来の接続は解除されましたので、新しい接続を行いましょう。controlキーを押したまま「Show Info」メニューをマウスで選択し、そのままドラッグしてFirst Responderまで持っていって放してください(fig.10)。InfoパネルがTarget/Actionの一覧表示に切り替わりますので、先ほど登録した「showInfoPanel:」を選んで、Connectボタンを押してください(fig.11)。

    [fig.09]従来の接続を解除する
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig09.gif

    [fig.10] メニューからFirst Responderまでコントロールキーを押しながらドラッグ
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig10.jpg

    [fig.11] 「showInfoPanel:」を接続
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/50/images/fig11.gif

     これで「Show Info」メニューの接続は切り替わりましたので、さっそく動かしてみましょう。MainMenu.nibを保存し、TinyViewをビルドし、実行してみてください。TinyViewが起動したら、「Show Info」メニューを選んでみましょう。すると、今まで通りパネルが表示されるではありませんか。「Show Info」メニューの接続をAppControllerからFirst Responderに切り替えてしまったのに、何故今まで通り動くのでしょうか。この続きは次回です。

    藤本裕之のプログラミング夜話 #45

     米は研ぐもんである。だから無洗米ぢゃなくて無研米ぢゃないのか、なんてコマカいことを言いたいわけではないが、「洗う」と「研ぐ」とは意味において大きな差があるんであり、やっぱり米は研がなければおいしくないのである。最近は「的を得る」とか言うヒトもおり、こないだ指摘したら『いや辞書も認めたとニュースで言ってました』とか言われて仰天した。当然「的を射る」が正しい。的ってのは的ですよ、あの的、弓矢だの鉄砲だの槍だの投石だの子供が小便だので狙うあれ。あんなもの得てどうするんだ、と思わなければいけない。いけません。
     いや、にわか国語審議会を始めたのはつまり、その目的語によって使われる動詞が決まるこの構造は、実にこの、オブジェクトオリエンティドではないのという話をしたいからでなんだけどね。

    例えばよく言われる話で「GET、 PUT、 MAKEなどいくつかの基本的な単語を駆使できれば英語は通じます」とか言うのがあるぢゃないか。もちろん「通じる」ってことで言えば一面真実かも知れぬ、が、つまりそれは「米を洗ったり、的を得たり」することなんだと思うわけ。
     取る、置く、作るの類いの基本的な単語は、英語にも日本語にも……よくは知らないがたぶんスワヒリ語にもタガログ語にもあるはずであり、それを使い倒せば意味は通じるわけだ。昔の西部劇のインディアンの台詞の吹き替えですな。「白人、銃作る、人殺す、よくない」。で、プログラムというのは長いことこういう書き方をされてきたわけだ、「コンピュータは人間よかバカだから」とか言われながら。
     でもインディアンが白人よりバカなわけではないように、この問題についてコンピュータをバカにするのは間違ってる。単にメモリが足りなかったり処理スピードが遅かったので、そんなに多くの言葉を区別してる余裕がなかっただけだ。
     例えば懐かしい話になるが、オレが最初に使ったパソコン用のCコンパイラはシンボルの名前を最初の8文字までしか区別しなかった。つまり、activityOfAとactivityOfBは全く同じもので、何のワーニングもなくプログラム中に存在する。最初この制限を知らないときに出したバグはホンマに謎だったよ。……考えてみればあれがあったんでオレは英語のドキュメントでもちゃんと読むようになったんだが(笑)。

    Cocoa/Cabonを問わず、最近は変数や関数、メソッドなどの名前がやたら長くなっていることを嫌がるプログラマは多い。しかしプログラミング言語がこの意味で「饒舌」に、しかも適切な言葉を使うようになったことは実は豊かなことではないか、と思うのである。なにが何でも出すものはPUT、取って来るのはGETというより、もっと細かなニュアンスまでその名前によって知らせることができる。
     例えばCocoaのNSImageというクラスには自身が保持するイメージを描くメソッドが大きく分けて3種類ある。compositeのグループ、dissolveのグループ、drawのグループである。それぞれの仕様についてここに細かく記す紙幅はないが、ドキュメントを読んでからこれらの単語の意味を細かく調べるとなるほどなぁ、と思うよ。似たように使う言葉、例えばsearchとfindの違いなんかも気になる。……ただ、そういう名前を自分で考える時には、その表現がほんまに英語として意味通じるんかい、と心配になることもあるんだけどね。

     何を言うフジモト、そんな細かいことはどーでもいいのだ。オトコはキッパリGETとPUTだしゃらくさい、と質実剛健ニッポン男児のあなたは言うかも知れない。しかし我々は本来、アメリカ人よりこういうことに敏感なはずなのである。英語では動詞も名詞も「program」である行為に関して、我々はちゃんと「組む」という動詞を使うのである。「書く」も「作る」もないではないが、やっぱり「組む」が主流だろう。
     アメリカ人の教えぢゃない。我々のプログラムという目的語に対する意識がこの言葉を使わせるのである。そしてこの「組み」は「ほねぐみ」「わくぐみ」「しくみ」の「組み」なのだ。……「書いた」や「作った」ぢゃなくて、「組んだ」と言えるプログラミングをしたいぢゃありませんか、ご同輩。
    (2004_05_15)

    高橋真人の「プログラミング指南」第44回

    オブジェクト指向のとっかかり(30)

     こんにちは、高橋真人です。今回は、名前空間ということについてお話しします。
     今回のプログラムソースを見ると、コード全体にわたってstd::というprefix(前に付く識別子)が使われていることに気付かれることと思います。これが今回お話しする名前空間を表す識別子です。
     名前空間(name space=ネームスペース)というのは、プログラムの規模が大きくなったときに、識別子が重複してプログラムが混乱することを防ぐための技術です。ただ、この名前空間というものは必ずしもオブジェクト指向固有の技術というわけでもありませんし、実際に名前空間を自分で定義することはそれほど多くないと思われます。
     ただ、C++に限らず昨今の多くの言語においてこの名前空間の考え方が使われていますし、今回のプログラムを説明するためにも触れないわけにはいかないため、ごくさらっとした説明であることはご理解ください。

    さて、よく「グローバル変数を無闇に使うな」ということを申します。グローバル変数を使うことの問題点の一つとして識別子の重複ということがあります。
     たとえば、filesという名のグローバル変数を定義したとします。そして、いくつかの関数の中でローカル変数として、これまたfilesという変数を定義したとします。このこと自体には問題はありません。ローカルなfilesは、グローバルなfilesを隠してしまうため、関数の中でfilesの操作をしても、それはグローバルのfilesには何ら影響を与えるものではないのです。
     ところがプログラムというのは変わるものです。コードをいろいろいじっているうちに、関数の中の変数宣言を消してしまうだとか、コードを部分的にコピーしたためにfilesの宣言部が欠けていたなどという時に、突然悲劇はやってきます(笑)。
     本来ならfilesという変数を操作している箇所で「この変数の宣言がない」というエラーが出るはずなのに、グローバル変数にも同じ名前のものがあるためにコンパイラは何の疑問も持たずに「これはグローバルのfilesに対する操作なのだな」と理解してしまうわけです。
     こうなると、何らかのタイミングで突然グローバル変数の値が変化してしまったりして「いったい、何が起こってるんだっ」と哀れなプログラマは頭を抱えることになるわけですね。
     と、まあこんな悲劇をあなたの身の上に起こさないためにも、グローバル変数を使うときには必ず頭にgを付けましょうとか、変数を束ねて構造体の中にくるんじゃいましょうとか、いろいろと防止策が講じられてきたわけです。
     それでもプログラムの規模が大きくなってくれば、当然使われる変数の数も増えてくるものです。さらにはオブジェクト指向となると、ほとんどの場合に一緒に使われるアプリケーションフレームワークなどというものでは、プログラマ(フレームワークのユーザーの方)の側では一切あずかり知らないところで、いくつものクラスが定義され、使われていたりするものですから、シンボル(識別子)のバッティングという問題は決して人ごとではないのです。
     そこでC++の場合、名前空間というものを作って「その中に納めたものは他の名前空間に属するものと区別ができるようにしましょう」ということになったのです。
     現在のC++では、標準ライブラリはすべてstdという名前空間にくるまれることになっているため、今回のプログラムでもコードが見にくくなるぐらいに何から何まで「std::」というものが付けられています。
     たとえば、main()のしょっぱなにある「std::cerr」というのは、「cerrはstdネームスペースに属している」ということを表しています。(ちなみに、cerrはANSI Cで言うところのstderrと同じ役割を持つstreamクラスです)
     このように、まずstd::cerrという形で、シンボルの直前にスコープ演算子である「::」を伴って名前空間名を付ける表し方が、一つの使い方です。
     他には「usingディレクティブ」というものの後に「namespace」を並べて使って、「これから、以下の名前空間を使うことを宣言します」というやり方があります。この場合、usingディレクティブの属するスコープが、そのまま名前空間の有効範囲ということになります。具体的には以下のような感じです。

    #include <iostream>
    #include <string>
    int main()
    {
        using namespace std;
        cout << "What your name? " << flush;
        string name;
        cin >> name;
        cout << "Hello " << name.c_str() << "!" << endl;
        return 0;
    }

     これは簡単なあいさつのプログラムですが、関数の冒頭でusingディレクティブによってstdネームスペースを宣言しているため、cout、flush、string、cin、endlの各識別子の前にstd::を付ける必要がありません。
     ちなみに、C++の入門書や解説本などにおいて、using namespace std;をコードの冒頭、つまりmain関数よりも前におくことによって、プログラムのグローバルスコープでstd名前空間を有効にしてしまう手法がよく見られます。
     私の書いた前回のプログラムでも、TextContent.hというすべてのソースファイルから取り込まれるヘッダファイルの中でusing namespace std;と宣言してプログラム全体で、std名前空間を有効になるようにしてありました。
     注意してほしいのは、これはあくまで余計な修飾子が付くことによって、その時に説明したいコードの本質が見えにくくなることを防ごうという制作者の配慮であって、実際のプログラムでは決して常用されるやり方ではないということです。
     こんなことをしたので、そもそも何のために名前空間を使うのかが分かりませんから、通常はこのような書き方はしないのです。(続く)

    ニュース・解説

     今週の解説担当:小池邦人

    Carbon ドキュメント & サンプル & SDK ナビゲーション(2004/05/14)

    【開発環境】

    WWDC2004のJobsによる基調講演の「目玉」は、Mac OS Xの次期バージョンである「Tiger」(Mac OS X 10.4)だということがApple社から発表されました。
    結局、次期OSのコードネームは噂通りだったようです(次はどうするのだという疑問も湧くが...)。前回のWWDCではPantherのプレビュー版が参加者全員に配布されたのですが、今回も同様にTigerのプレビュー版が配布されるのかどうかは定かではありません。しかし、大きな「柱」の出現により、WWDCに参加する者としては「現場でやらなきゃいけない仕事」がかなり増えてしまったことは間違いないようです(笑)。

    はたしてTigerは64bit OSとして登場するのでしょうか?x86エミュレーション環境をバンドルするという噂は当たっているのでしょうか?色々と興味はつきませんが、どうも現状のスケジュールでTBA(To be announced ...内容未定)と記されているセッションが多いのは、そこにTigerに関する技術セッションを挿入するためのようです。ということは、TBAの数からして随分と多くの新機能がお披露目される可能性ありそうですね。Tigerの派手なデビューを期待致しましょう!

    http://www.apple.com/pr/library/2004/may/04wwdc.html

    【テクニカルドキュメント】

    前回から5月14日の期間中、Apple社のDocumentationサイトにはドキュメントが15登録されました。「Carbon Result Code Alphabetic Index」や「Carbon Result Code Numeric Index」の登録は、Carbonプログラマの筆者としてはありがたいところです。ついでに、「All API Alphabetic Index」も出したらどうかと思うのですが...執筆途中でどんどん新しいAPIが増えていくのであまり意味が無いかもしれません(笑)。それより、Mac OS XやQuickTimeの新版が登場した時点で、そこで追加されたすべてのAPIと、その内容を一覧にまとめたドキュメントを出してくれないでしょうか?知らない間に「秘密のAPI」が登場していて「今まで苦労して実現していた問題が簡単に解決できるようになっている」という経験を何度もした筆者としては、「New Face API」ドキュメントシリーズの開始を切望したいと思います。

    「Carbon Result Code Alphabetic Index」
    「Carbon Result Code Numeric Index」
    「ColorSync Manager Reference」 (PDFあり)
    「Security Overview」(PDFあり)
    「Accessing Hardware From Applications」(PDFあり)
    「Adding Search to Your Application (Preliminary)」(PDFあり)
    「Core Foundation Reference」
    「Developing Cocoa Applications Using Bindings: A Tutorial」(PDFあり)
    「I/O Kit Fundamentals」 (PDFあり)
    「Kernel Extension Concepts」
    「Network Kernel Extensions」(PDFあり)
    「System Configuration Programming Guidelines」(PDFあり)
    「Xcode Build System」
    「Address Book」
    「Cocoa Bindings」

    http://developer.apple.com/documentation/index-rev-date.html

    また、デベロッパ向けの読み物として以下の2つの解説が登録されています。

    「Dynamic HTML and XML: The XMLHttpRequest Object」(読み物)

    http://developer.apple.com/internet/webcontent/xmlhttpreq.html

    「Binding Your Preferences in Cocoa」(読み物)

    http://developer.apple.com/cocoa/cocoabindings.html

    前回から5月14日の期間中、新規のテクニカルノートは2つ登録されました。「Native Scripting Additions」の方は再登録となっています。

    TN1164「Native Scripting Additions」 (再登録)
    TN2110「Identifying Java on Mac OS X」

    http://developer.apple.com/technicalnotes/index-rev-date.html

    テクニカルQ&Aの方も2つ登録されました。

    QA1264「Generating an NMI Without a Programmer's Switch」
    QA1317「Signaling the end of data when using
        AudioConverterFillComplexBuffer」

    http://developer.apple.com/technicalqas/index-rev-date.html

    【サンプルソースコード】

    前回から5月14日の期間中、Apple社のSample Codeサイトには新しいサンプルソースコードがひとつだけ登録されました。「StarMenu」は、カスタムメニューの構築にHIViewの仕組みを使う実例です。サンプルアプリケーションを起動するとド派手な7色の星形メニューが表示できます。もうこうなるとメニューと言って良いのかどうか疑問なのですが(笑)HIViewの仕組みを理解するのにはもってこいのサンプルです。

    「StarMenu」(HiView)

    http://developer.apple.com/samplecode/index-rev-date.html

    【デベロップメント SDK】

    前回から5月14日の期間中、Apple社のSDKサイトには新しいSDKが2つ登録されました。Windows版iTunes用SDKとFireWire SDK(Mac OS X用)の最新版です。
    またSDKではありませんが、コマンドラインでフォントの管理を行うための「Font Tools」と「CHUD」の最新版が登録されています。「iTunes COM for Windows SDK」と「Font Tools 2.0」については、前号の新居さんの解説も参考にしてください。

    「iTunes COM for Windows SDK」
    「FireWire SDK 19 for Mac OS X」

    http://developer.apple.com/sdk/

    「Font Tools Release 2.0.0」

    http://developer.apple.com/fonts/OSXTools.html

    Computer Hardware Understanding Development Tools (CHUD Tools)3.5.1

    http://developer.apple.com/tools/performance/

    MOSAからのお知らせと編集後記は割愛します

    MOSA Developer News   略称[MOSADeN=モサ伝]
    Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    http://www.mosa.gr.jp/
    Copyright (C)2004-2006 MOSA. All rights reserved.

  • MOSA Developer News[MOSADeN=モサ伝]第112号

    2004-05-11

    目次

    • Cocoaでいこう! Macらしく  第49回  Yoshiki(DreamField)
    • 小池邦人の「Carbon API 徒然草」
    • 「Behind the WebObjects」  第19回  田畑 英和
    • ニュース・解説
    • MOSAからのお知らせ

    Cocoaでいこう! Macらしく  第49回 Yoshiki(DreamField)

    パネルを表示しよう(その11)

     前回は、MyDocumentControllerのコーディングまでを行いました。今回は、これをフレームワークが生成しているNSDocumentControllerとすげ替えることを考えます。
     第25回で、AppControllerを起動時にインスタンス化する方法を説明しましたが、覚えていますでしょうか。その時は、AppControllerをインスタンス化した状態で、MainMenu.nibに組み込んでしまいました。こうすれば、MainMenu.nibをロードした時にAppControllerはインスタンス化されますから、フレームワークに手を入れることなく、起動時に生成できるようになるわけです。今回も同様の方法を使います。
     いつもの様にTinyViewのプロジェクトを開いてください。そして、MainMenu.nibを開いてください。まず、MyDocumentControllerクラスを使えるようにします。XcodeからMyDocumentController.hをInterfaceBuilderのnibファイルウィンドウにドラッグ&ドロップしてください(fig.01)。すると、InterfaceBuilderではMyDocumentControllerクラスが選択されている状態になりますので、ClassesメニューからInstantiate MyDocumentControllerを選択します(fig.02)。これでMyDocumentControllerクラスはインスタンス化された状態で、MainMenu.nibに組み込まれました(fig.03)。

    [fig.01] MyDocumentController.hをドラッグ&ドロップ
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/49/images/fig01.jpg

    [fig.02] MyDocumentControllerクラスをインスタンス化
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/49/images/fig02.jpg

    [fig.03] MainMenu.nibにMyDocumentControllerクラスのインスタンスが組み込まれた
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/49/images/fig03.jpg

     ところで、この様なことをしてしまって、フレームワークが生成しているNSDocumentControllerクラスのインスタンスはどうなってしまうのでしょうか。こちらも生成されてしまうのだとしたら、すげ替えたことになりません。ここで、NSDocumentControllerクラスのリファレンスを見てください。
    sharedDocumentControllerというクラスメソッドがあると思います。実は、NSDocumentControllerは、Document-based Applicationに一つしか存在してはいけないので、このメソッドを使って生成します。このメソッドは第43回で説明したsharedImageInfoの様な手法で、まだNSDocumentControllerクラスのインスタンスが存在していない時には生成しますが、一度生成してしまうと、次からはこのアドレスを返すだけになります。こうやって、生成されるインスタンスが一つだけになるようにしています。従いまして、MainMenu.nibに組み込んで、先にNSDocumentControllerクラスを継承しているMyDocumentControllerクラスのインスタンスを作ってしまえば、フレームワークが後から生成しようとしても、そのアドレスが返るだけになるというわけです。これですげ替えを行うことができました。
     それでは、MainMenu.nibを保存し、TinyViewをビルドして実行してみましょう。複数の画像を開いたり閉じたり、色々な操作をしてみてください。画像を一つも開いていない時は、パネルの値は0になるはずです(fig.04)。なお、Xcodeを最新にアップデートされた方は、一度クリーニングを行ってからビルドしてください。これを行わないとエラーが出ることがあるようです(私の環境では、今回触っていないはずのImageProducingData.mで、エラーが出ました)。

    [fig.04]何も画像を表示していない時は、パネルの値は0になる
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/49/images/fig04.gif

     さて、これで一通りのパネルの実装は終わりました。でも、まだちょっと見苦しいですね。もうちょっとだけ手を入れてみましょうか。現在は一つも画像を表示していない時は縦横とも0を表示していますが、これを空白にしましょう。サイズが0の画像は通常無いはずですから、この値の時には表示を空白にすることにします。InfoPanelController.mのupdateImageInfoメソッドの中で、画像のサイズをセットしている所を次の様に書き直してみてください。

    if( NSEqualSizes( imageSize, NSZeroSize)){
        [ [ infoForm cellAtIndex:0] setStringValue:@""];
        [ [ infoForm cellAtIndex:1] setStringValue:@""];
    }else{
        [ [ infoForm cellAtIndex:0] setFloatValue:imageSize.width];
        [ [ infoForm cellAtIndex:1] setFloatValue:imageSize.height];
    }
    


     imageSizeと0サイズを比較し、等しければ文字列の長さが0のNSStringクラスのインスタンスをセットしています。ビルドして実行してみましょう。今度は、何も画像を表示していない時には、パネルの値は空白になったはずです(fig.05)。

    [fig.05]何も画像を表示していない時は、パネルの値は空白になる
    http://www.remus.dti.ne.jp/~yoshiki/cocoa/ed1/49/images/fig05.gif

     これでパネルの表示は完成です。最後に説明した空白の表示は、今後項目を増やすことを考えると、いささか強引だったかもしれません。情報がクリアされていることが明確に分かるように実装した方が、より確実でしょう。この辺りは、各自で色々とやってみてください。
     それでは次回は、本来ならもっと早く説明すべきだったと反省している、First Responderの説明を行います。

    小池邦人の「Carbon API 徒然草」(2004/05/07)

    Carbon EventとApple Event

    今回は、初期化ルーチンのstartApplication()で呼ばれているsetupAppleEvent()と、それに関係する幾つかのルーチンを紹介したいと思います。

    Carbonアプリケーションでは、メニュー選択やボタンのマウスクリックといったユーザの操作内容が「Carbon Event」という仕組みで伝搬されてきます。これをアプリケーション側で用意したイベントハンドラ(Event Handller)と呼ばれるルーチンで受け取り、ユーザが指示した処理内容を実行するわけです。
    つまりハンドラへ「ユーザが何々をしたから何々しろ」といった「指示書」(単純にイベントと呼ぶ)が届くわけです。Carbon Eventのイベントには色々なタイプがあるので、宛先オブジェクト(ウィンドウ、コントロールなど)毎にハンドラを用意し処理を切り分けます。例えば、ユーザがファイルメニューから「開く」を選択すると、「メニューが選択された」と言う情報と同時に、kHICommandOpen(’open’)というコマンドがハンドラへ届きます。そうしたイベント情報(指示書)を正しく解析した後に、「ファイル選択ダイアログをオープンする」といった適切な処理を実行するわけです。

    Carbon Eventの仕組みは、Mac OS Xと同時に登場したCarbon Frameworkにおいて初めて実装されました。Carbon Eventを採用しなくてもCarbonアプリケーションを開発することは可能なのですが、本サンプルでは最新のCarbon Eventを利用しています。よって、その詳しい仕組みや利点については、本連載で順次言及していくことになると思います。ところで、Macintoshのシステムには、Carbon Eventが登場する以前(System 7の時代)から導入されているもうひとつのイベントシステムが存在しています。それが「Apple Event」です。
    いくつかの例外はありますが、Carbon Eventが「アプリケーション内部」で発生した出来事を把握するための仕組だとすると、Apple Eventは「アプリケーション外部」からの要求を受け取るための仕組みだと考えれば、分かりやすいかもしれません。

    Apple Eventの一番身近な例は、Finderでのドキュメントアイコンのダブルクリックです。Finderでアイコンをオープンすると、Finderから対象となるアプリケーション(ドキュメントを作成したアプリケーション)へ「XXXXというドキュメントの保存場所を教えるからオープンしなさい!」という要求が届きます。また別の例としては、AppleScriptで記述された命令が特定のアプリケーションへ送られる場合があります。AppleScriptの命令は、すべてApple Eventの仕組みによりターゲットアプリケーションへと送られます。よってCarbon Eventと同様に、要求を解析し正しく処理するためのイベントハンドラをアプリケーション側に用意しておく必要があるわけです。本サンプルには、Finderからの要求に対処するために2種類のイベントハンドラがインストールされています。その処理は、以下のsetupAppleEvent()で行われています。これは、前回のコールバックルーチンのインストールとよく似ていますね。

    void setupAppleEvent(void)
    {
        AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,myOpenApp,NULL,0);
        AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,myOpenDoc,NULL,0);
    }
    


    AEInstallEventHandler()の引数にkAEOpenApplicationを代入すると、Finderからアプリケーションが起動される時に呼ばれるイベントハンドラを実装したことになります。また、引数にkAEOpenDocumentsを代入した場合には、Finderでドキュメントがオープンされた時に呼ばれるハンドラの実装となります。これにより、Finderでアプリケーションアイコンがダブルクリックされた時にはmyOpenApp()が、ドキュメントアイコンがダブルクリックされた時にはmyOpenDoc()が実行されるようになります。myOpenDoc()の方は、アプリケーションアイコン上にドキュメントアイコンをドラッグ&ドロップした場合にも呼ばれます。また、Dockにおけるアプリケーションやドキュメントアイコンのクリックでも同様な現象が起こります。

    以下がFinderからの起動要求に対応するためのイベントハンドラmyOpenApp()です。ハンドラ内に起動に特化した処理を記述する必要はありません。myOpenApp()は、新規のカタログウィンドウをオープンするだけのいたってシンプルなルーチンとなっています。

    pascal OSErr myOpenApp( const AppleEvent *event,AppleEvent *reply,long refcon )
    {
        WindowRef    wptr;
    
        newCatalogWindow( &wptr );    // 新規カタログウィンドウをオープンする
        return( 0 );
    }

    先ほどCarbon EventとApple Eventの仕組みをお話した時に、それぞれのイベントを発生させている要因は「アプリケーション内」と「アプリケーション外」にあると説明しました。ところが、その区別が当てはまらない例外もあります。そのひとつは、アプリケーション終了時に発生するイベントです。実は「アプリケーションを終了しろ!」という要求は、Carbon EventとApple Eventどちらのイベントハンドラでも受け取ることが可能なのです。開発者は好みの方を実装し、そこにアプリケーションの終了処理を記述することになります。本サンプルでは、Carbon Event用のイベントハンドラ利用しています。
    もしそれを止めて、Apple Eventのイベントハンドラに切り替えたとすると、先ほど紹介したsetupAppleEvent()に、以下の一行を追加することになります。

    AEInstallEventHandler( kCoreEventClass,kAEQuitApplication,myQuitApp,NULL,0 );

    そしてイベントハンドラのmyQuitApp()は以下のように記述します。

    pascal OSErr myQuitApp( const AppleEvent *event,AppleEvent *reply,long refcon )
    {
        if( quitApplication()==noErr )  // 終了処理がユーザにキャンセルされなかった
            QuitApplicationEventLoop(); // Carbon Event Loopから抜ける
        return( 0 );
    }
    


    本サンプルの終了処理は、myApplicationEventHandler()でkHICommandQuit(’quit’)を受け取った時に実行されています。この内容を上記のApple Eventの場合と比較してみてください。Carbon Eventのハンドラでは、イベントループ(Carbon Event Loop)から抜けるためのQuitApplicationEventLoop()が呼ばれていないのですが、何故か終了処理は正しく実行されます。どうしてでしょうか?その答えは、次にCarbon Eventを解説するまで宿題にしておきたいと思います(笑)。ちなみに、予期せぬ事態が起こる可能性がありますので、Carbon EventとApple Event両方のイベントハンドラを実装しないように注意しましょう(意味無し)。試しに簡単な実験をしてみると、終了処理のイベントはApple EventよりCarbon Eventの方に先に届くようです…。

    Mac OS Xの場合、アプリケーションメニューの「環境設定…」(本サンプルでは未使用)が選択された時にも終了処理と同様な対応が可能です。Carbon Eventに対応したアプリケーションであれば、kHICommandPreferences(’pref’)というメニューコマンドを受け取り、それを適切なハンドラで処理すればOKとなります。しかし、Carbon Eventを使わず旧式イベントループ(WaitNextEvent()を使用)でメニュー選択のチェックを行っていると、ユーザが環境設定を選択したことを知る術がありません。そのため、Apple EventにはkAEShowPreferencesというパラメータが用意されており、メニューから環境設定が選択された場合の処理を、Appel Eventのイベントハンドラとして実装できるように考慮されています。

    Apple Eventに関連する定数やAPIが定義されているヘッダファイルは、ApplicationServices FrameworkのAppleEvents.hです。また、Carbon Eventのイベントクラス、タイプ、パラメータ、そしてAPIについては、Carbon FrameworkのCarbonEvents.hとCarbonEventsCore.hを参照してください。次回はApple Eventの話の続きです。先ほど紹介したもうひとつのイベントハンドラ、myOpenDoc()について説明したいと思います。

    つづく

    「Behind the WebObjects」  第19回  田畑 英和

     さて、今回も前回からの続きでDirectActionの解説になります。今回はセッションとDirectActionを組み合わせる方法について解説いたします。そもそもDirectActionを用いるとセッションを使用しない処理ができるのですが、必要に応じて使い分けることができ、1つのアプリケーションでも部分的にセッションを使用したり、DirectActionを使用したりできます。
     このとき、セッションをもったページからDirectActionを呼び出して、そこからまたもとのセッションにアクセスするといった処理も可能になっています。

    ではまずWebObjectsアプリケーション内からのDirectActionの呼び出しですが、第16回の連載で解説しましたようにWebObjects BuilderのInspector上で”actionClass”と”directActionName”を指定してアクションのバインディングをおこなえば、任意のDirectActionを呼び出すことができます。例えばMainコンポーネントにWOHyperLinkを追加して、以下のようにDirectActionを呼び出す設定をしたとしましょう。

    ・wodの設定
    actionClass = “DirectAction”;
    directActionName = “test”;

    ・DirectActionのULR
    http://[host]/cgi-bin/WebObjects/App.woa/wa/test

     このとき生成されるURLは上記のようになり、URL中にクラス(DirectActionクラスの場合は省略)とメソッド(xxxActionのxxxの部分)の情報が埋め込まれます。このようなDirectActionにアクセスするとURLは次のようになり、URLの最後にパラメータが1つ追加されます。

    …/wa/test?wosid=qFZbxk5xUuZ9dNHal9okbw

     wosidというkeyでパラメータが自動的に追加され、valueにはセッションIDが埋め込まれています。WebObjectsアプリケーションでは、デフォルトの設定の場合、トップページにアクセスしたときにセッションも作成されますが、この場合トップページ(Mainページ)へのアクセス時に生成されたセッションのIDがURLに埋め込まれています。つまりどのセッションからDirectActionを呼び出したかが分かるようになっているのです。
     このため、DirectAction側ではwosidをkeyとする値(value)を用いることによって、どのセッションからの呼び出しかを識別することができるのです。
     ではDirectAction側でどのようにして呼び出し元のセッションにアクセスするかですが、もちろん前回説明したリクエストオブジェクト(WORequest)を用いればリクエストデータからセッションIDを取り出すことができます。しかしWODirectActionクラス(正確には親クラスのWOAction)にはセッションにアクセスするための便利なメソッドが用意されているため、セッションIDを意識せずに処理をおこなうことができます。

    public WOSession existingSession()

     このexistingSessionメソッドがセッションにアクセスするためのメソッドですが、DirectActionでこのメソッドを使用するとリクエストデータに含まれるセッションIDから対応するセッションオブジェクトを自動的に取り出してくれます。もしリクエストデータにセッションIDがなかったり、セッションIDがあっても対応するセッションが存在しない場合にはnullが返ります。
     このように、このメソッドを用いればセッションIDがどのような値なのかを意識する必要なく、簡単に適切なセッションにアクセスすることができます。

    ところで、WebObjctesで開発したアプリケーションでは、トップページにアクセスすると同時にセッションの生成がおこなわれることはすでに説明しましたが、設定を変更すればトップページをDirectAction経由で処理し、セッションを生成しないようにもできます。
     セッションは必要になった時点で始めて生成すればよいので、トップページをDirectActionで生成するようにすれば余分なセッションが生成されるのを防ぐこともできます。*1
     この変更をおこなうにはリクエストハンドラーについて知っておく必要があるのですが、まずDirectActionの場合とそうでない場合とで、生成されるURLに違いがあることをおさえておきましょう。

    ・DirectActionの場合
    …/wa/test?wosid=qFZbxk5xUuZ9dNHal9okbw
    ・DirectActionでない場合
    …/wo/qFZbxk5xUuZ9dNHal9okbw/0.3

     このようにDirectActionの場合はURLに”wa”が、そうでない場合には”wo”が含まれています。これはリクエストハンドラーキーと呼ばれるもので、どのリクエストハンドラーによってリクエストを処理するのかを識別するためのキーです。つまりリクエスト処理の種類(例えばDirectActoion)ごとにリクエストハンドラーが存在し、どのハンドラーを呼び出すかがURLに埋め込まれるキーによって決定されるのです。
     アプリケーションにはデフォルトのリクエストハンドラーを定義することができ、次のようにコーディングすればDirectAction用のリクエストハンドラーがデフォルトとして設定され、トップページはDirectAction経由で処理されます。

         String handlerkey = directActionRequestHandlerKey();
         WORequestHandler handler = requestHandlerForKey(handlerkey);
         setDefaultRequestHandler(handler);

     このコードをApplication.javaのコンストラクタに追加しておけば、このアプリケーションのトップページにアクセスするとDirectActionが呼び出されます。具体的にはDirectActionクラスのdefaultAction()メソッドが呼び出されます。このとき、defaultAction()が返すコンポーネントのアクションバインディングをすべてDirectActionにしておけばセッションの生成はおこなわません。このようにしてDirectActionを利用することもできますので、効率的なアプリケーション開発に役立ててください。

    *1 ただし、必要に応じてセッションは自動的に生成されるのでDirectActionを経由したからといって必ずセッションが生成されないというわけではありません。非DirectActionがバインドされているようなページを生成すると自動的にセッションが生成されます。

    ニュース・解説

     今週の解説担当:新居雅行

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Xcodeのビルド機能を解説する文書が公開
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Mac OS Xの開発ツールXcodeのドキュメントが公開された。Xcodeでのコードビルドの機能を解説しており、どういった手順でビルドが行われ、ビルド時のさまざまなオプション設定や環境変数のリストなどが掲載されている。また、分散ビルドやZero Link、コマンドラインからのビルドの解説までも含まれている。Xcodeを使って開発を行っているデベロッパーにとって有益な情報源となるだろう。

    Xcode Build System
    http://developer.apple.com/documentation/DeveloperTools/Conceptual/Build_System/

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃ネットワークシステムの設定を処理するシステム機能の使い方
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    システム設定(System Configuration)についてのプログラミングのドキュメントが公開されている。これは、ネットワークの設定で、たとえば「場所」を切り替えるといったことや、自動的にPPP接続するなどの機能をアプリケーションに組み込む方法を説明したものである。システムのこの部分の機能はたとえばコマンドのscutil等で確認はできるため、機能としては以前のバージョンからあるが、APIドキュメントとしては初めて公開されたものだ。

    System Configuration Programming Guidelines
    http://developer.apple.com/documentation/Networking/Conceptual/SystemConfigFrameworks/

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃WebObjectsのトレーニングが6月に開催
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    WebObjectsを利用したアプリケーション開発のトレーニングが2004年6月8日(火)〜11日(金)に開催される。WebObjectsはAppleが開発するアプリケーションサーバ開発・稼働環境で、高度なフレームワーク機能をベースに使いやすいツールを使って短期間で多機能なWebアプリケーションを開発できるのが特徴だ。受講にはJavaやリレーショナルデータベースの基本知識があることが前提で、WebObjectsを使ったアプリケーション開発やデータベースとの連携、コンポーネントの利用方法や実用的なアプリケーション作成の方法を学習できる。Macを使って実際にハンズオンを行いながらの実習なので、その場で受講内容を確認できるだろう。場所は、東京・初台のアップルコンピュータのトレーニングルームで、価格は99,750円である。ADC会員は79,800円に割引される。

    WebObjects 5.2 トレーニングコース #1
    http://www.event21.ne.jp/apple/wobjpay.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃カーネル機能拡張に関する文書が公開
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    カーネル機能拡張に関する文書が更新されて、新たな文書「Kernel Extension Concepts」として公開されている。I/O Kitを使ったカーネル機能拡張の作り方をXcodeの最新版の状況に合わせて記述しているため、基本から学習することも可能だ。作成したソフトウエアを配布する方法も併せて解説されており、ドライバ系のプログラミングが必要な場合にはまずチェックしたい文書だろう。
    なお、ネットワーク機能拡張についての文書「Network Kernel Extensions」も公開されている。

    Kernel Extension Concepts
    http://developer.apple.com/documentation/Darwin/Conceptual/KEXTConcept/
    Network Kernel Extensions
    http://developer.apple.com/documentation/Darwin/Conceptual/NetworkKernelExtensions/

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃WebKitをJava言語で使うためのライブラリ
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Mac OS Xに付属するWebブラウザSafariのコンポーネントをアプリケーションから利用できるWebKitは、Cocoaクラスが用意されているもののなぜかObjective-Cからしか利用できなかった。しかしながら、Dmitry Markman氏によってJavaでWebKitを使えるライブラリが公開されており、ソースも公開されている。WebKitをJavaベースで使いたい人にとっては待ち望んでいたライブラリだろう。ただし、一般的なCocoa-JavaのクラスのようなObjective-Cとの完全な対応関係があるようなクラスにはなっていないので、利用するにはサンプルやクラスのソースを参照して機能を検討する必要があるだろう。JNIを使うなどかなり高度な内容のものでもある。

    WebKit & Java integration
    http://www.concord.org/~dima/jws/webkit/

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Mac OS XのSwing上での日本語入力問題を改善するモジュール
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    エクスファは、Mac OS XのJava環境での日本語入力の問題を改善するモジュール「Java 1.4.2 日本語編集モジュール(textpach142.class)」を公開した。
    Java VM 1.4.2を使った場合SwingのJTextPaneなどでインライン入力ができるが、変換候補のリスト表示中にreturnキーを押すとテキスト領域に改行が入るなどの問題があるが、textpach142. classを利用することで改善される。キーイベント処理でこのクラスを利用するようにソースの追加は必要となる。パッケージソフトへの組み込みや法人利用はライセンス料が必要だが、個人利用は無償となっている。

    MacOS-X向けJava1.4.2 日本語入力問題確認ページ
    http://www.x-fer.co.jp:80/xferhpservlet?opcode=textPach142

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃より高機能なプロパティファイルエディタ
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Mac OS Xのプロパティファイル(plistファイル)はXML形式でデータが保存されているが、Xcodeに付属のProperty List Editorを使って編集している人も多いだろう。Brian Webster氏が開発したPlistEdit Proを使えば、より多機能なプロパティファイルの編集が可能となる。ドラッグ&ドロップや検索置換ができることに加えてAppleScriptにも対応しているため、編集作業を自動化することもできる。 $24.95のシェアウエアである。

    PlistEdit Pro
    http://homepage.mac.com/bwebster/plisteditpro.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃フォント関連ツールがアップデート
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    コマンドラインでフォントの管理などを行うツール、Font Toolsがアップデートした。フォントファイルの情報や認識可能なフォントの一覧を得るなどのいくつかのコマンドラインツールが含まれている。フォントの情報を得るためにも使えるが、フォントを開発する場合のバッチ処理に組み込むためにも使えるだろう。ドキュメントがしっかりついているが、どんなコマンドがかあるかはQuick Referenceを見れば早いだろう。

    Font Tools 2.0
    http://developer.apple.com/fonts/OSXTools.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Windows版iTunesのSDKを公開
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Windows版iTunesについてのSDKが公開された。iTunes 4.5 for Windows以降が対象になるが、COMオブジェクトとして公開されいる部分を、JScriptや C++/C#、Visual Basic等で利用することで、WindowsでもiTunesと連携したアプリケーションやあるいはソリューションを構築できるようになる。

    iTunes COM for Windows SDK
    http://developer.apple.com/sdk/itunescomsdk.html

    MOSAからのお知らせと編集後記は割愛します

    MOSA Developer News   略称[MOSADeN=モサ伝]
    Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    http://www.mosa.gr.jp/
    Copyright (C)2004-2006 MOSA. All rights reserved.