MOSA Multi-OS Software Artists

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

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

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

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

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

    2005-11-29

    目次

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

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

     Apple社が運営しているメーリングリストがいくつかありますが、その中にWebObjectsのメーリングリスト「WebObjects-dev」があります。Apple関係者がこのMLに書き込むこともありますが、しばらく前にiTunes Music Storeのエンジニア求人情報が出ていました。求人といえばApple社のワールドワイドな求人サイトですが、こちらはWebObjectsで構築されています。

    ・WebObjects-dev
    http://lists.apple.com/mailman/listinfo/webobjects-dev
    ・Apple社求人サイト
    https://jobs.apple.com/cgi-bin/WebObjects/Employment.woa

    Session.java

     前回までセッション管理およびDirectActionの解説をしてきましたが、今回はセッションでどのような処理をおこなうのかについて取り上げてみたいと思います。
     WebObjectsではプロジェクトを作成すると以下のようなファイルが自動的に作成されます。

    Application.java <- WOApplicationから継承
    Session.java <- WOSessionから継承
    Main.java <- WOComponentから継承

     Applicationクラスのインスタンスは1つのアプリケーションプロセス内に1つしか生成されませんが、Sessionクラスのインスタンスはクライアントから新たなアクセスがあるたびに新たに生成されます。(*1)
     Main.javaはWebページのコンポーネント用クラスでページが新たに生成されるたびにインスタンス化されます。

     それぞれのクラスの使い分けは、名前からなんとなく想像がつくかと思いますが、Application.javaにはアプリケーション全体の処理を実装します。たとえば、アプリケーション全体の初期化処理やエラー処理、あるいはアプリケーション全体で共有するようなデータ処理の実装に利用できます。
     Session.javaはセッションごとにインスタンス化されますので、例えばユーザ固有の処理の実装に利用することができます。ビジネスマッチングシステムにおけるセッション処理では以下の2つの処理をおこなっています。

    ・ログインユーザの管理
    ・テーブル行の背景色の出力

     まずユーザ管理についてですが、プロフィールなどのユーザデータを登録するにはログイン処理をおこなっています。ログイン処理に成功した後は、現在どのユーザがログインしているのかを覚えておく必要がありますので、Sessionクラスにログイン中のユーザを記録しておくための変数を用意して管理しています。
     具体的には次のようなコードになります。ユーザのためのインスタンス変数としてloginUserを宣言し、loginUser用のセッターとゲッターを実装してあります。ログイン時にログイン認証に成功したユーザをセッション上にセットし、画面上にユーザの情報を表示するときもこのインスタンス変数を用いています。

         protected MOSAMember loginUser;
    
         public MOSAMember loginUser() {
             return loginUser;
         }
    
         public void setLoginUser(MOSAMember newLoginUser) {
             loginUser = newLoginUser;
         }
    


     次にテーブル行の背景色について解説します。テーブルを画面上に表示するときには、各行を識別しやすくするために、行の背景色を交互に変化させたりします。ここでは交互に使用する背景色の指定をおこなっています。背景色を出力するコードは次のようになっています。

         public static final String oddLine = "oddLine";
         public static final String evenLine = "evenLine";
         private boolean rowFlag;
    
         public String lineClass() {
             rowFlag = !rowFlag;
             if(rowFlag) {
                 return oddLine;
             } else {
                 return evenLine;
             }
         }
    


     先に使い方から説明しますと、まず交互に背景色を変化させたいテーブルの行
    をWebObjects Builder上で選択して、Inspector上で「Make Dynamic」ボタン(左下にあります)をクリックします。
    タグをDynamic化するとダイナミックエレメントのWOGenericContainerに置き換わり、Dynamic Inspectorで値をバインドできるようになります。
     背景色を指定する方法は
    タグのAttributeで指定する方法とCSSを用いて指定する方法がありますが、CSSを使用する場合はInspector上でAttributeに"class"を追加し、そこに次のようなバインドをおこないます。

    GenericContainer1: WOGenericContainer {
        class = session.lineClass;
    }

     このときCSSでは次のような定義をおこなってあります。

    .oddLine { font-size:11pt; background-color:white; }
    .evenLine { font-size:11pt; background-color:#DDD; }

     このように設定しておくとテーブルを生成するさいに、oddLineとevenLineで指定した色がテーブル行の背景色として交互に使用されます。
     最後にコードについて解説しておきますが、実装はきわめてシンプルです。boolean型のrowFlagを宣言しておきlineClass()メソッドが呼び出されるたびにtrueとfalseが交互に入れ替わります。rowFlagがtrueの場合はoddLineを、falseの場合はevenLineをreturnするように実装してあります。
     背景色を交互に入れ替えるには、1つ前に使用した背景色がなんであったのかをどこかで覚えておく必要がありますので、それをセッション上で管理するというわけです。

     さて、今回はSesson.javaの使用方法について実例を交えて紹介しました。このようにセッション単位での処理にはSession.javaを利用することができます。

    *1 DirectActionを使えばクライアントからのリクエスト時にセッションを生成しないようにもできます。

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

     まず最初にご挨拶。猿……猿ぢゃない去る11月20日、札幌で行なわれた「MOSAカフェ@札幌」にご参加くださいました皆さん、どうもご苦労様でした。やっぱり直に顔をあわせて喋るのは楽しいですな。あんまり(全然)テクニカルな話題とかは出なかったけど、それなりに有意義な会になったと思います。

     ほんでは本題。前回までワレワレは(と読者を巻き込む書き方には多少の偽善を感じたりするんだがまぁ堪忍)、「通常、アプリケーションで使われるNSWindow のインスタンスは、Interface Builder を使って定義され、起動時にNibファイルから読み込まれて生成させる」として、その例外として「タイトルバーのないウィンドウの作り方」を見てきた。
     今回からは逆に、……一部既に説明してしまったものもあるけれど、Interface Builder でウィンドウを定義する手順を追いながら、あの中で定義するあれこれがプログラム内部でどう使われるのか、または使えるのか、という部分を地味目に追ってみようと思う。いや地味目といっても大事なことなんである。

     Cocoa プロジェクトを新規に作成し、MainMenu.nibをダブルクリックしてInterface Buider を起動すると、画面には既にひとつ、ウィンドウが作られており、クリックすることでその内容をインスペクタ・ウィンドウに表示することができる。
     この段階でインスペクタ・ウィンドウに表示されているのは上から、まず「Window Title」。これは説明不要だろう、タイトルバーに表示されるタイトルであり、デフォルトで「Window」の文字列が入っている。次が「Auto Save Name」、今回の肴はこれである。

     また昔話が始まったと笑われるのを覚悟で書くが、その昔のアプリケーションで、ユーザーが移動したウィンドウの位置、大きさを覚えている、というのはなかなか面倒なコトだった。現状とズーム時(次にズーム・ボタンが押されたとき)の位置と大きさを……ワタシの場合で言えば Rect (つう名前の構造体があったんだよ、標準で)を2つ持った構造体をそのためのリソース型として準備して、初期設定ファイルに書き込んでおいた。まぁ誰もが似たようなやり方でやっていたはずだ。
     それがCocoaでは、Interface Builder でウィンドウを作ったときに、この「Auto Save Name」の欄に、そのアプリケーションで作られるウィンドウ内でユニークな文字列を名前として定義しておきさえすれば、その保存もロードも勝手にやってくれるのである。まぁなんて便利なんでしょう、てなもんや三度笠。
     しくみは至極簡単。プログラムが終了してウィンドウが破棄されるときに、その位置や大きさが変更されていれば、初期設定ファイルに「NSWindow Frame(Auto Save Nameとして定義した名前)」というキーでそれが記録され、次のオープン時に読み込まれて使われるのである。試しに最初からあるこのウィンドウのAuto Save Nameに「MOSAWindow」と指定しただけでプロジェクトをビルド、ランし、ウィンドウを動かしただけで終了。初期設定ファイル(こんだけしかやってない場合、このファイルは「~/library/preferences/com.apple.myCocoaApplication.plist」のはず)の中身をProperty List Editorで確認してみて欲しい。

     ……と、これでおしまいではまるでビギナー向けのチュートリアルなので、使わないかも知れないけど知っておいてもいいだろう余計な話をつけくわえておく。上の機能を実現しているのは以下の3つのメッセージ。これを知っておけばInterface Builder で定義をしなくても似たようなことが可能である。……そんなことになんの意味があるのかはイマひとつ分からないけれど。

    -(void) saveFrameUsingName:(NSString*) name;

    -(BOOL) setFrameUsingName:(NSString*) name;

    -(BOOL) setFrameAutoSaveName:(NSString*) name;

    それではまた次回。
    (2005_11_24)

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

    UNIXとしてのMac OS X

    〜Perlについて(25)〜

     こんにちは、高橋真人です。さて今回はPerlにおけるファイル処理のお話です。では早速コードを見ていただきましょう。

    open IN, "test.txt" or die;
    
    while () {
         chomp;
         print $_, "¥n";
    }
    


     このコードは、単にテキストファイルを開いて内容を出力しているだけのものですが、ファイル処理の基本的な部分が含まれています。
     順に解説いたしましょう。

     まず、ファイルのオープンです。
     Perlでは、ファイルを開く場合にファイルハンドルというのを使います。ここでは「IN」というのがそれに当たります。Perlの変数は、スカラー変数は$、配列は@、ハッシュは%で始まることになっていましたが、ファイルハンドルには何も付きません。また、これは強制ではないのですが、通例としてすべて大文字にすることになっています。
     open IN, "test.txt"で、test.txtというファイルを開いて、INというファイルハンドルに結び付けることをしますが、このopenという演算子はファイルのオープンに失敗すると偽の値を返すことになっています。
     よって、C言語などでしたら、

    if (open IN, "test.txt" == 0) { ...

    といったような書き方をするところですが、Perlではこういうときには、orというのを使います。
     dieというのは、Cで言うところのexit()ないしはabort()を意味します。Perlではこうした書き方が一般的なのですが、「開け、さもなくば、死ね」という文章になっていて、非常に分かりやすいというか、面白いというか...
     ちなみに、dieのあとに、"$!"と書き添えることもよくあります。例えば上記のスクリプトを実行した場合、test.txtというファイルが見つからないと、スクリプトは、dieするわけですが、単にdieだけ書いてある場合には、"Died at test.pl line1."(test.plはスクリプトのファイル名)というメッセージを出して終了しますが、"$!"が書き添えてある場合には、"No such file or directory at test.pl line 1."と、具体的にdieした理由がメッセージとして出力されるようになります。
     さて、INというファイルハンドルに無事にファイルが結び付けられた場合、いよいよ読み込みに入るわけですが、Perlではファイルからの読み込みには<>という演算子を使用します。この演算子は、通常は<IN>というようにファイルハンドルを挟んで使用しますが、中に何も挟まずに <> とだけ記述することもありますが、今回はそれには触れません。
     そしてこの演算子は、スカラーコンテキストで使用されると、ファイルハンドルによって結び付いているファイルの先頭から、呼び出される度に1行ずつを読み取って返します。今回のようにwhileの後のカッコ内で単独で使われると、ループが繰り返されるごとに特殊変数$_の中にファイルの各行が順番に入っているというわけです。

     次に、chompです。この演算子は引数にスカラー変数をとりますが、今回のスクリプトでは引数が省略されているので、例によって$_が暗黙のうちに与えられていることになります。
     で、chomp演算子の動作ですが、実はPerlにはもともとchopという演算子があります。このchop演算子は、「文字列の末尾の文字を切り落とす」という、正にその名の通りの処理をするのですが、今回の処理のようにファイルから1行ずつ取り出してきて処理していく場合、末尾の改行が邪魔になるケースにもよく使われます。
     ところが前回も触れたように、ファイルの最終行には改行が付いていない場合がよくあります。chopを使うとそういう場合に「改行でない最後の1文字」を切り落としてしまって都合が悪いので、ifを使って末尾に改行があるかどうかをいちいち調べなければなりませんでした。しかし、たかが(?)改行を落とす処理だけのためにわざわざそのような書き方をするのは、Perlの流儀に似つかわしくないと判断したのかどうなのか、Perl 5になってからこのchompという演算子が登場したのです。
     そんなわけで、このchompという何ともユニークな名前の演算子は、「文字列の末尾が改行であった時のみ切り落とす」という、名前に劣らぬ面白い動作をする仕組みとなっています。

     で、スクリプトの最後ですが、$_の最後に改行を付け足してから出力しています。「付け足すぐらいなら、何でわざわざ改行を切り落とすのか」と思われるかもしれませんが、前述の通り、ファイルの末尾に改行が付いていなくても、このスクリプトでは「すべての行」にきちんと改行が付いて出力されるわけです。

    ニュース・解説

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

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

    【開発環境】

    MOSA会員専用掲示板(MOSAdeBB)が開設されて3ヶ月が経ちました。

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

    現在では色々な質疑応答スレッドが立ちあがり、会員同士によるディープな(笑)情報交換がなされています。今回は、そのうちいくつかの興味深いスレッドをご紹介しておきます。まだMOSAdeBBをのぞいたことのない会員の方は、ぜひお立ち寄りください。会員相互の交流、技術情報交換に大いに役立つと思われますので、皆さんバリバリ活用しましょう!以前にも書きましたが、アップル社へひとつ質問をすると、その正式な回答を得るために高額な費用が発生します。日々のソフト開発に、MOSAdeBBでの情報交換をうまく活用してみてはいかがでしょうか?

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

    「CodeWarrior Development Studio for the Mac OS X v10」
    「CodeWarrior v10のレジストレーショントラブル」

    つい最近Metrowerks社から発表されたCodeWarrior Cの最終版であると思われるv10についての情報交換がなされています。

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

    「HIViewローカルなマウスロケーションを得る方法について」

    Carbon環境でHIViewを利用する場合、そのローカルマウス位置を簡単に得る方法についての質疑応答です。話はHIViewにおけるマウス処理の問題点へと展開しています。

    「シリアル番号」

    アプリケーションからMac本体の「シリアル番号」を得るためにどのような方法があるのかの質疑応答です。Mac本体の固有情報としてEthernetのMACアドレスを使う方法やUUIDを使う方法も紹介されています。

    「消えないテンポラリーファイル」

    Spotlightが情報を読み書きするため、即座にテンポラリーファイルが削除できない問題に対して色々な解決方法が提示されています。加えて、Spotlightにより引き起こされるファイル関連の問題について情報交換もなされています。

    「NSScrollViewの中のViewを自由に操るには?」

    Cocoa環境において、NSScrollViewの中にNSViewを継承したCustomView作った場合、それをハンドリングする時の手法について色々な情報交換がなされています。

    「Mac OS X 10.4.3のFinderが画像アイコンを表示しない」

    Mac OS X 10.4.3になってから、Finder側のアイコン表示のアップデートが不安定になった問題点が紹介され、それを回避する方法がサンプルソースとして提示されています。

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

    「Carbonウインドウの再描画イベントは来なくなったのでしょうか?」

    Carbon環境において、ウインドウを表示した時の再描画のイベントの授受に関する質疑応答が展開されています。

    「iTunes、iPhoto、iMovieをAppleScriptでコントロール」

    iTunes、iPhoto、iMovieなどをAppleScriptでコントロールするための手法を解説した、良い資料や書籍についての情報交換です。

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

    前回から10月25日の期間中、Apple社のDocumentationサイトには新規ドキュメントがひとつも登録されませんでしたが、新規リリースノートの方はひとつだけ登録されました。リリースノートで紹介されている「J2SE 5.0 Release 3」については、前号の木下さんの記事も参照してみてください。

    リリースノート

    「J2SE 5.0 Release 3 Release Notes」

    http://developer.apple.com/releasenotes/

    前回から10月25日の期間中、新規テクニカルノートと新規テクニカルQ&Aはひとつも登録されませんでした。ADCへ質問メールを送付したときの返答メールによると、Apple社のテクニカル関係のメンバーは一足先にクリスマス休暇(?)を取っているようですね。ひょっとして、1月のサンフランシスコ Expoで大きな発表があり忙しくなるのを予想しての早めの休暇なのかもしれません(笑)

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

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

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

    前回から10月25日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが4つ登録されました。
    すべてのサンプルが初めての登録(初版)となりますが、どうしたことか、Windows用のサンプルが多いですね(笑)。サンプル内容については前号の木下さんの記事を参照してください。

    「NullAuthPlugin」(Security関連)(初版)
    「CreateMovie - C#」QuickTime関連)(初版)
    「CreateMovie - VB6」QuickTime関連)(初版)
    「EventMonitorTest」(Carbon関連)(初版)
    「MoviePlayer - C#」(QuickTime関連)(初版)

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

    【デベロップメント SDK】

    前回から10月25日の期間中、Apple社のSDKサイトには新しいSDKが2つ登録されました。Mac OS X 10.4.3対応の「CoreAudio SDK」と「.Mac 2.0 SDK」のDeveloper Preview 2です。

    「.Mac 2.0 SDK (Developer Preview 2)」
    「CoreAudio SDK v1.4.3」

    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=モサ伝]第184号

    2005-11-22

    目次

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

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

    WebObjects 5.3.1

     WebObjects5.3.1がリリースされましたので今回はまずこちらのご紹介から始めます。Ver 5.3からXcodeにWebObjectsの開発環境が含まれるようになりましたが、つい最近リリースされました最新版のXcode2.2にはWebObjects 5.3.1が含まれています。これまでのWebObjectsはProject Builder/Xcodeとは独立してリリースされていましたが、Xcodeに統合されたことによりXcodeのアップデートに合わせて、WebObjectsもアップデートされるようになったようです。0.0.1のアップデートではありますが、今後はXcodeの進化と共にWebObjectsもアップデートされていくのではないでしょうか。
     5.3.1での変更点についてはすでにドキュメントが出ていますので、詳細についてはこちらのほうを参照してください。開発ツールについての改良がいくつかおこなわれています。Deployment版の5.3.1については直接ダウンロードすることも可能です。

    ・WebObjects 5.3.1 Updateについて
    http://docs.info.apple.com/article.html?artnum=302797

    ・WebObjects 5.3.1 for Mac OS X Server 10.4
    http://www.apple.com/jp/ftp-info/reference/webobjects531formacosxserver104.html

     あと新しいドキュメントも公開されています。5.3からWebObjects Builderが新しくなりましたが、新バージョンに対応した「User Guide」が公開されました。また、Mac OS X Server 10.4からはデーモンの起動方法が新たに導入されたlaunchdによって管理されるようになりましたが、こちらについての記述もドキュメント「WebObjects Deployment Guide」に反映されています。具体的にはwotaskdやMonitorの起動に関する記述が追加されています。

    ・WebObjects Builder User Guide
    http://developer.apple.com/documentation/WebObjects/Conceptual/WO53_WOBuilderGuide/index.html

    ・WebObjects Deployment Guide(Starting WebObjects Service)
    http://developer.apple.com/documentation/WebObjects/Deployment/Deploying_Applications/DeploymentElements/chapter_5_section_5.html

    セッション管理の続き

     前回はセッションを用いない処理DirectActionの使用方法を解説しましたが、この処理についてもう少し詳しくみていきたいと思います。プロジェクトの新規作成時に自動的に作成されるDirectActionクラスのDirectAction.javaにはあらかじめMainコンポーネントを表示するメソッドdefaultAction()が実装されています。
     このメソッドはWOActionResults型の値を返すようになっていますが、この型はInterfaceとして定義されており、WOComponentやWOResponseによって実装されています。WODirectActionクラスでもWOComponentクラスと同様にページを生成するpageWithName()が使用できますので、コンポーネント名を引数で指定してページを生成し、生成したページをreturnすることで任意のコンポーネントに遷移することができます。

    ・defaultAction()の実装
    public WOActionResults defaultAction() {
    return pageWithName(“Main”);
    }

     最低限このpageWithName()を用いてページを返すようにすればDirectActionでページを遷移することができますが、このとき返すページの実装に注意する必要があります。DirectActionを用いる1つの理由はセッションを使用しないことですが、DirectActionが返すページの実装によっては自動的にセッションが生成されてしまう場合があります。
     生成したページ内で状態を保持する必要がある場合には、自動的にセッションが生成されますので、DirectActionを用いたからといって必ずセッションが生成されないというわけではありません。例えばページ内でForm関連のDynamic Elementを使用したり、WOHyperLinkでaction属性にバインドをおこなった場合などではページが生成されると自動的にセッションも生成されてしまいます。つまりセッションを使用したくない場合にはDirectActionを使用するだけでなく、生成するページの作り方にも注意を払う必要があるということです。

     実際にセッションが生成されたかどうかを調べる方法ですが、セッションが生成されるということはSessionオブジェクトが生成されるということですので、Session.javaのコンストラクタに次のようなコードを実装しておけばログ上でセッションの生成を確認することができます。

    public Session() {
    super();

    /* ** Put your per-session initialization code here ** */
    NSLog.debug.appendln(“New Session!! : ” + sessionID());
    }

     セッションが生成されるときにフレームワークにより自動的にセッションごとにユニークなセッションIDが割り当てられますが、このセッションIDを取得するにはWOSessionクラスのsessionID()メソッドを用います。
     ビジネスマッチングシステムでは、データを閲覧する場合にはセッションを用いずに処理をおこない、データを登録する場合にはセッションを用いるような使い分けをおこなっています。

    小池邦人のCarbon API 徒然草(2005/11/18)

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

    今回は、Mac OS X 10.3から導入された新機能を使うことで、前回紹介した3つのルーチンの処理内容がどの様に変化するのかを、順序を追って解説します。

    今回の処理内容がMac OS X 10.3に対応していると言うことは、サンプルアプリケーションをMac OS X 10.4で起動しても問題はありません。しかし、当然ですが、Mac OS X 10.2では動作しませんので(クラッシュする)、サンプルのソースコードを今回の処理内容に切り替えたら、アプリケーション起動時にMac OS Xのバージョンをチェックして、対象外であればエラーを表示する必要があります。

    処理内容のキーポイントは、Mac OS X 10.3から導入されたSetWindowResizeLimits()とHIViewSetLayoutInfo()の2つのAPIを利用することです。画像表示用ウィンドウに実装しているCarbon Event Handlerの処理がかなり複雑なのは、ウィンドウをリサイズした時の幅と高さを、画像の矩形枠内に制限する処理を行っているためです。ウィンドウの最大幅と高さを、SetControlMinimum()とSetControlMaximum()によりScrollView自身に記憶しておき(本来の目的とは異なる使い方ですが…)その値を、Event Handler側で読み込んで制限する処理に利用しています。

    ウィンドウサイズの制限は、setupViwerWindowEvent()ルーチンでインストールされているEventTypeSpecの以下の2つのイベントを受け取る時に処理されています。

    { kEventClassWindow,kEventWindowGetMinimumSize },
    { kEventClassWindow,kEventWindowGetMaximumSize },

    setupViwerWindow()ルーチンの最初に、SetWindowResizeLimits()を加えることで、これらのイベントに対する処理を省くことが可能となります。SetWindowResizeLimits()には、予想されるウィンドウの最大幅と高さをHISize構造体として渡します。

    同様に、ウィンドウサイズを変更した時に、それに合わせてScrollViewのサイズを制限する処理もEvent Handlerを肥大化させている原因です。そちらは、以下の2つのベントを受け取る時に処理されています。この処理の方は、HIViewSetLayoutInfo()を使うことで省略することが可能です。

    { kEventClassWindow,kEventWindowBoundsChanging },
    { kEventClassWindow,kEventWindowBoundsChanged },

    Mac OS X 10.3から、あるViewが、それが埋め込まれているViewに対して、どのような位置関係を保つのかを自動制御できるようになりました。今回のScrollViewはウィンドウのContentViewに埋め込まれていますので、その相対位置関係(レイアウト)を固定してしまいます。一度固定されたレイアウトは、ウィンドウがリサイズなどされてもシステム側で自動調整され保持されます。これをHIViewの自動レイアウト機能と呼びますが、そのレイアウト情報を指定するのがHIViewSetLayoutInfo()です。自動レイアウトを実現するのには、以下のHILayoutInfo構造体に適切な情報を記載してHIViewSetLayoutInfo()に渡します。

    HILayoutInfo s_layout=
    {
        kHILayoutInfoVersionZero,                // 構造体バージョン(現在はゼロ)
        {
            { NULL,kHILayoutBindTop },           // HIBinding構造体
            { NULL,kHILayoutBindLeft },
            { NULL,kHILayoutBindBottom },
            { NULL,kHILayoutBindRight }
        },
        {
            { NULL,kHILayoutScaleAbsolute,0.0 }, // HIScaling構造体
            { NULL,kHILayoutScaleAbsolute,0.0 }
        },
        {
            { NULL,kHILayoutPositionTop,0 },    // HIPositioning構造体
            { NULL,kHILayoutPositionLeft,0 }
        }
    };
    


    HILayoutInfo構造体はHIView.hに記載されています。この構造体のパラメータの意味やレイアウト情報の利用目的については、次回に詳しく解説したいと思います。以下に、SetWindowResizeLimits()とHIViewSetLayoutInfo()を加えた、Mac OS X 10.3用の新しいsetupViwerWindow()を紹介しておきます。

    short setupViwerWindow( WindowRef window,CGImageRef image )
    {
        HIViewRef    iview,sview,cview;
        short        ww,hh,ret=1;
        HISize       hmax;          // ウィンドウサイズの制限を代入するのに用いる
        ControlID    cid;
        Rect         drt;
        HIRect       vrt;
    
        ww=CGImageGetWidth( image );                // 表示画像の幅(Pixel)を得る
        hh=CGImageGetHeight( image );               // 表示画像の高さ(Pixel)を得る
    
        hmax.width=ww+15;                           // ウィンドウの最大幅を代入
        hmax.height=hh+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のフレームサイズを設定
    
            SetControlMinimum( sview,ww+15 );   // 画像の幅+ScrollBar幅を記憶する
            SetControlMaximum( sview,hh+15 );   // 画像の高さ+ScrollBar幅を記憶する
                                                // 上記2つの値の保持はズーム処理用
            HIViewSetLayoutInfo( sview,&s_layout ); // 自動レイアウト情報を設定する
    
            HIImageViewCreate( image,&iview );  // ImageViewを作成する
            HIViewSetVisible( iview,1 );        // ImageViewを表示可に切り替える
            HIViewAddSubview( sview,iview );    // ImageViewをScrollViewに埋め込む
    
            cid.id=VIEW_ID;                     // Control ID=300
            cid.signature=MY_SIG;               // Signature='MosA'
            SetControlID( sview,&cid );         // ScrollViewにControlIDを設定する
            ret=0;
        }
        return( ret );
    }
    


    新APIの機能を使えるようになったおかげで、setupViwerWindowEvent()で用意しなければいけないEventTypeSpecは、7種類から3種類にまで減りました。また、画像ウィンドウ用のCarbon Event HandlerであるmyViwerWindowEventHandler()も、Mac OS X 10.3対応により大きく簡素化されました。

    void setupViwerWindowEvent( WindowRef window )
    {
        EventTypeSpec    list[]={
                                  { kEventClassCommand,kEventCommandUpdateStatus },
                                  // メニューのアップデートを確認
                                  { kEventClassWindow,kEventWindowZoom },
                                  // ウィンドウのズームボタンに対応
                                  { kEventClassWindow, kEventWindowClose }
                                  // ウィンドウのクローズボタン(閉じる)に対応
                                };
    
        InstallWindowEventHandler( window,myViwerWindowEventHandler,
                                       GetEventTypeCount(list),list,window,NULL );
                    // 3種類のCarbon Eventに対応するCarbon Event Handlerを実装する
    }
    
    pascal OSStatus myViwerWindowEventHandler( EventHandlerCallRef myHandler,
                                                    EventRef event,void *userData )
    {
        short            ret=eventNotHandledErr;
        WindowRef        wptr=NULL;
        unsigned long    ekind;
        HIViewRef        sview;
        short            part;
        long             cls;
        HICommand        cmd;
        ControlID        cid;
        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を得る
            cid.id=VIEW_ID;                                    // Control ID=300
            cid.signature=MY_SIG;                              // Signature='MosA'
            HIViewFindByID( HIViewGetRoot(wptr),cid,&sview );  // ScrollViewを得る
            switch( ekind )
            {
                case kEventWindowZoom: // ウィンドウのズームボタンに対応
    
                    pt.h=GetControlMinimum( sview ); // ウィンドウの最大幅を得る
                    pt.v=GetControlMaximum( sview ); // ウィンドウの最大高さを得る
                    if( IsWindowInStandardState(wptr,&pt,NULL ) ) // 現状のチェック
                        part=inZoomIn; // ズームインを行う
                    else
                        part=inZoomOut; // ズームアウトを行う
                    ZoomWindowIdeal( wptr,part,&pt ); // ウィンドウのズーム処理実行
                    ret=noErr;
                    break;
    
                case kEventWindowClose: // ウィンドウのクローズボタンに対応
    
                    disposeMyWindow( wptr ); // ウィンドウを破棄する自作ルーチン
                    ret=noErr;
                    break;
            }
        }
        return( ret );
    }
    


    しかし、せっかくSetWindowResizeLimits()でウィンドウサイズの制限をシステム側に教えているのに、何故だかStandard Handlerのズーム処理(kEventWindowZoom)ではその制限が利いていません(どこまでも大きくなる)。Mac OS X 10.3の仕様なのかバグなのかは判断できませんが、とにかく納得いかない現象です。そのため、Mac OS X 10.3の段階では、ウィンドウの最大幅と高さをSetControlMinimum()とSetControlMaximum()で記憶する処理を、setupViwerWindow()ルーチンから外すことができませんでした。しかし、嬉しいことに、Mac OS X 10.4では、SetWindowResizeLimits()で設定したサイズ限界がズーム処理にも適応されるようになっています。

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

    つづく

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。前回に引き続き、チェンジセットの扱いを取りあげます。

    ▼チェンジセットへの登録のタイミング
     デフォルトの記録先として指定されているチェンジセット(チェンジソーターで選択した時「Changes go to …」と表示されるチェンジセット。以下、デフォルトのチェンジセット)には、システムに加えられた改変が自動的に登録されてゆきます。これはその都度「登録」されたもので、けっして過去のある時点の状態と今の状態の差分をその都度いちいちチェックしているわけではないことに注意してください。

     登録のタイミングは再コンパイル(もしくは新規コンパイル)です。したがって、何も改変を加えなくても再コンパイルすればデフォルトのチェンジセットに登録されてしまいます。たとえば、Integer >> #factorialをブラウズして、これを内容を変更せずに再コンパイルしてデフォルトのチェンジセットがどうなるか確認してみましょう。Integer >> #factorialの定義は、どこか適当な場所(たとえばワークスペースなど)で「factorial」とタイプしてからbrowse it(cmd+B)すると簡単に呼び出すことができます。

    [fig.A]Integer >> #factorialの定義
    http://squab.no-ip.com:8080/mosaren/uploads/51a.png

     #factorialの定義を呼び出すことができたら、これを再コンパイル、つまりaccept(cmd+S)すればよいのですが、Macで開いたばかりの文書ファイルの保存ができないのと同様に、Smalltalkシステムでも何らかの変更を加えないとエディタの内容はacceptできないようになっています。試しにaccept(cmd+S、あるいは黄ボタンメニューから「了解」を選択)してみても、コードペインがフラッシュ(瞬間的に白黒反転)して軽い注意を促されるはずです。

     どこか適当な場所に改行やスペース(文字でも構いません)を挿入してから直ちにdeleteキーで削除するか、select all(cmd+A)してカット&ペースト(cmd+X後、cmd+V)するなどしてみましょう。コードペインに赤い枠が表示されれば、それがacceptが可能になった合図です。ここで改めてaccept(cmd+S、あるいは黄ボタンメニューから「了解」を選択)します。赤い枠が消えれば再コンパイルは完了です。

    [fig.B]Integer >> #factorialを内容を変えずに再コンパイルする
    http://squab.no-ip.com:8080/mosaren/uploads/51b.png

     さて、この状態でデフォルトのチェンジセットはどうなっているでしょうか? アクティブウインドウをブラウザからチェンジソーターに切り換えて確認してみます。右手上のペインにIntegerが追加されているので、それをクリックして選択すると、たった今、再コンパイルしたばかりの#factorialが登録されているはずです。このようなチェンジセット機構の挙動を便利に感じるか不便に思うかは場合によりますが、とりあえず今のところは、再コンパイルをきっかけにしてデフォルトチェンジセットへの登録が行なわれることを覚えておいてください。

    [fig.C]内容不変にも関わらず登録された#factorial
    http://squab.no-ip.com:8080/mosaren/uploads/51c.png

    ▼冗長な登録を回避する
     改変が加えられたメソッドは、バージョン管理機能を利用して、その定義を元に戻すことが可能です。この機構を用いれば、デフォルトのチェンジセットへの冗長な登録は避けられるのでないか…と思い付いた方もおられるかもしれませんね。でも残念ながら答はノーです。それは、今のデフォルトチェンジセットにFile >> #readContentsBrief:が登録されていることからもご推察いただけるものと思います。このメソッドは、確認のためいったん加筆しましたが、用が済んだ後、元に戻したはずです。しかし、こうしてしっかり登録されてしまっています。

     じつはこれ、バージョン復帰の機構や、先のデフォルトチェンジセットへの登録のタイミングについて知っていれば、納得できる挙動なのです。バージョン復帰は、単に、元の定義をチェンジファイル(あるいはソースファイル)から引っ張ってきて再コンパイルしているだけなので、再コンパイルが行なわれたかどうかしか関知しないチェンジセット機構にとっては、内容が元にもどったかどうかなどは知ったことではない…というわけです。

     でも、バージョンブラウザの機能を使って、いちいちチェンジソーターを開いて確認せずとも、デフォルトのチェンジセットへの冗長な登録を排除(削除)することは可能です。Integer >> #factorialを使って、実際に試してみましょう。まず、Integer >> #factorialのバージョンブラウザを開いてください。バージョンブラウザを開くには、ブラウザのversionsボタンをクリックします。他にも、メソッド名リストペインの黄ボタンメニューからversionsを選んでも、同ペインにフォーカス(マウスポインタを移動)してからcmd-Vとタイプしても同様です。

    [fig.D]Integer >> #factorialのバージョンブラウザ
    http://squab.no-ip.com:8080/mosaren/uploads/51d.png

     上のペインから元のバージョンを選んで中央のrevertボタンをクリックすることで、選択した元のバージョンに戻すことできます。そして、この操作を行なってもデフォルトのチェンジセットには相変わらずInteger >> #factorialは登録されたままであることについても、すでに述べたとおりなので、もはや確認の必要はないでしょう。

     ここで注目すべきは、revertの隣にあるremove from changesボタンです。このボタンをクリックすることで、このバージョンブラウザを開いた(つまり注目している)メソッドをデフォルトのチェンジセットから削除することができます。ためしに同ボタンをクリックして、チェンジソーターに切り換えてその効果を確認してみてください。

     余談ですが、このInteger >> #factorialバージョン履歴を見ると分かるように、内容をまったく変えていなくともacceptで強制的に再コンパイルにより、そのメソッドのオーサー(書き手)は変更されてしまっています。したがって、現状復帰を心がけるなら、必要があってメソッドの定義をいったん改変し元に戻す場合、それがささいな改変でも再編集してacceptするのではなく、バージョンブラウザのrevert機構を用いたほうがよさそうです。

    ▼チェンジソーターでの登録の削除
     もちろん、チェンジソーターを使って不要な登録を削除することもできます。削除したいメソッド(たとえば、FileList >> #readContentsBrief:)を選んで、黄ボタンメニューからdelete method from changeSetを選択します。

    [fig.E]FileList >> #readContentsBrief:の登録抹消
    http://squab.no-ip.com:8080/mosaren/uploads/51e.png

     似ていてまぎらわしいのですが、次のremove method from systemを選んではいけません。このメニュー項目は、システムブラウザでのremove methodと同じで、メソッドそれ自体の削除になってしまいます。注意してください。

     クラスごとチェンジセットから登録を抹消する場合は、右上のクラス名のリストペインからdelete class from change setを選択します。

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

    ニュース・解説

    今週の解説担当:木下 誠

    ———————————————————————-
    J2SE 5.0 Release 3登場
    ———————————————————————-

    J2SE 5.0 Release 3が登場しました。ソフトウェアアップデートによる更新で、全ユーザが対象となります。

    J2SE 5.0は、JavaのバージョンとしてはJava 1.5ということになります。Java 1.4ではJ2SE 1.4と表記されていましたが、今回からはJ2SE 5.0という表記を使うようです。ユーザが混乱しそうですね。

    また、このリリースでは、J2SE 5.0をインストールしても、J2SE 1.4がデフォルトとして残ります。J2SE 5.0を利用するには、ユーティリティにあるJ2SE 5.0/Java Preferencesを使って、スイッチする必要があります。

    J2SE 5.0 Release 3 Release Notes
    http://developer.apple.com/releasenotes/Java/Java50Release3RN/index.html

    ———————————————————————-
    Windows用のサンプルが多数公開
    ———————————————————————-

    Windows用のサンプルが多数公開されています。ADCで、C#やVBといった文字をこれほど目にすることなるとは、思いもしませんでした。

    QuickTimeのCOMを利用した、C#とVBのサンプルになっています。確かに、WindowsでのQuickTime COMは機能が充実しており、かなり高度な操作が行えます。また、WindowsのiTunesもCOMが提供されていて、Mac OS XでAppleScriptによる操作と、同程度のことが行えます。

    というわけで、Windows上でのAppleソフトのプログラミング環境は、意外に整備されています。

    CreateMovie – C#
    http://developer.apple.com/samplecode/CreateMovieCSharp/CreateMovieCSharp.html

    CreateMovie – VB6
    http://developer.apple.com/samplecode/CreateMovieVB6/CreateMovieVB6.html

    MoviePlayer – C#
    http://developer.apple.com/samplecode/MoviePlayerCSharp/MoviePlayerCSharp.html

    ———————————————————————-
    他サンプル2点
    ———————————————————————-

    通常のサンプルも公開されています。認証のためのプラグインを作る、NullAuthPlugin。そして、キーボードやマウスからのイベントを受け取る、EventMonitorTestです。

    NullAuthPlugin
    http://developer.apple.com/samplecode/NullAuthPlugin/NullAuthPlugin.html

    EventMonitorTest
    http://developer.apple.com/samplecode/EventMonitorTest/EventMonitorTest.html

    ———————————————————————-
    CoreAudio SDKアップデート
    ———————————————————————-

    CoreAudio SDKがアップデートしました。バージョン番号は1.4.3となります。これはTiger専用となるようです。

    CoreAudioに興味のある方は、前回公開されました「The Sound of Opportunity Knocking: The Audio Units Community Takes Off」も併せて読まれるといいと思います。

    CoreAudio 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=モサ伝]第183号

    2005-11-15

    目次

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

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

     前回に引き続きセッション管理のお話です。WebObjectsでは自動的にセッション管理がおこなわれるということを前回説明しました。自動的にセッション管理をおこなってくれますのでとても便利なのですが、逆にデフォルトの状態では、クライアントからリクエストがあるたびにサーバ側でセッションオブジェクトが生成されてしまいます。これが逆に不便な場合というのもありますので、今回はセッションを用いない処理について解説していきます。

    DirectAction

     Webアプリケーションといってもいつもセッションが必要になるわけではありません。基本的には状態を管理する必要がなければセッションも必要ないわけですが、必要のないものを生成していては余計な負荷にもなりかねません。例えば、検索をおこなうようなアプリではセッションを用いない場合もあるでしょう。
     また、セッションを用いた場合は、URLに自動的にセッションIDが含まれるようになり、各画面のURLというものは常に変化します。これではクライアント側でブックマークに追加することはできませんが、セッションを用いない処理をおこなう場合は、URLにセッションIDが含まれなくなりURLも固定になりますので、各画面をブックマークできるようになります。

     では、セッションを使わずに処理をおこなう方法ですが、セッションが用いられたときのURLをみてみますと以下のようになっています。

    ・URL
    /cgi-bin/WebObjects/MOSAJobMatch.woa/wo/5smyn1cV1XzALuFPFVCMUw/2.0.4.3

     ここで、アプリケーション名とセッションIDの間にある文字列”wo”に注目してください。WebObjectsでは、クライアントからのリクエストをリクエストハンドラーを用いて処理しますが、このリクエストハンドラーにはいくつかの種類があり、どのリクエストハンドラーを用いるかはリクエストハンドラーキーによって指定されます。URLに埋め込まれた”wo”はこのリクエストハンドラーキーなのです。
     セッションを用いた処理ではリクエストハンドラーキー”wo”が使用されますが、DirectActionと呼ばれるセッションを用いない処理をおこなう場合は”wa”というリクエストハンドラーキーを用います。

     次に、リクエストハンドラーキーによって呼び出される処理をどのように実装するかですが、WebObjectsアプリケーションのプロジェクトを作成したときに、”Classes”グループの中に”DirectAction.java”というクラスファイルが自動生成されています。このクラスがDirectActionの処理を実装するためのクラスになります。このクラスは”WODirectAction”クラスを継承して作成されています。例えばこのクラスに次のようなメソッドを追加したとしましょう。

         public WOActionResults browseAction() {
             return pageWithName("UserList");
         }
    


     このメソッドを実際に実行するには、以下のようなURLにアクセスします。

    ・DirectActionのURL
    /cgi-bin/WebObjects/MOSAJobMatch.woa/wa/browse

     つまり、”wo”の代わりに”wa”を用い、その次に呼び出したいメソッド名を指定します。このとき実際のメソッド名は”…Action”となっていますがURL上では”Action”の部分は省略します。ようするにURLで直接呼び出したいメソッドを指定しているわけです。
     DirectActionを実装できるのは”DirectAction”クラスだけではありません。”WODirectAction”クラスを継承したクラスを作成してメソッドを追加すれば、そちらを呼び出すこともできます。あとから追加したクラスのメソッドを呼び出すには次のようなURLを用います。

    ・クラスを追加した場合のURL
    /cgi-bin/WebObjects/MOSAJobMatch.woa/wa/クラス名/メソッド名

     たとえばMyDirectクラスを追加して、sampleAction()というメソッドを実装した場合には次のURLで実行することができます。

    ・クラスを追加した場合のURL
    /cgi-bin/WebObjects/MOSAJobMatch.woa/wa/MyAction/sample

     これでDirectActionの実装方法と、どのような形式のURLで呼び出すかが分かりましたが、動的に生成されたページからDirectActionを呼び出すにはどうすればよいでしょうか。例えば、WOHyperLinkのInspectorをみてみますと、アクションメソッドをバインドするAttributeとして”action”があります。セッションを用いる場合はこのAttributeを用いたりしますが、DirectActionのメソッドを呼び出したい場合には”actionClass”と”directActionName”を用います。使い方は名前からなんとなく想像できるかと思いますが、それぞれ次のような使い方をします。

    actionClass:DirectActionクラスのクラス名を指定
    directActionName:actionClassで指定したクラス内のメソッド名を指定
             ※ただし”Action”を除いたもの

     例えば、MyActionクラスのsampleAction()を呼び出す場合には次のようにバインドをおこないます。

    actionClass:MyAction
    directActionName:sample

     これでDirectActionの基本的な使い方が分かりましたが、このままではアプリケーションのトップ画面にアクセスしたさいにはセッションが生成されてしまいます。トップページにアクセスした時点で本当にセッションが必要になるようでしたら問題ないのですが、そうでない場合はDirectActionを利用してセッションの生成をおこなわない方法があります。
     実際にビジネスマッチングシステムでは、トップページからDirectActionで処理をおこなうようにApplication.javaのコンストラクタに次のような処理を追加してあります。

    setDefaultRequestHandler(requestHandlerForKey(
         directActionRequestHandlerKey()));

     アプリケーションが使用するデフォルトのリクエストハンドラーを変更してDirectAction用のリクエストハンドラーを使用するように設定しています。
     このメソッドを追加しておけば、DirectAction.javaのdefaultAction()によってトップページの処理がおこなわれます。defaultAction()はプロジェクトを生成した時点で自動的に生成されており、”Main”ページを返すようになっていますので、これでトップページをセッションを生成させずに表示できるようになります。
     このようにDirectActionを使えばセッションを用いない処理にも対応することができます。

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

    というわけで「タイトルバーのないウィンドウの作り方・実践編」である。マシンの準備はよろしいか。

     まず第一にこの「タイトルバーのないウィンドウ」の class を定義する。え、そんなもの別に NSWindow のままでいいぢゃねぇかって? どっこいそうでもないのである。実は NSWindow のインスタンスは自分がタイトルバーを持たない場合、以下の2つのメッセージに対して「NO」を返す。

    - (BOOL) canBecomeMainWindow;
    - (BOOL) canBecomeKeyWindow;

     つまり「タイトルバーを持たないウィンドウはそのままではメインウィンドウにもキーウィンドウにもなれないのだ。……なぜそうなのかは各自考えることにして(ホントのことを言うとオレは考えたことがなかった。で、今ちょっと考えたけど「これだ」と言う理由が思いつかない)、なぜそれでは困るのか。
     えっと……これは「タイトルバーのないウィンドウを作って何に使うか」の問題なので、「いや、オレは困らないもん」とあなたが言うのは勝手なんだが、オレなどはこれを例えば初期化に時間がかかるアプリの「アバウトボックス」として使いたいので、メインウィンドウになれてもらえないとちとまずいのである。
     で、こいつらをオーバーライドして「タイトルバーは持ってないけどメインウィンドウになれる、ついでだからキーウィンドウにもなれる NSWindow のサブクラス」というのを「TLWindow」(TLはTitleLessね)と定義する。

    @interface TLWindow : NSWindow {   // TL = TitleLess
        //  インスタンス変数はなし。
    }
    
    - (BOOL) canBecomeMainWindow;
    - (BOOL) canBecomeKeyWindow;
    
    @end

     あとは上の2つのメッセージ両方に「YES」を返すインプリメンテーションをすればそれでOKである。

     次に Interface Builder を使って上のウィンドウに表示する View を持つウィンドウを作成する。動的に表示を変更するなどの細工をおこないたい場合にはこの View をカスタムビューにしておいてフルマイを記述すればいい。

     ではいよいよ実際にウィンドウを作成するコード。上で定義したウィンドウを IBOutlet として参照しているオブジェクトの中で(dummyWindowというのがそれだとする)……

    OurTitlelessWindow = [[TLWindow alloc]
      initWithContentRect: [[dummyWindow contentView] frame]
      styleMask: NSBorderlessWindowMask
      backing: [aboutPanel backingType]
      defer: NO];
    
      if(OurTitlelessWindow) {
    
        [OurTitlelessWindow setHasShadow: YES];
        [OurTitlelessWindow setDelegate: self];
        [OurTitlelessWindow center];
    
        NSView          *content = [[dummyWindow contentView] retain];
        [content removeFromSuperview];
        [OurTitlelessWindow setContentView: content];
        [content release];
      }
    


     とまぁ、これでめでたくタイトルバーのないウィンドウのできあがりである。
     やれやれ、ようやくNSWindowに関する「最初の話題」が一段落かぁ。次回からは……次回からのことは次回までに考えることにする。あしからず。
    (2005_11_11)

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

    UNIXとしてのMac OS X

    〜Perlについて(24)〜

     こんにちは、高橋真人です。早速、前回の最後で触れたバグの件を解説します。
     まずはスクリプトをご覧ください。

    while ($data =~ m/会員向け¥t([^¥t]+)¥t(.+)¥n/g) {
        print "タイトル:" . $1 . "¥t状況:" . $2 . "¥n";
    }

     データをセットしている部分を今回は省略しましたが、実は前回のスクリプトでは、入力をファイルから行わずにヒアドキュメント方式で行っていたためにバグが顕在化しなかったのです。そこで今回はファイルからデータを読み込むやり方に変えてみましょう。

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

     の部分は、当たり前ですがご自分の環境に合わせて書き換えてください。ついでに仕様も少し変更しました。
     今回は「会員向け」の行を拾うのではなく、先頭項目に日付が入っているものを拾う形になっています。正規表現の先頭部分がかなり込み入ってしまっていますが、「数字の1個以上の連続、ピリオド、数字の1個以上の連続、ピリオド、数字の1個以上の連続、(タブを除く)任意の文字の0個以上の連続」ということで日付部分に対応しています。
     末尾の「任意の文字の0個以上の連続」という部分は、日付のあとに「迄」などの文字が付加されているケースに対応したものです。
     それから処理対象のファイルですが、以下のデータ(前回のものと同じ)をテキストファイルとして保存します。

    MOSA NEWS
    10.21-22 湘南ミーティングへのご参加ありがとうございました!
    会員向け アップル技術者トレーニング割引のご案内 受付中
    会員向け アップル技術者試験 受験料半額割引のご提供 受付中
    会員向け MOSA会員向け掲示板開設のお知らせ 運用中
    参加受付中のセミナー、イベントなど
    2005.11.12 Dashboard ウィジェット作成セミナー 受付中
    2005.11.15 NEW!ポッドキャスティング・セミナー 受付中
    2005.11.30迄 Dashboardウィジェット コンテスト 受付中
    終了したセミナー、イベントなどのご報告
    2005.10.15 Dashboard ウィジェット作成セミナー ご報告

     注意していただきたいのは、文字コードと改行コードです。PerlにはC言語のようなテキストモードなどという概念はないので、今回の場合改行コードはLF(UNIX)にしておく必要があります。また、文字コードについてもPerlスクリプト自体のエンコーディングに合わせる必要があるかもしれません。

     それでは早速実行してみましょう。
     結果は、私のところでは以下のようになりました。

    日付:2005.11.12, 内容:Dashboard ウィジェット作成セミナー, 状況:受付中
    日付:2005.11.15, 内容:NEW!ポッドキャスティング・セミナー, 状況:受付中
    日付:2005.11.30迄, 内容:Dashboardウィジェット コンテスト, 状況:受付中
    Done

     おや? 最後の行が出力されていませんね。って、わざとらしいですね(笑)
     実は、私はデータをファイルに保存する時に、最後の行のあとに改行を入れなかったのです。従って、最後の行の末尾にはLF(¥n)がなかったために、マッチしなかったということになります。
     Perlに限らず、行単位のテキストファイルを処理する場合にはこの問題を無視することができないのですが、Perlの場合どのようにすればよいのでしょう?
     まず、いちばん単純なのは¥nを取ってしまうことです。何故これでうまく行くかというと、正規表現における . の役目は「改行以外の任意の文字」だからです。.+ という表現は、改行文字の直前までマッチすることになるので、末尾の改行はあってもなくても関係がないわけです。
     ただ、これで問題がないわけでもないのです。前回も触れましたが、.+ という表現だけだとデータ項目の区切りであるタブ文字にもマッチしてしまうため、万が一想定した以上にタブが含まれていてもそこで止まってはくれません。もちろん、今回のスクリプトはそこまで考慮しているわけではありませんし、そもそも万能の正規表現などというものはあり得ないのです。
     まあ、それでもどうしてもタブを含ませたくないのでしたら、[^¥t¥n]+ とでもすることになるでしょうが。

     さて、何とも歯切れの悪い展開になってしまいましたが(笑)、実は今回のようなやり方はPerlとしては一般的ではありません。もともと文字列処理を得意とするPerlの場合、今回のような「タブ区切り、行単位」の典型的なデータテキスト(例えばファイルメーカーやExcelからデータをテキストで書き出す場合にはこの形式になることが多いでしょう)を処理するポピュラーなやり方がちゃんとあるのです。
     次回は、その辺のお話と、併せてファイル処理について説明したいと思います。

    ニュース・解説

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

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

    【開発環境】

    前号のニュースで木下さんも紹介されていますが、Metrowerks社(と言うよりFreescale Semiconductor社が正しいのかな?)から「CodeWarrior Development Studio for the Mac OS X v10」が販売開始となりました。

    http://www.metrowerks.com/MW/Develop/Desktop/mac10

    ダウンロード販売のみで、Professional版は$99です。さっそく購入して正規のレジストレーション手続きをしたのですが、何故だかコンパイル時に「レジストレーションされてない!」と言った趣旨のエラーが出て作業が終了しませんでした(涙)。自分であれこれ試すのもバカらしいので、license@metrowerks.comへ認証用ファイルのlicense.datを送りつけて修復してもらいOKとなりました。ライセンスの認証システムにバグがあったんじゃ話になりませんよねぇ(笑)。同じ現象で悩んでいる方は、この解決方法が近道なのでお試しください。

    私としては、PowerPlant、PowerPlant X、Constructorのどれも使用しないので、v9.6から大きく変わった箇所は見受けられません。また、Mac OS X 10.4.3環境でライブラリを再構築すると問題が出るという話もあります。ソースコードをコンパイルした後のコードサイズなどにも大きな変化は見られないので、v9.6が利用できる間はそれで済ませようと考えています。この発表に対抗したのかどうかは分かりませんが(笑)、Apple社からもXcode 2.2の正式版が発表となりました。これで、自作アプリケーション をUniversal Binary化するための最終準備は整ったわけです。

    「Xcode 2.2」

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

    嬉しいことに、2.2対応ユーザーズガイドもちゃんと日本語訳されて登録されています。

    「Xcode 2.2ユーザーガイド」(日本語訳)

    http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeUserGuide21/Contents/Resources/ja.lproj/index.html

    ちなみに、Xcode 2.2をインストールするのと同時にCHUDもインストールしたい場合には、インストーラの「カスタマイズ」ボタンで表示されるツール一覧で「CHUD Tools」をチェックしてからインストールを実行する必要があります。お試しください。

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

    前回から11月11日の期間中、Apple社のDocumentationサイトには数多くのドキュメントが登録されました。ただし、大部分は今までの内容のマイナーチェンジです。今回は、その中で初版ドキュメントと内容が大幅変更になったドキュメントだけをピックアップしておきます。全体的に見ると、GCCやGDBといったツール類のドキュメント改訂が多いようですが、注目ドキュメントは、Universal Binary関連の「Mac OS X ABI Function Call Guide」と「Universal Binary Programming Guidelines, Second Edition」でしょう。ちなみに、ABIとは「Application Binary Interface」の略です。

    新規リリースノートの方は4つ登録されました。そのうち3つがXcode 2.2関連なのですが、何故だか今頃になって2.1のリリースノートも登録されています(忘れていた?)。また、デベロッパー向け読み物も2つ登録されました。「The Audio Units Community Takes Off」については、前号の木下さんの記事を参照してみてください。

    「Accessibility (ApplicationServices/HIServices) Reference」
    「Audio Device Driver Programming Guide」(PDFあり)
    「Carbon Overview」(PDFあり)
    「Coding in the Kernel」
    「CPlusTest Reference」(初版)
    「Cross-Development Programming Guide」(PDFあり)
    「Debugging with GDB」
    「Flex」
    「GCC Porting Guide」(PDFあり)
    「GDB Internals」
    「GNU C/C++/Objective-C 4.0.1 Compiler User Guide」(PDFあり)
    「GNU macro processor」
    「GNU Make」
    「Kernel Programming Guide」(PDFあり)
    「Libtool」
    「Mac OS X ABI Function Call Guide」(PDFあり)(初版)
    「Mac OS X Server Administrator Topics」(PDFあり)(初版)
    「Mach-O Programming Topics」(PDFあり)
    「Navigation Services Programming Guide」(PDFあり)
    「Navigation Services Reference」(PDFあり)
    「Quartz 2D Reference」(PDFあり)
    「QuickTime Kit Programming Guide」(PDFあり)
    「STABS Debug Format」
    「Universal Binary Programming Guidelines, Second Edition」(PDFあり)
    「WebObjects Builder User Guide」(PDFあり)(初版)
    「Xcode 2.2 User Guide」(PDFあり)(日本語訳あり)

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

    リリースノート

    「Xcode 2.1 Release Notes」
    「Xcode Build Settings Release Notes」(v2.2用)
    「Xcode Expert Preferences Release Notes」(v2.2用)
    「Xcode Release Notes」(v2.2用)

    http://developer.apple.com/releasenotes/

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

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

    「The Audio Units Community Takes Off」(読み物)

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

    前回から11月11日の期間中、新規テクニカルノートとクニカルQ&Aはひとつも登録されませんでした。最近では珍しいことです(笑)。

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

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

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

    前回から11月11日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが10登録されました。Widget関連の4つのサンプルは、Mac OS X 10.4.3に対応させるために内容が更新されています。新顔の「CocoaDVDPlayer」については、前号の木下さんの記事を参照してください。

    「CocoaDVDPlayer」(Cocoa関連)(初版)
    「SampleRSS」(Widget関連)
    「Scroller」(Widget関連)
    「Stretcher」(Widget関連)
    「Fader」(Widget関連)
    「QTMetaData」(QuickTime関連)
    「TabsShowcase」(Carbon関連)(初版)
    「FileNotification」(Carbon関連)
    「GetPrimaryMACAddress」(Network関連)
    「SampleD」(Darwin関連)

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

    【デベロップメント SDK】

    前回から11月11日の期間中、Apple社のSDKサイトには新しいSDKがひとつだけ登録されました。Mac OS X 10.4.3に対応した「Kernel Debug Kit」です。同様に、10.4.3に対応したDarwinの最新ソースコードもダウンロード可能になっています。

    「QuickTime Windows SDK」

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

    「Mac OS X 10.4.3 (Darwin 8.3)」

    http://www.opensource.apple.com/darwinsource/10.4.3/

    また、以下のサイトからCHUDの最新版である4.2.3がダウンロード可能です。

    「Computer Hardware Understanding Development Tools (CHUD )4.2.3」

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

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

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

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

    2005-11-08

    目次

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

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

     前回、前々回は少し話題を変えてサーバ構築について説明してきましたが、
    今回はまたプロジェクトの解説に戻りたいと思います。今回のテーマは、セッション管理です。

    セッション管理

     Webアプリケーションの基盤となるHTTPにはもともとセッション管理の仕組みがありません。つまり、Webサーバに複数回アクセスしたとしても、各アクセスは個別のリクエストとして処理され、リクエスト間の関連性は保持されません。
     こうなると困るのが、例えばオンラインショッピングサイトのショッピングカートのようなものを実現するときです。連続してリクエストをおこなったとき、つまりページを移動していったときにもショッピングカートの中身は保持される必要があります。ですので、もともとセッションの仕組みがないHTTPでもなんとかセッション管理をおこなう必要が出てくるのです。

    WebObjectsのセッション管理

     セッションを実現する方法はいくつか考えられますが、WebObjectsはフレームワークが自動的にセッションの管理をおこなってくれます。ですので、なにも準備をしなくても最初からセッションを利用することができるのです。
     実際どのようにセッション管理がおこなわれるかですが、あるクライアントから最初のリクエストがあったとき、WebObjectsのフレームワークはそのクライアント用に新しいセッションを割り当てます。まずサーバ上でセッションオブジェクトとセッションを識別するためのセッションIDが生成されます。そして、動的に生成されたWebページにはセッションIDを含んだハイパーリンクが埋め込まれます。URLおよびURLに含まれるセッションIDは次のようになります。

    ・URL
    /cgi-bin/WebObjects/MOSAJobMatch.woa/wo/5smyn1cV1XzALuFPFVCMUw/2.0.4.3
    ・セッションID
    5smyn1cV1XzALuFPFVCMUw

     このように22桁の英数字によるセッションIDが、セッションに割り当てられて、URLに埋め込まれます。1度セッションが割り当てられたクライアントから2度目以降のリクエストがあった場合、すでに最初に表示したWebページのハイパーリンクにはセッションIDを含んだURLが埋め込まれていますので、サーバ側ではURLに含まれるセッションIDから、リクエストのあったクライアントがサーバ上のどのセッションオブジェクトに関連付けられているのかを識別して、セッションの管理をおこないます。
     別のクライアントからアクセスがあった場合、つまりまだセッションが割り当てられていないクライアントからアクセスがあると、再びセッションの生成がおこなわれ、そのセッション固有のセッションIDによって管理がおこなわれます。

     セッションIDがURLに含まれるということはWebブラウザ上で簡単にセッションIDを見ることができますが、これがセキュリティ上問題があるという場合は、セッションIDをURLからははずし、クッキーの中に格納することもできます。この場合、もちろんWebブラウザ側ではクッキ−が利用できるようになっている必要があります。

        public Session() {
             super();
    
             // セッションIDをURLからはずし、クッキーに格納
             setStoresIDsInURLs(false);
             setStoresIDsInCookies(true);
         }
    

    セッションの有効期間

     クッキーにセッションIDを格納して、セッションIDを表面上は隠すことができますが、セッションは永久に存在するわけではありません。最後にリクエストがあってから一定時間が経過するとサーバ上のセッションオブジェクトはタイムアウトして自動的に消滅してしまいます。つまり一定時間しかセッションオブジェクトは存在しません。デフォルトでは、タイムアウトまでの時間は60分に設定されていますが、セッションのタイムアウト時間は自由にカスタマイズすることができます。

     まず一番お手軽な方法は、プロジェクトに含まれるPropertiesファイルに次のような設定を追加します。このときタイムアウト時間は秒単位で指定します。この設定はあらかじめコメントアウトされたものがPropertiesファイルに書き込まれています。

    ・Propertiesファイルによるセッションタイムアウト時間の設定(30分)
    WOSessionTimeOut=1800

     また、これ以外にも直接コーディングによりタイムアウト時間を指定することもでき、アプリケーション全体で指定する方法と、セッションごとに指定する方法があります。

    ・アプリケーション(WOApplicationクラス)
    public void setSessionTimeOut(Number timeOut)
    ・セッション(WOSessionクラス)
    public void setTimeOut(double aTimeInterval)

     今回はWebObjectsがどのようにしてセッションを管理するのかを解説してきましたが、セッションが不要な場合はセッションを用いない処理をおこなうこともできます。次回は、セッションを用いない処理と、ビジネスマッチングシステムで実際にどのようなセッションの制御をおこなっているかを紹介したいと思います。

    小池邦人のCarbon API 徒然草(2005/11/4)

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

    今回は、setupViwerWindow()ルーチンとsetupViwerWindowEvent()ルーチン、そして画像表示用ウィンドウに実装するCarbon Event HandlerのmyViwerWindowEventHandler()を紹介します。実は、この3つのルーチンに記述する処理内容は、ターゲットとなるMac OS Xのバージョンによって大きく変化します。

    まず最初に、Mac OS X 10.2でも問題なく動作する処理方法を取り上げます。Mac OS X 10.2で問題なく動作すると言うことは、当然、Mac OS X 10.3や10.4での動作も問題ありません。つまり、アプリケーションユーザのターゲットが、Mac OS X 10.2から10.4である場合には、今回紹介するソースコードを用いる必要があります。ただし、本サンプルアプリケーションが画像表示のために多用しているHIView APIは、Mac OS X 10.2からしか利用できませんので、Mac OS X 10.0や10.1をターゲットとする場合には、今回の処理内容を大幅に変更する必要があります。今回は、そうした「古いタイプ」の処理方法については言及いたしません。

    以下が、画像表示用のウィンドウに各種Viewを配置しているsetupViwerWindow()ルーチンです。

    #define    VIEW_ID      300        // ScrollViewのControl ID
    #define    MY_SIG      'MosA'      // ScrollViewのSignature
    
    short setupViwerWindow( WindowRef window,CGImageRef image )
    {
        HIViewRef    iview,sview,cview;
        short        ww,hh,ret=1;
        ControlID    cid;
        Rect         drt;
        HIRect       vrt;
    
        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のフレームサイズを設定
    
            ww=CGImageGetWidth( image );        // 表示画像の幅(Pixel)を得る
            hh=CGImageGetHeight( image );       // 表示画像の高さ(Pixel)を得る
            SetControlMinimum( sview,ww+15 );   // 画像の幅+ScrollBar幅を記憶する
            SetControlMaximum( sview,hh+15 );   // 画像の高さ+ScrollBar幅を記憶する
            HIImageViewCreate( image,&iview );  // ImageViewを作成する
            HIViewSetVisible( iview,1 );        // ImageViewを表示可に切り替える
            HIViewAddSubview( sview,iview );    // ImageViewをScrollViewに埋め込む
    
            cid.id=VIEW_ID;                     // Control ID=300
            cid.signature=MY_SIG;               // Signature='MosA'
            SetControlID( sview,&cid );         // ScrollViewにControlIDを設定する
            ret=0;
        }
        return( ret );
    }
    


    画像ウィンドウにCarbon Event Handlerを実装しているのは、setupViwerWindowEvent()ルーチンです。ここでは、7種類のCarbon Eventを受理できるようにEventTypeSpecを設定しています。

    void setupViwerWindowEvent( WindowRef window )
    {
        EventTypeSpec    list[]={
                                  { kEventClassCommand,kEventCommandUpdateStatus },
                                  // メニューのアップデートを確認
                                  { kEventClassWindow,kEventWindowZoom },
                                  // ウィンドウのズームボタンに対応
                                  { kEventClassWindow,kEventWindowGetMinimumSize },
                                  // ウィンドウの矩形枠最大サイズを制限
                                  { kEventClassWindow,kEventWindowGetMaximumSize },
                                  // ウィンドウの矩形枠最小サイズを制限
                                  { kEventClassWindow,kEventWindowBoundsChanging },
                                  // ウィンドウの拡大縮小に対応(グローボックス)
                                  { kEventClassWindow,kEventWindowBoundsChanged },
                                  // ウィンドウの拡大縮小に対応(グローボックス)
                                  { kEventClassWindow, kEventWindowClose }
                                  // ウィンドウのクローズボタン(閉じる)に対応
                                };
    
        InstallWindowEventHandler( window,myViwerWindowEventHandler,
                                       GetEventTypeCount(list),list,window,NULL );
                           // 7種類のCarbon Eventに対応するCarbon Event Handlerを実装する
    }
    


    最後に紹介するのは、Carbon Event HandlerであるmyViwerWindowEventHandler()ルーチンです。このルーチンは、setupViwerWindowEvent()のInstallWindowEventHandler()により画像表示用ウィンドウに実装されます。

    pascal OSStatus myViwerWindowEventHandler( EventHandlerCallRef myHandler,
                                                    EventRef event,void *userData )
    {
        short            ret=eventNotHandledErr;
        WindowRef        wptr=NULL;
        unsigned long    ekind;
        unsigned long    ctype;
        HIViewRef        sview;
        short            part;
        long             cls;
        HICommand        cmd;
        ControlID        cid;
        HIRect           vrt;
        Rect             brt;
        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を得る
            cid.id=VIEW_ID;                                    // Control ID=300
            cid.signature=MY_SIG;                              // Signature='MosA'
            HIViewFindByID( HIViewGetRoot(wptr),cid,&sview );  // ScrollViewを得る
            switch( ekind )
            {
                case kEventWindowGetMinimumSize: // ウィンドウ矩形枠最小サイズを制限
    
                    pt.v=pt.h=80;
                    SetEventParameter( event,kEventParamDimensions,typeQDPoint,
                                                            sizeof(Point),&pt );
                           // 幅と高さが80ピクセルより小さくならないよう制限する
                    ret=noErr;
                    break;
    
                case kEventWindowGetMaximumSize: // ウィンドウ矩形枠最大サイズを制限
    
                    pt.h=GetControlMinimum( sview ); // ウィンドウの最大幅を得る
                    pt.v=GetControlMaximum( sview ); // ウィンドウの最大高さを得る
                    SetEventParameter( event,kEventParamDimensions,typeQDPoint,
                                                               sizeof(Point),&pt );
                           // 幅と高さが得られた最大値を超えないように制限する
                    ret=noErr;
                    break;
    
                case kEventWindowBoundsChanging: // ウィンドウの拡大縮小に対応
                case kEventWindowBoundsChanged:
    
                    GetEventParameter( event,kEventParamAttributes,typeUInt32,NULL,
                                               sizeof(unsigned long),NULL,&ctype );
                           // ウィンドウ矩形枠がどのように変化したのか調べる
                    if( (ctype&kWindowBoundsChangeSizeChanged) ) // サイズが変わった
                    {
                        GetWindowPortBounds( wptr,&brt ); // ウィンドウ矩形枠を得る
                        vrt.origin.y=vrt.origin.x=0.0;
                        vrt.size.width=(brt.right-brt.left);
                        vrt.size.height=(brt.bottom-brt.top);
                        HIViewSetFrame( sview,&vrt );    // ScrollViewのサイズも変更
                    }
                    ret=noErr;
                    break;
    
                case kEventWindowZoom: // ウィンドウのズームボタンに対応
    
                    pt.h=GetControlMinimum( sview ); // ウィンドウの最大幅を得る
                    pt.v=GetControlMaximum( sview ); // ウィンドウの最大高さを得る
                    if( IsWindowInStandardState(wptr,&pt,NULL ) ) // 現状のチェック
                        part=inZoomIn; // ズームインを行う
                    else
                        part=inZoomOut; // ズームアウトを行う
                    ZoomWindowIdeal( wptr,part,&pt ); // ウィンドウのズーム処理実行
                    ret=noErr;
                    break;
    
                case kEventWindowClose: // ウィンドウのクローズボタンに対応
    
                    disposeMyWindow( wptr ); // ウィンドウを破棄する自作ルーチン
                    ret=noErr;
                    break;
            }
        }
        return( ret );
    }
    


    次回は、今回紹介した3つのルーチンの処理内容について、さらに詳しく解説します。そして、こうして用意したMac OS X 10.2用の処理が、Mac OS X 10.3や10.4でどの様に変化するのかを、順序を追って紹介して行きたいと思います。

    つづく

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回から数回にわたって、システムに対して散発的に施された改変を管理するための機構「チェンジセット」を取りあげます。

    ▼チェンジセットとは
     我々はすでに、システムブラウザを使うことで、クラス単位やクラスカテゴリ単位、メソッド単位やメソッドカテゴリ(プロトコル)単位で、そのソースコードをファイルアウトし、他の仮想イメージにそれを読み込ませる(ファイルインする)ことが可能であることを知っています。しかしシステムブラウザには、クラスをまたいで複数のメソッドを追加したり改変を加えるような作業を行なった場合に、それらを一括してファイルアウトする仕組みは用意されていません。

     こんなとき役に立つのが「チェンジセット」という機構です。チェンジセットは、その名の示すとおり、システムに加えられた主に複数の“改変”箇所を、あとで確認できるよう“ひとまとめ”に扱うために提供された機構です。あるいは、そうして改変箇所が登録されたデータベース(もちろんオブジェクト)の呼称としても用いられます。

     じつは、Smalltalkシステムは、あらかじめ指定されたチェンジセット(変更箇所のデータベース)に、システムのどの部分、つまり、“どのクラスのどのメソッド”が変更されたのかという情報を自動的に記録し蓄積する仕組みを持ちます。チェンジセットに蓄積された変更箇所については、あとで該当するクラスやメソッドのソースを一括してファイルアウトすることが可能です。なお、チェンジセットは複数持つことができて、それぞれに名前を付けて適宜、切り換えて使うことができます。

    ▼チェンジファイルへのログ機構との違い
     前回、取りあげた「チェンジファイル」へのログ機能と、今回の「チェンジセット」への変更箇所の登録機構は、名前も作業の内容も似ているように感じられますが、両者はまったく別物です。混同しないように注意してください。

     すでにご紹介したとおり、チェンジファイルへのログ機能は、改変の“内容”を記録してゆくものです。これに対しチェンジセット機構は、改変された“箇所”だけを情報として記録します。

     また、改変内容の記録先であるチェンジファイルは、Smalltalkシステムの“外界”にある単一のテキストファイル(ログ用のワークファイル)なのに対し、チェンジセットはSmalltalkシステムの中に複数存在するオブジェクトで、それぞれが小規模なデータベースのような振る舞いをする…という違いもあります。

    ▼チェンジソーター
     システムに加えられた改変の登録先として指定されているチェンジセットと、その他のチェンジセット群やその内容を閲覧するためのツールが「チェンジソーター」です。デスクトップメニューの「開く…」(英語メニューでは「open…」)→「シンプル・チェンジ・ソーター」(同、simple change sorter)で起動できます。

    [fig.A]チェンジソーター
    http://squab.no-ip.com:8080/mosaren/uploads/50a.png

     まず、ウインドウタイトルにある「Changes go to “名無し1″」(英語では「Changes go to “New Changes”」)に注目してください。このタイトルには、二つのことが示されています。

     ひとつは、このシステムに登録されているチェンジセット群の中で、ブラウズ中(選択されている)のは「名無し1」(あるいは「New Changes」)と名付けられたチェンジセットであること。そして、もうひとつは、このチェンジセットが改変箇所の記録先として指定されていること、です。

     後者については「Changes go to」という部分に表わされています。ためしに左上のリストペインで別のチェンジセットをクリックして選択しなおしてみてください。「名無し1」チェンジセット以外では、タイトルは「ChangeSet:<<チェンジセット名>>」のように変化するのを確認できるしょう。

     右手最上段のリストペインでは、選択したチェンジセットに登録された改変箇所をクラス名で一覧できます。このペインでクラスを選択すると、さらにそのクラス内で改変されたメソッドが(あれば)中央のリストペインに列挙されます(クラス情報の改変のみなら、中央のリストペインは空欄のまま最下段のペインにそのむねだけが表示されます)。

     「名無し1」チェンジセットには、ちょうど第47回に終えたばかりの、日本語ファイルの扱いに関するファイルリスト不都合を修正するために加えた改変が登録されているはずです。

    [fig.B]チェンジセットに登録された改変を確認する
    http://squab.no-ip.com:8080/mosaren/uploads/50b.png

     チェンジセットが実際に保持している情報はこれ(改変されたクラスとメソッド群の名前)までです。しかし、クラスとメソッド名まで分かっていれば、そのソースコードを見たくなるのは人情ですし、メソッドもオブジェクトであるSmalltalkシステムにおいては、そのソースを“たぐる”ことは実にたやすいことです。したがって、チェンジソーターがシステムブラウザのような機能を持っていたとしても、何ら不思議なことではないでしょう。

     実際、そのようになっていて、中段リストペインに列挙されたメソッド名をクリックして選択すれば、そのメソッドのソースを閲覧できます。もちろん、必要ならばこの場で編集(再コンパイル)も可能です。

    [fig.C]システムブラウザ同様、ソースの閲覧や編集も可能
    http://squab.no-ip.com:8080/mosaren/uploads/50c.png

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

    ニュース・解説

    今週の解説担当:木下 誠

    ———————————————————————-
    CodeWarrior 10登場!
    ———————————————————————-

    ついにCodeWarrior 10が登場しました。Mac版としては、最後になるであろう、と言われているCWです。

    2つのバージョンが用意されています。1つは、学生やホビースト向けの、無料のLearning Edition。ライセンスに制限があり、テクニカルサポートはありません。もう1つは、$99で販売されるProfessional版。どちらも、ダウンロードのみです。

    細かい変更点に付いては、おそらく来週小池さんが書いてくださるでしょう。一つ、注目しておきたいポイントは、PowerPlant、PowerPlant X、Constructorが将来オープンソース化されることが明記されました。これで、オープンソースコミュニティによる、PowerPlantのサポートが現実味を帯びます。

    CodeWarrior Development Studio for Mac 10
    http://www.metrowerks.com/MW/Develop/Desktop/mac10

    ———————————————————————-
    Core Audioの紹介記事
    ———————————————————————-

    「The Sound of Opportunity Knocking: The Audio Units Community Takes Off」と、題する記事が公開されました。Core Audioを用いたアプリケーションや、デベロッパが紹介されています。

    また、Developer CDに付属するAU Labの簡単な使い方や、Audio Unitプラグインの開発の流れも併せて紹介されています。Core Audioの簡単なオーバービューを知りたい方は、目を通してみるといいと思います。

    The Sound of Opportunity Knocking: The Audio Units Community Takes Off
    http://developer.apple.com/audio/audiocommunity.html

    ———————————————————————-
    DVDPlaybackフレームワークを利用したサンプルと、
    Tabコントロールを利用したサンプル
    ———————————————————————-

    CocoaでDVDを再生するサンプル、CocoaDVDPlayerが公開されました。これは、Mac OS X 10.3から搭載されている、DVDPlayback.frameworkを使ったサンプルです。標準アプリケーションの、DVDプレイヤーと同等のことを行えるアプリケーションを作成できます。

    CocoaDVDPlayer
    http://developer.apple.com/samplecode/CocoaDVDPlayer/CocoaDVDPlayer.html

    タブコントロールを利用するサンプルも公開されています。こちらは、Carbon用です。

    TabsShowcase
    http://developer.apple.com/samplecode/TabsShowcase/TabsShowcase.html

    ———————————————————————-
    Kernel Debug Kitアップデート
    ———————————————————————-

    Kernel Debug Kitがアップデートされて、Kernel Debug Kit 10.4.3となりました。Mac OS Xのアップデートに合わせた公開です。

    Developer – Development Kits
    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=モサ伝]第181号

    2005-11-01

    目次

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

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

     今年のMOSA湘南ミーティングも無事終了し、ご参加いただいた方々ありがとうございました。さっそくですが、1点訂正があります。セッション中にOSのインストールディスクはDVDと申し上げましたが、Mac OS X ServerのパッケージにはDVDとCDの両方が含まれていました。
     さて、それでは前回に引き続き今回もサーバ構築について解説していきたいと思います。Mac OS X Serverには様々なサービスが含まれていますが、システム構築やメンテナンスに重要なサービスをご紹介してきます。

    ・WebObjects Deployment
     まずなんといってもMac OS X ServerにはWebObjectsの運用環境が含まれています。Tiger Serverからは、各種サービスを設定/管理するツール「サーバ管理」上でWebObjectsの運用環境も設定できるようになりました。ですが、設定できる項目はほとんどなく、運用環境を制御するデーモンwotaskdと、運用環境の設定をおこなうMonitorを実行するポート番号が指定できます。特に必要がなければポート番号はデフォルトのものを使えばよいでしょう。あとMonitorの起動も設定できるようになっていますが、Monitorは必要に応じて手動で起動することもできます。またwotaskdの起動も「サーバ管理」から実行できるようになっています。

    ・Web(Apache)
     WebObjectsでシステムを構築するさいにはWebサーバが別途必要になります。
    Mac OS X ServerにはApacheが搭載されていますので、これを利用できます。
     Apacheは1.3と2.0系列の2つがインストールされていますが「サーバ管理」から制御できるのは1.3系列のみになります。デフォルトの設定ですぐにサービスを起動することができますが、いくつか設定をおこなっておいたほうがよい箇所があります。まずサイトのオプション設定ですが、パフォーマンスキャッシュはOffにしておきましょう。これはパフォーマンス向上のためにWebサーバが提供するコンテンツをメモリ上にキャッシュする機能ですが、Webアプリケーションではコンテンツを動的に生成しますので、キャッシュによる効果はあまりなく、1度しか使わないデータまでキャッシュしてしまいますので、かえって逆効果になります。
     また、WebObjectsは専用のWebObjects用モジュールを用いますのでCGIを有効にする必要はありません。CGI経由で実行することもできますが、モジュールを用いたほうがパフォーマンス的にも優れています。
     あと、システムによってはデータを保護するためにSSLを用いる場合もあるでしょう。「サーバ管理」上でSSLの設定が可能ですが、Tiger ServerからはSSLの設定方法が改良されています。以前はWebサービス固有の設定としてSSLの設定をおこなっていましたが、Tiger Serverではまずサーバ全体の設定としてSSLの登録をおこない、Webサーバの設定ではサーバに登録したSSLの指定のみをおこなうように改良されています。これは、他のサービスでもSSLの設定を共通しておこなうための改良です。

    ・メール
     オンラインショッピングサイトなどでは、注文の確認メール送信などをおこなう場合もありますが、Mac OS X ServerにはPostfixを用いたメールサーバが搭載されています。こういったサービスも組み合わせることによって、より付加価値の高いシステムを構築することができます。

    ・ファイアウォール
     Mac OS X Serverでファイアウォールを設定することもできます。ですが、実際にはファイアウォールの専用機などもありますので、そちらを利用するようなケースが多いのではないかと思います。

    ・AFP/FTP/WebDAV
     メンテナンスのために、サーバへ新バージョンのアプリや画像リソースなどをアップロードしたり、ログファイルをダウンロードしたりしますが、このような作業のためにMac OS X ServerをAFPやFTPのサーバとして利用することができます。
     AFPではユーザ認証時にパスワードが暗号化されたり、Finder上から自由にファイルのアップロード/ダウンロードができますので、Mac上からメンテナンスする場合にはこちらのほうが便利でしょう。ただしAFPが使用するポートがサーバとの間で開いている必要があります。
     サーバとの間で80番のポートしか開いていないような場合はWebサービスの機能としてWebDAVが利用できますので、こちらを用いてファイル転送をおこなうこともできます。

    ・SSH
     リモートログインをおこない、サーバ上でのコマンド操作がおこなえます。SSHは他のプラットフォームからも利用できますので、コマンド操作ができればなにかと役に立ちます。WebObjectsアプリケーションの設定をおこなう場合、コマンドラインからMonitorを起動したりしますので、サーバ管理には欠かせません。SSHはMac OS X Serverではデフォルトで有効になっています。

    ・Apple Remote Desktop
     こちらは別売のソフトになりますが、用意しておくとサーバ管理がさらにやりやすくなります。Remote Desktopからリモートのサーバにファイルをコピーしたり、サーバの情報(OSのバージョンやメモリサイズなど)を確認したりできますし、なんといってもリモートの画面を直接制御できますので、サーバ機を直接操作するのとまったく同じことがリモートできます。ただし、実際に利用するにはAFPと同様にRemote Desktopが使用するポートをあらかじめ空けておく必要があるのと、画面を制御する場合にはそれなりに通信のデータ量が増えますので回線が遅いとあまりよいレスポンスは得られません。

     というわけで、Mac OS X Serverで利用できるサービスを一通りご紹介しました。次回からはまたプロジェクトの解説に戻りたいと思います。

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

     というわけで今回のテーマは「タイトルバーのないウィンドウの作り方」である。……まずはこのテーマをキッチリ把握するトコロから始めていただきたい。なにを言いたいかというと、これが「ウィンドウのタイトルバーの消し方」でないことに気づいてほしいのである。
     そうなのだ、ワタシもこれを知ったときはかなり仰天したのだが、Mac OS Xのウィンドウってクラシック環境のそれと違い、作ってしまってからそのウィンドウのタイトルバーを「要らない」つうことが出来ないのだ。前にも書いたが、そのウィンドウがタイトルバーを持つか持たないかは、初期化のメッセージ、

    -(id) initWithContentRect:(NSRect)contentRect
                  styleMask:(unsigned int)aStyle
                    backing:(NSBackingStoreType)bufferingType
                      defer:(BOOL)flag;

    の「styleMask」という引数によって決定される。そして、そのウィンドウがタイトルバーを持つか否かは、

    -(BOOL) hasTitleBar;

    というメッセージで参照できる。トコロが、あとからこの「styleMask」を変更するメソッドはどこを探してもないのである。
     いや書けば「ないのである」でおしまいだけど、そう納得するまでワタシはずいぶん探しました、これ。リーマン予想の反証を探索し続けるアンドリュー・オドリッコのように……とは言わんがあると思ってたからさ。今ではそれがない理由もなんとなく解ってきたけれど(OS Xのウィンドウはクラシックでのウィンドウに比べて遥かにシステムと密接な関係にある)、当初は「こんなあからさまな仕様後退があるはずない」とか思ったし。
     とにかく病的に猜疑心が強い一部のヒトは別にして、ワタシが通った道を皆さんがもう一度たどる必要はないわけなので、ここではそういうメッセージはないということでよろしいな。
     でだ。ならば「タイトルバーのないウィンドウの作り方」なんてのは簡単で、上の初期化メッセージを次のように使えばいい。

      NSWindow* myWindow =
      [[NSWindow alloc] initWithContentRect:myContentRect
                              styleMask:NSBorderlessWindowMask
                                backing:NSBackingStoreRetained
                                  defer:YES];

     だけど、こういう作り方をすると、このウィンドウの中身……というかこのウィンドウのcontentViewに表示するものも全部同じようにシコシコとハードコーディングしなくちゃいけなそうでしょ? で、それはとっても面倒くさい。ここはできれば文字をBOLDにしたいけれど、そんな面倒くさいことをシコシコここで出来るヒトにはプログラマなんてのよりもっとずっと向いている職業があると思う。思うでしょ?
     なのでcontentViewの中身はInterface Builder(以下IBと略)で作っておいてそれを読み込むというズル(いや、テクニックです、テクニック)をする。すなわち IB でタイトルバーつきのウィンドウとその中身を定義しておき、そいつのcontentViewのframeをcontentRectとして初期化メッセージを送る。そしてできあがったウィンドウのcontentViewを破棄し、IB で定義したウィンドウのcontentViewですり替えるわけだ。……文章で読んでも解りにくかろうから、次回この手順を具体的なコーディング例を使って詳述しよう。ほんぢゃ。
    (2005_10_26)

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

    UNIXとしてのMac OS X

    〜Perlについて(23)〜

     こんにちは、高橋真人です。
     丸カッコを使って正規表現の中にグループを作ると、その部分が記憶されるという副作用がある。こういうことを前回の最後で申しました。
     しかし、「副作用」という言い方は、ちょっと卑屈というか何というか、まるでおまけの機能であるかのように感じられてしまいますが、実際には私が正規表現に丸カッコを使うケースでは、ほとんどが「記憶のため」で、グルーピングを目的として使うことはめったにないのです。
     まあ、それはさておき具体的に丸カッコを使った記憶がどのように活用できるのかを見ていきましょう。
     以前、$&という変数に「実際にマッチした中身が記憶される」と説明したのを憶えていますでしょうか。丸カッコを使うと、この辺の制御がもっときめ細かくできるのです。つまり、正規表現の中の部分を区切って特定することができるということです。
     例えば、/a.c/という正規表現は、abcにもadcにもaBcにもマッチするわけですが、. が実際には何マッチしたのかを知りたい時には、/a(.)c/という具合に、. の部分をカッコで囲ってやるわけです。すると、実際にマッチした結果、つまりabcの時には、bが、adcの時にはdが記憶されるようになります。
     それでは具体的な題材を使って説明します。今回は複雑さを避けるために、作為的なデータを用意します。
     以下は、MOSAのWebにあるMOSAニュースのデータです。ただし、HTMLのソースを直接処理するとなると、タグの処理が不可避となるため(タグの扱いは正規表現でも難易度の高いものです)、単純にタブ区切りで並んでいる形に仕立てます。

     以下のようなデータですが、折り返すと見にくくなるので、大幅に端折りました。

    MOSA NEWS
    10.21-22 湘南ミーティングへのご参加ありがとうございました!
    会員向け<TAB>アップル技術者トレーニング割引のご案内<TAB>受付中
    会員向け<TAB>アップル技術者試験 受験料半額割引のご提供<TAB>受付中
    会員向け<TAB>MOSA会員向け掲示板開設のお知らせ<TAB>運用中
    参加受付中のセミナー、イベントなど
    2005.11.12<TAB>Dashboard ウィジェット作成セミナー<TAB>受付中
    2005.11.15<TAB>NEW!ポッドキャスティング・セミナー<TAB>受付中
    2005.11.30迄<TAB>Dashboardウィジェット コンテスト<TAB>受付中
    終了したセミナー、イベントなどのご報告
    2005.10.15<TAB>Dashboard ウィジェット作成セミナー<TAB>ご報告

     <TAB>と書いてあるところには、タブ(0×09)が入っているものと思ってください。
     さて、このデータの中から「会員向け」のものだけを拾い出し、その「タイトル」と「状態」を表示するPerlスクリプトを書いてみます。
     処理対象のデータをファイルから読み込む方が現実的かもしれませんが、まだファイルの扱いについては説明していないので、ここでは以前CGIの書き方を解説した時に使用した「ヒアドキュメント」方式を使ってスカラー変数にデータを文字列としてセットします。

    $data = <
    

     このスクリプトを走らせると、以下のように結果が出力されます。

    タイトル:アップル技術者トレーニング割引のご案内 状況:受付中
    タイトル:アップル技術者試験 受験料半額割引のご提供 状況:受付中
    タイトル:MOSA会員向け掲示板開設のお知らせ 状況:運用中
    Done

     スクリプトで使用している正規表現の中で、丸カッコで囲っている部分に注目してください。最初が([^¥t]+)で、二番目が(.+)です。カッコがあると正規表現自体がちょっと読みにくくなりますが、あくまでこのカッコは「記憶させるため」に使われているだけなので、マッチング自体には影響はありません。
     カッコを外して表記してみると、正規表現の部分は以下のようになります。

    /会員向け¥t[^¥t]+¥t.+¥n/

     ¥によるエスケープ表記が多いので少し見づらいですが、「会員向け」という文字列の直後にタブがあり、タブ以外の文字の1文字以上の連続、タブ、任意の文字(ただし改行は除く)の1文字以上の連続、そして改行文字という文字並びにマッチするようになっています。
     最初の + 記号の直前をともすると . にしてしまいがちなのですが、そうすると以前説明した「最長マッチ」の性質により、タブ自体も含まれてしまうため、例えば行の中にタブが3つや4つある文字列にもマッチしてしまうのです。ですから、否定文字クラスを使ってタブを除外することで、確実にタブとそれ以外の文字を切り分けることができるわけです。
     丸カッコを使って記憶させた文字列は、マッチした順に$1, $2, $3...と、特殊変数の中に記録されます。それで上記の例のようにタイトルと状況を拾い出せるというわけです。
     ところで、このスクリプトには実はちょっとしたバグがあります。次回はその辺についてお話ししていきましょう。

    ニュース・解説

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

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

    【開発環境】

    新型のiMac G5、PowerMac G5、PowerBook G4が相次いで発表されました。Macintoshは、来年6月からCPUをインテル版に切り換え始めるわけですが、ハイエンドマシンの方は後2年以上はPowerPCに頼ることになるので、新型PowerMac G5がどのように進化しているのかは注目の的です。予想通りDual Core CPUである「PowerPC 970MP」を2CPU搭載したマシンが登場しました。つまり、理論的には4CPUが並列で処理を行うことになります。

    しかし、旧機種よりクロック数が増加していないところを見ると、消費電力の増大と発熱には相当苦労していることが理解できます。なんと消費電力は、1チップあたりフル稼働で100Wだそうです(涙)。ちなみに最近、USのベンチャー企業P.A.Semiから、PowerPCアーキテクチャの64bitマルチコアプロセッサ「PWRficient」が発表されました。特徴は動作時の消費電力の低さで、2GHzのDual Core版での消費電力は5W〜13Wだそうです。

    何だか、インテル版へのトランジションを準備している間に、PowerPCの世界でも大きな転換がありそうです。WWDC 2007の基調講演で「インテルだけにするのは止めたぜ!」なんてJobsが言い出すかもしれません(笑)。まあ、そのころデベロッパー側はすっかり「Universal Binary対応」に慣れているでしょうから、「MacintoshにどんなCPUが搭載されてもOKだぜ!」と言うことになっているでしょう(笑)。打ちのめされたら一回り大きくなって立ち上がる星飛雄馬のごとく!

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

    前回から10月28日の期間中、Apple社のDocumentationサイトには新規ドキュメントが3つ登録されました。そのうち2つは、最近発表された新型のPowerBook G4のハードウェア仕様書です。なぜだか、新型iMac G5やPowerMac G5についてはドキュメントが登場していません。直前に仕様が変更され内容を調整中でしょうか(笑)。また、デベロッパー向け読み物も3つ登録されています。「Understanding Xcode Projects」については、前号の木下さんの記事も参照してみてください。

    「15-inch PowerBook G4 Developer Note」(PDFあり)
    「17-inch PowerBook G4 Developer Note」(PDFあり)
    「CFNetworkDiagnostics API Reference」(初版)

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

    「Designing Network-Friendly Applications」(読み物)

    http://developer.apple.com/networking/networkfriendlyapps.html

    「Aspyr Brings Their Games to Intel-based Macs」(読み物)

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

    「Understanding Xcode Projects」(読み物)

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

    前回から10月28日の期間中、新規テクニカルノートはひとつだけ登録されました。また、新規テクニカルQ&Aの方は6つ登録されています。

    TN2153「Improving Windows Screen Updating with QuickTime for Windows Double-Buffering Feature」

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

    QA1448「Sound Manager Codec support in QuickTime 7」
    QA1447「Final Cut Pro - Preferred Video Media Time Scales and Sample Durations」
    QA1430「Apple RGB and Generic RGB profiles explained」
    QA1444「Compression Sessions - Configuring codec quality settings」
    QA1267「Importer Components - What is the 'mcfg' resource used for?」
    QA1340「Registering and unregistering for sleep notifications」

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

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

    前回から10月28日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが9つ登録されました。この中で初めて登録されたサンプルは「LoginItemsAE」と「MoviePlayer」だけです。前号でも木下さんが解説されていますが、後者は本当に珍しいサンプルですね(笑)。CarbonのHIViewを勉強されている方は「ImageMapView」が良いサンプルとなります。

    「AuthForAll」(Security関連)
    「DelegateOnlyComponent」(QuickTime関連)
    「HackTV Carbon」(QuickTime関連)
    「HICustomPushButton」(HIView関連)
    「ImageMapView」(HIView関連)
    「LoginItemsAE」(Carbon関連)(初版)
    「CIVideoDemoG」(QuickTime関連)
    「MoviePlayer」(Windows QuickTime関連)(初版)
    「SoftVDigX」(QuickTime関連)

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

    【デベロップメント SDK】

    前回から10月28日の期間中、Apple社のSDKサイトには新しいSDKが3つ登録されました。「.Mac 1.2 SDK」は、Universal Binary対応版のようです。前号の木下さんの記事を参照してみてください。

    「QuickTime 7.0.3 SDK for Windows 」
    「QuickTime 7.0.3 SDK」
    「.Mac 1.2 SDK」

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

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

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