MOSA Multi-OS Software Artists

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

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

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

MOSADenバックナンバー 2005年12月発行分

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

    2005-12-27

    目次

    • 「WebObjects Dev Report」    第34回  田畑 英和
    • SqueakではじめるSmalltalk入門  第53回  鷲見 正人
    • ニュース・解説               木下 誠

    「WebObjects Dev Report」  第34回  田畑 英和

     これまでダイレクトアクション内での処理については解説してきましたが、今回はダイレクトアクションへのパラメータの指定方法について解説します。

     まずはどのようなときにダイレクトアクションに対してパラメータを指定するかをみてみましょう。前回ご紹介した特定のユーザ情報を表示するためのダイレクトアクション(browseCareerAction)ですが、ダイレクトアクションを単純に呼び出しただけでは、どのユーザ情報を表示してよいのか特定できません。そこでダイレクトアクションを呼び出すときに、パラメータも一緒に指定します。具体的には次のようなダイレクトアクションの呼び出し方をおこないます。

    ・パラメータ付きダイレクトアクションのURL
    /cgi-bin/WebObjects/MOSAJobMatch.woa/wa/browseCareer?id=4

     URLに指定したダイレクトアクション名(browseCareer)の後ろにある”?id=4″がパラメータです。このパラメータがユーザを特定するためのキーになり、ここではユーザのプライマリーキーを用いています。このパラメータをダイレクトアクション内で取得して、ユーザの検索処理に用います。
     次に、このようなパラメータ付きのURLを生成する方法をみてみましょう。WOHyperLinkを使ってダイレクトアクションを呼び出すには次のようなバインドをおこないます(*1)。

    actionClass = “DirectAction”;
    directActionName = “browseCareer”;

     actionClassには呼び出すダイレクトアクションが実装してあるクラスのクラス名を指定し、directActionNameにはダイレクトアクションのメソッド名から最後のactionを外したものを指定します。
     つまりこの場合はDirectAction.javaに実装されているbrowseCareerActionメソッドを呼び出す設定になります。
     ですが、これだけではまだパラメータの指定ができていません。パラメータの指定方法は何通りかあるのですが、browseCareerのように1組のパラメータしか指定しないのであれば次のようなバインドを追加することで対応できます。

    ?id = 4;

     今回はidという名前のパラメータを指定していますが、idという名前はアプリケーション独自のものですので、あらかじめ定義されているactionClassやdirectActionNameとは違い、「WebObjects Builder」のInspector上では手動で追加する必要があります。
     これでURLにパラメータを追加することができるようになりましたが、このままではidが”4″のユーザ情報しか取得することができません。ですので”4″の部分を動的に変化させる必要があります。ここではユーザのプライマリーキーを指定しますので、ユーザクラス(MOSAUser)にプライマリーキーを取得するメソッドを追加して、そのメソッドをバインドすることにします。
     モデル上でプライマリーキーをクラスプロパティに指定している場合は、メソッドを追加する必要なく直接プライマリーキーの値にアクセスすることができますが、クラスプロパティに指定していない場合は次のようなメソッドを追加することによりプライマリーキーを取得することができます。objectForKeyの引数で指定している”mosaUserId”はプライマリーキーの名前です。

         public Number primaryKey() {
              NSDictionary primaryDict = EOUtilities.primaryKeyForObject(
                                                    editingContext(), this);
              if(primaryDict != null) {
                   return (Number)primaryDict.objectForKey("mosaUserId");
              }
    
              return null;
         }

     これで各ユーザのプライマリーキーにアクセスできるようになりましたので先ほどのidのバインドを次のように書き換えます。このときmosaUserItemはいずれかのユーザのオブジェクトになります。

    ?id = mosaUserItem.primaryKey;

     これでダイレクトアクションを呼び出すURLにパラメータを追加し、特定のユーザ情報が表示できるようになりました。
     今回は1組のパラメータしかURLに追加しませんでしたが、複数のパラメータも指定できます。WOHyperLinkには”queryDictionary”というattributeが用意されていますが、ここにDictionary型の変数をバインドすればkey-valueのペアをパラメータとして指定することができます。

    *1 wodファイルの形式で表記しています。

    SqueakではじめるSmalltalk入門   第53回  鷲見 正人

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、単に複数の仮想的なデスクトップを提供することだけにとどまらない「プロジェクト」が担う、他の二つの役割についてです。

    ▼チェンジセットの自動切り換え機構としてのプロジェクト
     第50回でご紹介したとおり、チェンジセットは、システムに加えられた変更の箇所情報を管理するためのデータベースです。必要なら、いつでもいくつでも自由に作ることができますが、実際にシステム改変箇所に関する情報が記録されてゆくのは、原則として“デフォルト”として定められたチェンジセットに限られます。

     どのチェンジセットを“デフォルト”にするかについては、じつは、デスクトップ(つまり、プロジェクト)ごとに割り振ることができるようになっています。したがってユーザーは、チェンジソーターなどの専用ツールを使っていちいち明示的にせずとも、ただデスクトップ(プロジェクト)を切り換えるだけで、暗黙のうちにシステム改変の記録先であるチェンジセットの変更も同時に行なうことが可能なわけです。

     仮想デスクトップのような機構に「プロジェクト」などという似つかわしくない名前がついている理由は、この「チェンジセットとの連携」にあると言えそうです。Xcodeでは開発の作業単位である“プロジェクト”をファイル(あるいは関連ファイルを収めたフォルダ)として管理していますが、Squeakでは、そうした“プロジェクト”ひとつひとつに専用の仮想デスクトップという「作業スペースのメタファ」と、チェンジセットという「作業内容を裏で自動的に蓄積するデータベース」を割り当てている…というようなイメージでとらえていただければSqueakのこのプロジェクトという名前に対する違和感も、多少は払拭できるのではないでしょうか。

     なお、Squeakのような古典的Smalltalk、つまりALTOのOSだったころの性格を色濃く残しているSmalltalkシステム(暫定ダイナブック環境)において、ソフトウエア開発とは、システムの拡張や改変の作業に他なりません。したがって、ソフトウエアも、Macをはじめとする現在主流のコンピュータシステムでは主に「実行可能なファイル」のかたちであるのに対し、古典的なSmalltalkではいわゆる“パッチ(差分情報)”のかたちで配布され、利用者は自分の仮想イメージにそれを読み込んで(ファイルインして)機能させるスタイルをとります。このパッチは、プロジェクトごとの作業内容を逐一記録した対応するチェンジセットをファイルアウトすることで、容易に得られます(拡張子は「.cs」)。

     新しいプロジェクトを作ると、自動的に新しいチェンジセット(日本語では「名無しX」、英語では「UnnamedX」。Xは数字)が作られ関連づけられ、その名前が、そのまま新しいプロジェクトの名前としても使われます。なお、チェンジソーターなどを使ってデフォルトのチェンジセットを切り換えたときは、プロジェクトの名前もそれに伴って変わります。逆に、プロジェクトビューでプロジェクト名を変えたときは、そのプロジェクトの関連付けられているチェンジセットの名前も同様に変更されます。複数のデスクトップでひとつのチェンジセットをデフォルトとして共有することはできません。

    ▼デスクトップのモーフを保存する機構としてのプロジェクト
     Squeakのプロジェクトには、チェンジセットを視覚的に切り換える役割のほかにも、もうひとつ、古典的なSmalltalkシステムにはないSqueak独自の機能が与えられています。それは、デスクトップに配置されたオブジェクト「モーフ」をそのままの状態でファイルとして出力する機能です。

     モーフとは、数値やデータベースのような抽象的なオブジェクトではなく、丸や四角など、我々の目に見える“姿”を持った具象的なオブジェクトのSqueakシステムにおける呼称です。もとは、1990年代初頭にSmalltalkにインスパイアされて作られた「SELF」というオブジェクト指向環境向けに考案されたものですが、当初ビットマップ画像しか扱えなかったSqueakにマルチメディア機能を強化する目的で、開発の比較的早い時期に、Squeakプロジェクトに合流したオリジナルの考案者自らの手で移植され組み込まれました。簡単には、互いに連携が可能な仕組みを持つドロー系ソフトの基本図形オブジェクトのようなものを想像してもらえればよいと思います。

     Squeakには、これらモーフに対して、動きや性質を変化させる指示をプログラムとして付加できる、非プログラマ向けのスクリプトシステムが「eToys」として提供されています。ユーザーは、デスクトップをキャンバス代わりにして、モーフを好きなように配置し、それらに動きをあたえることである種のソフトウエア作品を組み立てることが可能です。こうして作られた作品は、もちろん、仮想イメージに保存することは可能ですが、ひとつの作品の保存場所に巨大な仮想イメージをそのつど用いるというのは、現実的ではありません。そこで、Squeakのプロジェクトには、デスクトップの様子をそのままファイルとして出力し、別の仮想イメージでそれを読み込み再現できるような機能が追加されました。

     一見、単なる仮想デスクトップに過ぎないSqueakのプロジェクトですが、Smalltalk言語によるソフトウエア開発ではチェンジセットと連携することで、また、eToysによるデジタル創作においては、作品のキャンバス代わりになることで、実は「プロジェクト」という名に相応しい機能を提供しているわけです。

    バックナンバー:
    http://squab.no-ip.com:8080/mosaren/

    ニュース・解説

    今週の解説担当:木下 誠

    クリスマス休暇を前にして、Apple Developer Connectionの動きは、ほとんどなくなっています。来年の始めにあるExpoをにらんで、ひとまず静けさを保っているという状態でしょうか。

    ———————————————————————-
    QuickTimeで、ムービーから音声を取り出す方法
    ———————————————————————-

    QuickTime 7のAPIを使って、ムービーから音声を取り出す方法を解説したドキュメントが公開されました。音声を、生のPCMとして取り出すことができます。

    これにより、iTunesのビジュアルエフェクトに使われているように、音声を可視化したり、Core Audioの信号処理を使って、音声の加工などが、行えるようになるようです。ドキュメントでは、ステップ・バイ・ステップで、ていねいに処理の手順を説明しています。

    Using the Audio Extraction API in QuickTime 7
    http://developer.apple.com/quicktime/audioextraction.html

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

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

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

    2005-12-20

    目次

    • 「WebObjects Dev Report」     第33回  田畑 英和
    • 藤本裕之のプログラミング夜話 #82
    • 高橋真人の「プログラミング指南」  第80回
    • ニュース・解説                小池 邦人

    「WebObjects Dev Report」  第33回  田畑 英和

     前回、前々回とセッション、アプリケーションの処理について解説してきましたが、今回はダイレクトアクションの解説をしたいと思います。ダイレクトアクションについてはその呼び出し方などを以前解説済ですが、今回はダイレクトアクション内部の実装方法について紹介します。

     単純なダイレクトアクションには次のようなものがありますが、こちらのダイレクトアクションは”Main”ページを呼び出すだけの単純な処理です。

    ・単純なダイレクトアクションの例

         public WOActionResults defaultAction() {
             return pageWithName("Main");
         }
    


     このようなダイレクトアクションでは、いつも同じ処理しかおこないませんが、ダイレクトアクションにパラメータを渡すことによって、たとえば任意の条件での検索処理などが可能になります。
     ビジネスマッチングシステムでは特定のユーザの情報を表示するという処理をダイレクトアクションでおこなっていますが、これを例に処理の実装方法をみていきましょう。

    ・パラメータをともなうダイレクトアクションの例

         public WOActionResults browseCareerAction() {
              String mosaUserId = request().stringFormValueForKey("id");
              MOSAUser selectedUser = findUser(mosaUserId);
    
              if(selectedUser != null) {
                   WOComponent nextPage = pageWithName("UserCareer");
                   nextPage.takeValueForKey(selectedUser, "selectedUser");
    
                   return nextPage;
              }
    
              return browseAction();
         }
    


     まずパラメータの取り出し方ですが、セッションをもった通常のアクションでは、あらかじめWebObjects Builder上でバインドしておいた情報に基づいて自動的にパラメータの処理がおこなわれます。一方ダイレクトアクションではパラメータを直接操作する必要があります。
     HTTPで渡されるパラメータはkey=valueの形式になっていますが、リクエストデータからkeyを指定してvalueを取り出す必要があります。この処理をおこなっているのが次のコードになります。

    String mosaUserId = request().stringFormValueForKey(“id”);

     このときkeyとして”id”を指定し、request()が返すWORequestのインスタンスからvalueを取り出しています。valueを取り出すにはWORequestのメソッドのstringFormValueForKey()を使用していますが、このメソッドはString型としてvalueを返してくれます。formValueForKey()というよく似た名前のメソッドもありますが、こちらはObject型でvalueを返します。
     パラメータが複数ある場合は、必要に応じてそれぞれのvalueを取り出すことになります。なおパラメータがPOSTでクライアントから送信されてきた場合でも、GETで送信されてきた場合でも、同じコードの処理で対応できます。

     次の処理はfindUser()を使って、パラメータで指定されたidをもとにユーザの検索をおこなっています。findUser()の実装は次のようになっています。

         private MOSAUser findUser(String mosaUserId) {
              EOQualifier qualifier = EOQualifier.
                 qualifierWithQualifierFormat(
                     "mosaUserId = %@",
                     new NSArray(Integer.valueOf(mosaUserId)));
              EOFetchSpecification fetchSpec =
                 new EOFetchSpecification("MOSAUser", qualifier, null);
    
              EOEditingContext ec = new EOEditingContext();
              ec.lock();
              NSArray results = ec.objectsWithFetchSpecification(fetchSpec);
              ec.unlock();
    
              if(results != null && results.count() == 1) {
                   return (MOSAUser)results.objectAtIndex(0);
              }
    
              return null;
         }
    


     これは通常の検索処理ですが、ダイレクトアクションではEditingContextの使い方に注意する必要があります。セッションをもたない場合にはセッションが提供するdefaultEditingContextを使用することができませんので、明示的にEditingContextを生成して処理をおこなう必要があります。
     またセッションとdefaultEditingContextを使用すると、EditingContextのロックを自動的におこなってくれますが、ロックの処理も明示的に行う必要があります。
     ユーザが1人だけ検索された場合には、そのユーザをセットしてUserCareerページに移動し、もし検索できなかった場合にはbrowseAction()メソッドを利用して別のページに移動しています。

     このようにダイレクトアクションでは、パラメータの処理を実装する必要があったり、EditingContextを用意する必要がありますので、コードの量は若干多くなります。それでは、次回はダイレクトアクションへのパラメータの指定方法について解説します。

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

     では前回の続き。Interface BuilderのNSWindow Inspector、Attributesで指定できる項目を追ってみる。Auto Save Nameの下には「Title Bar Controls」として3つのチェックボックスがある。……まぁこれの説明は要りませんな、タイトル・バーの左上に並ぶ、赤(クローズ)、黄色(ミニマイズ)、緑(ズーム)のボタンを活かすか殺すかのスイッチであり、このタイトルバー自体を持たないウィンドウはInterface Builderだけで作ることはできないんであった。
     その次に並んでいるのが「Window Backing」というラジオボタン3つ。これも既にみたように、ウィンドウの描画の仕方を指定する。覚えてますかね。

     その下にいろいろとチェックボックスが群れをなしているんだが、これらを一個ずつ検証して行こうというわけだ。
     まず最初、「Release when closed」というのは文字通り、クローズされたときにこのインスタンスをリリースしてしまうという意味だろうが、どんな時に指定/解除するのだろうか。例えばドキュメント・ベースのアプリケーションなどの場合、1ドキュメントがすなわち1ウィンドウを構成し、ウィンドウが閉じられればそのドキュメントが閉じられることになる。自動的にそのインスタンスが解放された方が嬉しい。それに対して例えば初期設定のパネルのような、ユーザーによって何度開かれるかわからないウィンドウの場合は、逆の方がいい。
     ……もう少し具体的に見てみようか。ウィンドウひとつにチェックボックス1個、ボタン2個を並べ、チェックボックスを「□Release when closed」とする。ボタンはそれぞれ「Close」と「OrderOut」。NSObjectのサブクラスをひとつ作り、そいつのIBOutletとして、このウィンドウ本体とチェックボックスを連結。IBActionとして以下の4つを定義する。

    -(void) closeWindow:(id) sender {
        [ourWindow close];
    }                          // 当然、「Close」ボタンに連結
    
    -(void) orderOutWindow:(id) sender {
        [ourWindow orderOut:self];
    }                          //  「OrderOut」ボタンに連結
    
    -(void) toggleReleaseFlag:(id) sender {
        [ourWindow setReleasedWhenClosed:
                ([sender state] == NSOnState) ? YES:NO];
    }                            // チェックボックスに連結
    
    -(void) openWindow:(id) sender {
        [ourWindow orderFront:self];
    }                            // メインメニューのFile->Openに連結
    


    あと、Interface Builderでの設定を起動時にチェックボックスに反映するための以下のコードを書けばテストの準備完了。

    - (void) awakeFromNib {
        [ourCheckBox setState:([ourWindow isReleasedWhenClosed] == YES) ?
                                                        NSOnState:NSOffState];
    }

     さぁ、実験開始。まずはチェックボックスの状態に構わず「OrderOut」ボタンと「Open」メニューを交互に実行してみる。当然ながらこの場合、「OrderOut」でウィンドウが画面から消え、「Open」で再び現れる。次にチェックボックスを「オフ」、すなわち「Close時にウィンドウを解放しない」状態にして「Close」ボタンから「Open」のワンツーパンチ。この場合も「Open」でウィンドウは再び開く。
     ではいよいよ本日のメインイベント、チェックボックスをオンにして同じ手順をやってみると……、ああ残念ながら紙幅が尽きた。どうなるか知りたい人はやってみること。知りたいけどやるのは面倒なヒトは2006年正月の新年特大号(つうのがあるのか)を待て(笑)!
    (2005_12_15)

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

    UNIXとしてのMac OS X

    〜Perlについて(26)〜

     こんにちは、高橋真人です。さて前回学んだPerlにおけるファイル処理のオーソドックスなパターンを、早速以前の正規表現処理に応用してみましょう。
     以前の処理は以下のようなものでした。

    $file_path = '/Users//Desktop/data.txt';
    open IN, "$file_path" or die;
    
    $data = join "", <IN>;
    
    while ($data =~ m/(¥d+¥.¥d+¥.¥d+[^¥t]*)¥t([^¥t]+)¥t(.+)¥n/g) {
         print "日付:" . $1 . ", 内容:" . $2 . ", 状況:" . $3 . "¥n";
    }
    
    print "Done¥n";
    


     この例では、join “”, <IN>というように、<>演算子をリストコンテキストで使っているため、ファイルの内容がリストとして(リストにはファイルの各行が入ります)一挙に読み込まれてしまいます。ですから、サイズの大きいファイルの場合にはメモリーへの圧迫も大きくなります。
     では早速、これをPerlのオーソドックスな処理に変えてみましょう。

    $file_path = '/Users//Desktop/data.txt';
    open IN, "$file_path" or die;
    
    while (<IN>) {
         chomp;
         if (/(¥d+¥.¥d+¥.¥d+[^¥t]*)¥t([^¥t]+)¥t(.+)/) {
              print "日付:" . $1 . ", 内容:" . $2 . ", 状況:" . $3 . "¥n";
         }
    }
    print "Done¥n";
    

     ところで、もしかしたら以前もトラブった方がおいでかもしれませんが、今のMacでPerlを使う場合、これはUNIXの領域になるので、ファイルの改行コードはLF(0x0a)でなければなりません。CR+LF、つまりWindowsタイプの場合では、CR(0x0d)がゴミとして邪魔をするだけですが、Mac本来のCRを使ったテキストファイルは、UNIX系のソフトからはすべてが1行につながった状態に見えてしまうので、うまく行かないのです。
     それと、Perlスクリプトとデータファイルのエンコードは、共にUTF-8にする必要があるかもしれません。この連載の本文はシフトJISを使用しているために、いわゆるバックスラッシュを¥マークにしてありますが、スクリプトをUTF-8にした場合には、ここもバックスラッシュに打ち替える必要があるかもしれません。
     単にこれだけのことをするのに、前提条件がいろいろと出てくるのがテキスト処理の厄介な点の一つなのかもしれません。テキスト処理を中心に仕事をしている人なら、一度ならずも「あーあ、何で日本人に生まれてしまったかなぁ」と嘆いた経験があるのではないでしょうか(笑)

     さて、本題に戻ります。
     書き替えた方のスクリプトでは、if文を使って、いちいち条件判断をしているので少し冗長に見えるかもしれません。ですが、Perlの場合、if以下を後ろに持ってきて、

    print “$n” if ($n < 10);

    などというような書き方ができるので、幾分すっきりさせることはできます。
     さらに、Perlではダブルコーテーションで囲った文字列の中には変数を埋め込めますから、上記のprint文は、以下のように書くこともできます。

    print "日付:$1, 内容:$2, 状況:$3¥n";

     こうすると、ずっとコンパクトになって読みやすくなりますね。
     それと、書き替えたスクリプトでもう一つ注目すべきなのは、正規表現の部分が単にスラッシュで囲まれただけになっていることです。以前にも触れたと思いますが、m//演算子は、検索の対象が$_の場合には、=~演算子で検索対象を明示する必要がありませんし、さらに 'm' も書かなくてもよいのです。というより、むしろPerlで正規表現を書く場合、m を書くことの方が少ないかもしれません。
     さて、以上で処理はだいぶオーソドックスになってきましたが、あと一つ。読み込むデータをスクリプトに直接埋め込んでしまっているのでは、余りにも汎用性がなさ過ぎますので、次回はファイル名を動的に与えるやり方についての解説をします。

    ニュース・解説

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

    Carbon ドキュメント & サンプル & SDK ナビゲーション(2005/12/16)

    【開発環境】

    今回もApple側からのネタがありませんので(笑)MOSA会員専用掲示板(MOSAdeBB)に登録された興味深いスレッドをご紹介しておきます。まだMOSAdeBBをのぞいたことのない会員の方は、ぜひお立ち寄りください。

    http://www.mosa.gr.jp/bb/modules/newbb/

    【談話室】フォーラムから…

    「皆さんの環境は?」

    MOSAのメンバーがどんな開発環境で作業をしているのかと言う質問が上がったのをきっかけに、話はC++からOOPへと幅広く展開しております(笑)。

    【プログラミング技術Q&A 中・上級】フォーラムから…

    「WebKitが作成するキャッシュファイル」

    CarbonからWebKitを利用した時、自動で作成されるキャッシュファイルの取り扱いについての質疑応答です。

    「DataBrowserでCheckBoxをあとからEditableにする方法」

    CarbonのDataBrowserで「check box」を使う場合についての考察です。対象APIの機能チェックには最新のサンプルを利用しましょうという教訓付き(笑)。

    「Xcodeでプロジェクト名と別のプロダクト名にするには?」

    Xcodeで開発する場合のプロジェクト名とプロダクト名の設定の仕方について解説されています。

    「Carbon Font Panelで文字カラー」

    Carbonから「Font Panel」を利用する場合、そこから文字カラーの情報を得る方法が説明されています(Mac OS X 10.4.3から可能になったもよう)。

    「Quartzでindexed color は?」

    Quartz 2Dでは、indexed color(カラーパレット256色)の取り扱いはどうなっているのかという話題が取り上げられています。

    「読み取り専用とファイルのロック」

    PosixPermissionsでファイルの読み取り専用を判断する方法と、Finderでのロックを検出するCocoaメソッドはあるのか? という質問を軸に、ファイル処理回りの話題が展開しています。

    【プログラミング技術Q&A 入門・初級】フォーラムから…

    「スクリーンキャプチャ」

    Macintoshのスクリーンを高速にキャプチャする方法について、いくつかのヒントが書き込まれています。こうした処理では、マウスカーソル画像が同時にキャプチャできない点がボトルネックになるもよう。

    「Cのリファレンス本」

    メンバーの方々が推薦されるCのリファレンス本の話題です。

    「CrossDevelopment」

    Xcode 2.2を利用し、Mac OS X 10.3.Xや10.2.Xなどの旧バージョンOSで問題なく起動するアプリケーションを開発する方法について考察されています。色々と制限があるようですので要注意!

    「pascalってなんでしょう?」

    Carbon Framworkにおいて、ルーチンの先頭に「pascal」と定義されているコールバックルーチンがありますが、その「pascal」の意味が何であるのかが解説されています。そこには意外な顛末が….。

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

    前回から12月16日の期間中、Apple社のDocumentationサイトには数多くのドキュメントが登録されました。ただし、大部分は今までの内容のマイナーチェンジです。今回は、その中で初版と内容が大幅変更になったドキュメントだけをピックアップしました。今回の初版は「DVD Playback Services Programming Guide」のみですね。また、デベロッパー向け読み物も5つ登録されました。Xcode関連の読み物が3つ登録されています。そろそろエンジンをかけなさいと言うApple社からの暗黙の圧力でしょうか(笑)。「Moving Your Project from CodeWarrior to Xcode」については、前号の木下さんの記事も参照してみてください。

    「Apple Human Interface Guidelines」(PDFあり)
    「Dashboard Programming Topics」(PDFあり)
    「Dashboard Tutorial」(PDFあり)
    「DVD Playback Services Programming Guide」(初版)(PDFあり)
    「Process Manager Reference」(PDFあり)
    「Search Kit Programming Guide」(PDFあり)
    「Universal Binary Programming Guidelines, Second Edition」(PDFあり)

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

    「Working with Xcode Build Settings」(読み物)

    http://developer.apple.com/tools/xcode/xcodebuildsettings.html

    「Salon Transcripts Exploits Benefits of Mac Advantages」(読み物)

    http://developer.apple.com/business/macmarket/salontranscripts.html

    「Moving Your Project from CodeWarrior to Xcode」(読み物)

    http://developer.apple.com/tools/movingfromcodewarrior.html

    「Getting Control with Subversion and Xcode」(読み物)

    http://developer.apple.com/tools/subversionxcode.html

    「Sound of Opportunity: The Audio Units Community Takes Off」(読み物)

    http://developer.apple.com/audio/audiocommunity.html

    前回から12月16日の期間中、新規テクニカルノートはひとつも登録されませんでしたが、新規テクニカルQ&Aは2つ登録されました。「How can I handle smooth mouse wheel scrolling?」の方については、前号の木下さんの記事を参照してみてください。

    QA1180「Is dlopen available on all versions of Mac OS X?」
    QA1453「How can I handle smooth mouse wheel scrolling?」

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

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

    前回から12月16日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードがひとつも登録されませんでした。

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

    【デベロップメント SDK】

    前回から12月16日の期間中、Apple社のSDKサイトには新しいSDKがひとつも登録されませんでした。

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

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

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

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

    2005-12-06

    目次

    • 「WebObjects Dev Report」    第32回  田畑 英和
    • 小池邦人の「Carbon API 徒然草」
    • SqueakではじめるSmalltalk入門  第52回  鷲見 正人
    • ニュース・解説               木下 誠

    「WebObjects Dev Report」  第32回  田畑 英和

     以前紹介しましたEclipse上でWebObjectsの開発を可能にする「WOLips」ですが、着実にバージョンアップがおこなわれ、最新版では.woの編集までできるようになってきました。Javaの開発環境としてはすっかりおなじみになったEclipseですが、ぜひ最新版のWOLipsもチェックしてみてください。
     「WOLips」に関する最新情報はMLでチェックすることができます。英語でのMLになりますが、活発なメールのやりとりがなされています。

    ・ML
    http://objectstyle.org/woproject/lists.html

    Application.java

     前回はセッションの使い方について解説しましたが、今回はアプリケーションの使い方について解説したいと思います。アプリケーション全体の処理を実装するにはApplication.javaを使用し、このクラスのインスタンスは、アプリケーションプロセス内で1つしか生成されません。
     このクラスに実装する処理としてはまずはアプリケーションの初期化処理が考えられます。ビジネスマッチングシステムでの初期化処理は次のような実装になっています。

         public Application() {
             super();
             System.out.println("Welcome to " + this.name() + "!");
    
             /* ** Put your application initialization code here ** */
              // Encoding
              WOMessage.setDefaultEncoding("UTF-8");
    
             // Request Handler
             setDefaultRequestHandler(
                 requestHandlerForKey(directActionRequestHandlerKey()));
         }
    


     super()の次の行のSystem.out.printlnはプロジェクト生成時に自動的に追加されたコードで、アプリケーション名を出力するためのものです。このコードを実行すると次のような出力が得られます。

    Welcome to MOSAJobMatch!

     ここで「MOSAJobMatch」にはアプリケーション名が表示されています。アプリケーションをXcodeから実行したときにはプロジェクト名がそのまま表示されますが、DeploymentしたときにはMonitor上で設定したアプリケーション名が表示されます。
     自動生成されたコードではアプリケーション名を表示するだけですが、これに加えてアプリケーション固有の情報を表示するようにしておけば、ログに記録することができます。例えば独自に定義したアプリケーションのバージョン番号などの表示を追加しておくと便利です。

     次の処理からは、あとから独自に追加したコードです。まずはエンコーディング関連の処理をおこなっています。WebObjectsアプリケーションはデフォルトの状態では”ISO8859_1″を使ってエンコーディング処理をおこないます。ここでのエンコーディング処理とはアプリケーションとWebブラウザ間でのエンコーディング処理のことです。アプリケ−ション本体はJavaですのでUnicodeベースでの処理がおこなわれますが、Webブラウザ上で使用するエンコーディング(一般的にはHTMLで使用するエンコーディング)は個別に設定することができます。
     デフォルトの”ISO8859_1″のまま処理をおこなってしまいますと日本語が文字化けしてしまいますので、デフォルトのエンコーディングに適切なエンコーディング名を指定して文字化けの発生を防ぐ必要があります。具体的には次のようなコードを実装します。

    WOMessage.setDefaultEncoding(“UTF-8″);

     ここではエンコーディング名として”UTF-8″を指定していますが、Javaで使用できるエンコーディング名を指定することができます。現在設定されているデフォルトのエンコーディングを取得するには次のメソッドを用います。

    WOMessage.defaultURLEncoding();

     ただし、これだけではエンコーディング処理が完全ではありません。プログラム上で適切なエンコーディング処理をおこなうだけでなく、Webブラウザ側にエンコーディング名を伝える必要があります。この処理については以前の連載で紹介していますので、今回は省略させていただきます。デフォルトのエンコーディングの指定の次はリクエストハンドラーの設定ですがこちらについてもすでに解説済です。

     その他のApplication.javaでの処理としてはエラー処理があります。一言でエラー処理といいましても、いくつかの種類が考えられます。WebObjectsフレームワークでは、エラーが発生したときに表示する画面があらかじめ種類別に実装されており、デフォルトの状態ではフレームワークで実装されているエラー画面が表示されます。この画面を独自のものに差し替えるメソッドが用意されており、よく使うであろうメソッドに次のようなものがあります。

    ・セッションをリストアできなかったときのエラー処理
    handleSessionRestorationErrorInContext()
    ・Exceptionが発生したときのエラー処理
    handleException()

     handleSessionRestorationErrorInContext()は一般的にはセッションがタイムアウトされたときに呼び出されます。あと初期化とは逆に、アプリケーションが終了するときになにか処理をおこないたい場合はterminate()メソッドを利用することができます。

    小池邦人のCarbon API 徒然草(2005/12/02)

    画像ファイルをウィンドウに表示する(その6)

    今回は「画像ファイルをウィンドウに表示する」の最終回です。HIViewSetLayoutInfo()に渡すHILayoutInfo構造体について詳しく解説し、Mac OS X 10.4により、今まで解説してきた3つのルーチンの処理内容がどう変化したかを見てみます。

    Mac OS X 10.3から、あるViewが、それが埋め込まれているViewに対して、どのような位置関係を保つのかを自動制御できるようになりました。これを、HIViewの自動レイアウト機能と呼びます。自動レイアウト機能を実現するのには、前回紹介したHILayoutInfo構造体に適切な情報を記載してHIViewSetLayoutInfo()に渡します。HILayoutInfo構造体の内部構造は、HIBinding構造体、HIScaling構造体、HIPositioning構造体の3つのパートに分かれています。

    struct HILayoutInfo {        // 自動レイアウト情報構造体
        UInt32 version;          // kHILayoutInfoVersionZeroを代入(固定)
        HIBinding binding;       // Bind情報のための構造体(A)
        HIScaling scale;         // Scale情報のための構造体(B)
        HIPositioning position;  // Position情報のための構造体(C)
        };
    


    (A)Bind情報を格納するHIBinding構造体(他のViewの縁との距離を保つ)
    (B)Scale情報を格納するHIScaling構造体(他のViewとの相対サイズを保つ)
    (C)Position情報を格納するHIPositioning構造体(他のViewとの相対位置を保つ)

    Bind情報はHIBinding構造体に格納されます。HIBinding構造体には、メンバーとして4つのHISideBinding構造体が含まれており、それぞれが上下左右の縁と別のViewの縁との距離を一定に保つかどうかを指定します。Scale情報はHIScaling構造体に格納されます。HIScaling構造体には、メンバーとして2つのHIAxisScale構造体が含まれており、それぞれX方向およびY方向に対象となるViewとのサイズ比率を代入できます。Position情報はHIPositioning構造体に格納されます。HIPositioning構造体には、メンバーとして2つのHIAxisPosition構造体が含まれ、それぞれX方向およびY方向に対象となるViewとの相対位置を固定できます。

    自動レイアウト機能に用いられている各構造体の詳しい役割については、以下のサイトに「HIView Programming Guide」の日本語要約がありますので、そちらとヘッダファイルのHIView.hを参照してみてください。

    http://www.mosa.gr.jp/?p=464

    以下が、Mac OS X 10.4では不必要となった処理を外したsetupViwerWindow()ルーチンです。ウィンドウのズーム処理のために制限サイズを保存していたSetControlMinimum()やSetControlMaximum()はもう必要ありません。また、SetControlID()でセットしていたControl IDやSignatureも利用しないので処理が省略されています。

    short setupViwerWindow( WindowRef window,CGImageRef image )
    {
        HIViewRef    iview,sview,cview;
        short        ret=1;
        HISize       hmax;          // ウィンドウサイズの制限を代入するのに用いる
        Rect         drt;
        HIRect       vrt;
    
        hmax.width=CGImageGetWidth( image )+15;     // ウィンドウの最大幅を代入
        hmax.height=CGImageGetHeight( image )+15;   // ウィンドウの最大高さを代入
        SetWindowResizeLimits( window,NULL,&hmax ); // リサイズの限界を設定する
        if( ! HIScrollViewCreate( kHIScrollViewOptionsVertScroll|
                                         kHIScrollViewOptionsHorizScroll,&sview ) )
                           // 縦横スクロールバーを持つScrollViewを作る
        {
            HIViewSetVisible( sview,1 );      // ScrollViewを表示可に切り替える
            HIViewFindByID( HIViewGetRoot(window),kHIViewWindowContentID,&cview );
                                              // 画像ウィンドウのContentViewを得る
            HIViewAddSubview( cview,sview );  // ScrollViewをContentViewに埋め込む
            GetWindowPortBounds( window,&drt ); // ウィンドウの矩形枠を得る
            vrt.origin.x=vrt.origin.y=0.0;
            vrt.size.width=drt.right-drt.left;
            vrt.size.height=drt.bottom-drt.top;
            HIViewSetFrame( sview,&vrt );       // ScrollViewのフレームサイズを設定
            HIViewSetLayoutInfo( sview,&s_layout ); // 自動レイアウト情報を設定する
            HIImageViewCreate( image,&iview );  // ImageViewを作成する
            HIViewSetVisible( iview,1 );        // ImageViewを表示可に切り替える
            HIViewAddSubview( sview,iview );    // ImageViewをScrollViewに埋め込む
            ret=noErr;
        }
        return( ret );
    }
    


    Mac OS X 10.4ではウィンドウのズーム処理も省略することができます。よって最終的には、setupViwerWindowEvent()で用意するEventTypeSpecは2種類まで減らすことが可能になりました。また、myViwerWindowEventHandler()の方も、Mac OS X 10.4対応で簡素化されています。

    void setupViwerWindowEvent( WindowRef window )
    {
        EventTypeSpec    list[]={
                                  { kEventClassCommand,kEventCommandUpdateStatus },
                                  // メニューのアップデートを確認
                                  { kEventClassWindow, kEventWindowClose }
                                  // ウィンドウのクローズボタン(閉じる)に対応
                                };
    
        InstallWindowEventHandler( window,myViwerWindowEventHandler,
                                       GetEventTypeCount(list),list,window,NULL );
                    // 2種類のCarbon Eventに対応するCarbon Event Handlerを実装する
    }
    
    pascal OSStatus myViwerWindowEventHandler( EventHandlerCallRef myHandler,
                                                    EventRef event,void *userData )
    {
        short            ret=eventNotHandledErr;
        WindowRef        wptr=NULL;
        unsigned long    ekind;
        short            part;
        long             cls;
        HICommand        cmd;
        Point            pt;
    
        cls=GetEventClass( event );  // イベントクラスを得る
        ekind=GetEventKind(event);    // イベントの種類を得る
        if( cls==kEventClassCommand ) // イベントクラスがkEventClassCommandの場合
        {
            switch( ekind )
            {
                case kEventCommandUpdateStatus: // メニューのアップデートを確認
    
                    GetEventParameter( event,kEventParamDirectObject,typeHICommand,
                                                NULL,sizeof(HICommand),NULL,&cmd );
                                                // 選択されたメニューの情報を得る
                    ret=mainteViewerWindowMenu( wptr,cmd.menu.menuRef );
                                                // メニューメンテナンス自作ルーチン
                    break;
            }
        }
        else if( cls==kEventClassWindow ) // イベントクラスがkEventClassWindowの場合
        {
            GetEventParameter( event,kEventParamDirectObject,typeWindowRef,NULL,
                                                    sizeof(WindowRef),NULL,&wptr );
                                          // 対象となるウィンドウのWindowRefを得る
            switch( ekind )
            {
                case kEventWindowClose: // ウィンドウのクローズボタンに対応
    
                    disposeMyWindow( wptr ); // ウィンドウを破棄する自作ルーチン
                    ret=noErr;
                    break;
            }
        }
        return( ret );
    }
    


    前回も紹介しましたが、Mac OS X 10.4になり、SetWindowResizeLimits()で設定したサイズ限界が画像ウィンドウのズーム処理にも適応されるようになりました。そのおかげで、Event HandlerのkEventWindowZoom処理を実装する必要がなくなりました。最終的に残ったのは、ウィンドウを閉じる処理のみです。画像ウィンドウに関する処理は、ほとんどシステム側のStandard Event Handlerが行ってくれることになり、開発者側で用意する処理ボリュームはかなりダイエットされたことになります(笑)。

    次回からは、本サンプルアプリケーションのUniversal Binary化(インテルCPU対応)について解説していきたいと思います。まずは、現在の開発プロジェクトをMetrowerks CodeWarriorからXcode 2.2へ移植する話からスタートしたいと思います。

    つづく

    SqueakではじめるSmalltalk入門   第52回  鷲見正人

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、前回のチェンジセットに絡めて、SqueakシステムやSmalltalk-80システムなど、比較的古典的なSmalltalkシステムに備わっている仮想デスクトップ機能「プロジェクト」を取りあげます。

    ▼仮想デスクトップとしてのプロジェクト
     すでに何度か述べているように、1981年にデビューする以前の1970年代、Smalltalkシステムは、試作機ALTOを世界初の本格的GUIベースのパーソナルコンピューティングシステムである“暫定ダイナブック”として機能させるためのOSとしての役割を担っていました。ゴミ箱アイコンこそありませんでしたが、複数のウインドウを開く場としてのデスクトップは、1970年代半ば頃にはすでにSmalltalkシステムに備えられていた機能のひとつです。同じXEROXのStarシステムよりも5年、Macintosh誕生から遡れば10年近くも前のことです。

     さらに、Smalltalkシステムの先進性は単にデスクトップを備えていた…ということだけにとどまりません。1970年代後半には、複数のデスクトップを作成し、それらを自由に行き来できる機能もすでに用意されていたのです。なんとも驚きですね。この仮想デスクトップ機構が、今回紹介する「プロジェクト」です。

    ▼プロジェクトの作成と切り換え、任意のプロジェクトへの移動
     新しいデスクトップ(プロジェクト)を作るには、デスクトップメニューから「開く」→「モーフィック・プロジェクト」を選択します(英語ではopen…→morphic project)。すると、画面に「名無しX」(英語ではUnnamedX。Xは数字)という名前の小さなウインドウが現われます。これは「プロジェクトビューウインドウ」と呼ばれるもので、デスクトップの最近の様子を現わしたサムネイルを表示したり、実際にそのプロジェクトへデスクトップを切り換えるのに用いられます。作成直後は、まだサムネイルは表示されず、ウインドウの“地”の色(オレンジ色)のままです。

    [fig.A]新規に作成されたプロジェクトウインドウ
    http://squab.no-ip.com:8080/mosaren/uploads/52a.png

     新しく作ったプロジェクトを画面に呼び出すには、プロジェクトビューウインドウ内にマウスポインタを合わせ、そこでクリックします。あるいは長押しをしてメニューをポップアップさせ、enter this projectを選んでも同じです。それまでのデスクトップが消え、代わりにまっさらなデスクトップが現われます(後ほどサムネイルの効果を確認しやすいように、ここでいくつかのウインドウを開いておくとよいでしょう)。元のプロジェクトに戻るには、デスクトップメニューから「前のプロジェクト」(英語ではprevious project)を選びます。

    [fig.B]ひとつ前に開いていたプロジェクトに戻る
    http://squab.no-ip.com:8080/mosaren/uploads/52b.png

     戻ってくると、それまで表示されていたデスクトップの様子がサムネイルとしてプロジェクトビューウインドウ内に描かれているはずです。先ほど、プロジェクトにenterする際に、プロジェクトビューの中央付近をクリックしましたが、下の「名無しX」の部分をクリックして選択状態にしてタイプすると、プロジェクトの名前を付け替えることができます。

    [fig.C]プロジェクトの名称変更
    http://squab.no-ip.com:8080/mosaren/uploads/52c.png

     プロジェクトは入れ子にしていくつでも作成可能です。また、親子関係にないプロジェクト間も自由に行き来できます。任意のプロジェクトにジャンプするには、デスクトップメニューから「プロジェクトへジャンプ」(英語ではjump to project…)を選び、ポップアップしてサブメニューから移動したいプロジェクトを選択します。

    ▼プロジェクトビューの追加と削除、プロジェクトの削除
     プロジェクト作成時に作られるウインドウ型のプロジェクトビュー(プロジェクトビューウインドウ)のほかにも、既存のプロジェクトにenterするためのプロジェクトビューをいくつでも、どのプロジェクト(デスクトップ)にも作ることができます。ドラえもんでいうならどこでもドア、MacのFinderでいうなら“エイリアス”のようなものですね。デスクトップメニューの「新しいモーフ…」→「プロジェクトへのリンクを作ります…」(英語では、new morph… → make link to project…)で、ちょっと大きめのアイコンのようなプロジェクトビューが現われるので、そのまま好きな場所でクリックして設置してください。

    [fig.D]アイコン型のプロジェクトビュー
    http://squab.no-ip.com:8080/mosaren/uploads/52d.png

     このアイコンのようなプロジェクトビューは、cmd-ドラッグで好きな場所に移動したり、cmd-クリックで選択し、×ボタンをクリックすることで削除もできます。

    [fig.E]アイコン型のプロジェクトビューの削除
    http://squab.no-ip.com:8080/mosaren/uploads/52e.png

     これら“エイリアス”(プロジェクトビュー)とは異なり、“オリジナル”(プロジェクトビューウインドウ)は、ウインドウの形をしているのでクローズボックスのクリックで消すことができます。が、このときプロジェクト(仮想デスクトップ)の実体もシステムから削除されるので注意しましょう(警告は出ます)。ただし、削除しようとするプロジェクトにさらに別の“子”プロジェクトが作られている場合は、その旨、ポップアップで注意を促され、それら子プロジェクトたちを削除するまで削除は行えません。

    [fig.F]子を持つプロジェクトの削除を拒否するポップアップ
    http://squab.no-ip.com:8080/mosaren/uploads/52f.png

    ▼プロジェクトとチェンジセット
     さて。プロジェクトをいくつか作ってから、チェンジソーターを開いてみてください。リストの先頭に、作成したプロジェクトと同名のチェンジセットが登録されているはずです。次回は、このプロジェクトとチェンジセットの密接な繋がりについて解説します。

    バックナンバー:
    http://squab.no-ip.com:8080/mosaren/

    ニュース・解説

    今週の解説担当:木下 誠

    ———————————————————————-
    CodeWarriorからXcodeへの、プロジェクトの移行
    ———————————————————————-

    ADCにて、CodeWarriorからXcodeへの移行方法を説明したドキュメント、「Moving Your Project from CodeWarrior to Xcode」が公開されました。XcodeとCodeWarriorのプロジェクト設定の差異、CodeWarriorファイルのインポートなどが解説されています。

    Intel Macの登場もあり、事実上Xcodeが唯一の開発環境になってしまった今、この種のドキュメントの充実を望みたいところです。

    関連するWebページとして、CodeWarriorからの移行も含めて、Intel Mac対応に関するドキュメントを集めた、Developer Transition Resource Centerもあります。

    Moving Your Project from CodeWarrior to Xcode
    http://developer.apple.com/tools/movingfromcodewarrior.html

    Developer Transition Resource Center
    http://developer.apple.com/transition/index.html

    ———————————————————————-
    Carbonでのホイールイベント
    ———————————————————————-

    Technical Q&Aが1つ公開されています。Carbonでホイールマウスのイベントを扱うための方法です。

    Mighty MouseやPowerBook G4のタッチパッドなど、最近Appleハードウェアでもホイールイベントを使えるようになりました。Cocoaでは当初から利用できてましたが、Carbonでは非公開イベントを使う必要があるようです。

    QA1453: How can I handle smooth mouse wheel scrolling?
    http://developer.apple.com/qa/qa2005/qa1453.html

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

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