MOSA Multi-OS Software Artists

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

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

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

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

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

    2005-08-30

    目次

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

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

     今回はビジネスマッチングシステムに登録する登録者情報について、現行システムで登録可能なデータを参考にしながら検討していきたいと思います。

    認証情報

     まずはシステムを利用するにあたって必要となるユーザ認証についての情報です。現在のシステムでは登録者情報を登録するさいに、MOSA IDとメールアドレスによるユーザ認証をおこなっています。また、他の一般的な認証情報としてはパスワードを用いるような場合もあります。
     こういったユーザ認証についての情報や個人情報などは漏洩すると問題がありますので、慎重に管理する必要があります。例えばMac OS Xでのユーザ認証の仕組みをみてみますと、パスワードを暗号化したり、認証時にパスワードそのものをネットワーク上に流さないような仕組みが組み込まれています。

     Webの場合は、クライアント側で高度な処理をおこなうのはなかな難しいですが、せめてデータベース上でのパスワードの管理はセキュアにしておきたいところです。これには、パスワードを直接データベースに登録せずに暗号化したパスワードを登録するなどの対策が考えられます。パスワードの暗号化については、Javaには文字列からハッシュ値を計算するAPIがありますのでこちらを利用することができます。
     つまり、最初にパスワードを登録する時点で、一度そのパスワードからハッシュ値を求めて、パスワードそのものではなくハッシュ値をデータベースに保存しておきます。次にユーザ認証がおこなわれたときには、ユーザが入力したパスワードを、パスワード登録時に用いたのと同じ方法でハッシュ値を計算し、あらかじめデータベースに保存しておいたハッシュ値と比較します。これで、データベース上ではパスワードを暗号化した形式で保存することができます。
     ハッシュ値の計算方法ですが、WebObjects向けのオープンソースフレームワーク「Project WONDER」にはJavaの暗号化APIを用いたクラス(ERXCrypto.java)が用意されており、例えばSHA方式でハッシュ値を計算する次のようなメソッドが利用できます。このメソッドは指定した文字列からハッシュ値を計算し、文字列としてreturnしてくれます。

    ・ERXCrypto.java

        public static String shaEncode(String string) {
             if( string == null )
                 return string;
             byte[] buf = string.getBytes();
             MessageDigest md;
             try {
                 md= MessageDigest.getInstance("SHA");
             } catch (NoSuchAlgorithmException e) {
                 log.fatal("Caught "+e+" - "+ERXUtilities.stackTrace(e));
                 throw new NSForwardException(e);
             }
             md.update(buf);
             return ERXStringUtilities.byteArrayToHexString(md.digest());
         }
    

    個人情報

     現行システムでは次のような個人情報を登録することができます。

    ・個人情報
      MOSA ID, 氏名, カナ, E-MAIL, 性別, 生年月日, 現住所(都道府県)
      最終学歴, 最終卒業校(学部・学科/卒業年), 自己アピール(資格等)

     基本的にはこちらを参考にしたいと思いますが、資格情報などは個別の項目として管理するようにしたいと思います。特に今年からアップルコンピュータの技術者認定試験が日本語でも受験できるようになりましたので、この試験に合格することによって取得できる認定資格についても登録できるようにしたいと思います。

    ・アップル技術者認定資格
    http://train.apple.co.jp/certification/index.html

    技術情報

     個人情報以外に、登録者の技術情報として以下のような情報を登録することができます。

    ・OS, 使用言語, DB, WEB開発環境(実務年数)
    ・経験業務, 経験分野(実務年数)
    ・業務実績、得意分野・技術(自由入力)

     実務年数については、「経験なし」「〜1年」「1-3年」「3年〜」といった区分で登録をおこないます。この区分で単純に入力しただけでは、1年後、2年後に古い情報になってしまいますので、たまには情報の更新をおこなわないと正確な情報を管理できません。
     いつごろから使い始めたのかを入力し、そこから年数を計算するという方法もありますが、これでは途中ブランクがあったり、最初少しだけ使っただけといった場合に対応できないことになります。また、実務年数だけではなかなか技術レベルまでは分かりませんので、そもそもそれほど正確に管理するような情報ではないかもしれません。技術情報をどのように扱うかは今後の課題にしたいと思います。

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

     一週間余計に間が空いたので前回の復習から。すべてのウィンドウ・インスタンス(NSWindowのサブクラス)はfirstResponderというインスタンス変数に、そのウィンドウがKeyWindowであるときにキーボードからの入力イベントにまず反応するレスポンダを保持している、と言う話だった。覚えてますか?

     それを受けて今回の話は……、ちょっとハンズオン風にいこうか。ちょっとお手元でInterface Builderを起動し、新規でアプリケーション用のNibファイルを作ってみてもらえまいか。出来上がったNibファイルには最初、

     File’s Owner
     First Responder
     MainMenu
     Window

     という4つのアイコンが表示されているはずである。今回の話は、ここに見える「First Responder」というのと前回みた各ウィンドウが保持している「firstResponder」との関係はどうなっておるのか、ということである。字面だけ見れば、片方は大文字で始まっており「First」と「Responder」の間にスペースがあり、もう片方は小文字で始まってスペースがない、とそんだけだが、実はこの2つがそんな風にクリソツなのが混乱の元なのである。いや、だからって違う名前をつけるわけにも行かないんだが。

     上で作った(というほど「作って」ないか)Nibファイルの「MainMenu」をダブルクリックし、例えば「編集メニュー」にある「カット」がどんなターゲットのなんというアクションに結びつけられているかを確認してほしい。インスペクタ・ウィンドウを開くと、こいつは「FirstResponder」の「cut:」と連結されているはずだ。
     ここでこの「FirstResponder」の「First」と「Responder」の間にスペースがないのがまたコトをややこしくするのだが、この「FirstResponder」はつまりNibファイルのウィンドウにある「First Responder」のアイコンである。ウソだと思ったら試しにインスペクタ・ウィンドウの「cut:」をもう一度クリックしてみてごらん。メニューの「カット」と「First Responder」のアイコンを結ぶラインが表示されるはずである。
     どうしてこんな「スペースを入れたり入れなかったり」というイタズラに初心者を混乱させるような表記をしているか。いや、これ、単なる意地悪ではなくて、まぁ聞いてみればそれなりの理由があるのだ。普通、メニューアイテムやボタンなどのオブジェクトに連結されるアクションを持つのは「クラス」である。早い話、インスペクタ・ウィンドウの、今「Actions in FirstResponder」と表示されている「FirstResponder」の部分は普通「NSButton」とか「NSTableView」とか「MyObject」とか「YourSong」(ぢゃエルトン・ジョンか)とかのクラス名が表示される場所なのである。実はクラスではない特別な概念である「First Responder」だがここではクラスとして扱われている。「First Responder」と空白を挟む2つの単語で構成されるクラス名つうのはないので、ここでは泣く泣く(かどうかは知らないが)「FirstResponder」とつなげて表記されているわけだ。

     では「First Responder」とはどんな特別な概念か。さぁお立ち会い、それこそがあの「レスポンダ・チェイン」なのである。キーボードからのキー入力と同様、アプリケーションには「カット」とか「コピー」あるいは「やり直し(undo)」のように、その時々でそのアクションの担い手たるオブジェクトが変わらなければならない機能が存在する。その振り分けの複雑さを実にエレガントに解決するためにここでレスポンダ・チェインが使われるのだ。……では次回は、この「First Responder」によって表象されているレスポンダ・チェインがどういう風に使われるのかを追いかけて行くことにしよう。
    (2005_08_25)

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

    UNIXとしてのMac OS X

    〜Perlについて(19)〜

     こんにちは、高橋真人です。
     今までPerlの正規表現についてつまみ食い的に説明をしてきましたが、ここらで少し整理をしてみることにします。
     まずは、量指定子です。
     正規表現に慣れている人でも量指定子という呼び方を聞くと「一体、何のことだ?!」と思われるかもしれません。これは文字表現の後に付けてその文字をどれだけ繰り返すかなどを表現する特殊な記号で、正規表現を使う上ではなくてはならないと言ってよいぐらい頻繁に利用されるものです。
     Perlの正規表現における量指定子の主なものを挙げてみます。

    * 直前の文字の0回以上の繰り返し
    + 直前の文字の1回以上の繰り返し
    ? 直前の文字が0回もしくは1回
    {n} 直前の文字のn回の繰り返し
    {n,} 直前の文字のn回以上の繰り返し
    {x,y} 直前の文字のx回以上、y回までの繰り返し

     {n}というのがいちばん理解しやすいでしょう。これはもうそのまま、直前にある文字がn回連続して並んでいる部分にマッチします。

    a{3}

    という表現は、

    aaa

    と等価ということになります。
     次に、{x,y}は、最低でx回、多くてもy回の連続、ということですので、

    a{3,6}

    という表現は、

    aaa
    でも、
    aaaa
    でも、
    aaaaaa
    でもマッチします。

     {n,}は、{x,y}のyが省略されていると考えればよいでしょう。つまり、下限値は指定してあるが上限値はない(つまり、いくつでもよい)ということなの
    で、

    a{3,}

    という表現は、

    aaa
    も、
    aaaaaaaa
    も、
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    にもマッチします。

     以上が分かれば、残りのものも理解も容易です。
     * は、{0,}と同じで、+ は、{1,}と同じになります。そして ? は、{0,1}と同じことになります。
     これらの記号の中で、特に「0回」という意味を含む表現の場合、単独で使われることはまずありません。何故なら、特定の表現のゼロ回の繰り返しとは即ち「何もない」ことを意味するからです。
     この「何もない」は正規表現においては「どこにでもマッチする」ということになります。慣れないとこの考え方は分かりにくいのですが、例を挙げれば理解しやすいでしょう。以下のコードを見てください。

    $str = 'ABCDEFGHIJKLMN';
    
    if ($str =~ /X?/) {
        print "match.¥n";
    } else {
        print "unmatch.¥n";
    }

     走らせてみれば一目瞭然。出力は “match” となります。
     これは、正規表現では文字と文字の間は何もないと考え、上記のような表現はその「何もない場所」にマッチすることになるのです。(上記の例では、最初の「文字ではない場所」となる「Aの直前の部分」にマッチします)
     そんなわけですので、これらの「0回」を含む表現は必ず他の表現と組み合わせて使われます。たとえば、行頭の空白文字を除去したいときに以下のような書き方ができます。

    $line =~ s/^[ ?t]*//;

     s///演算子を使った文字の置き換えですが、$lineというスカラー変数に文字列が入っているとして、先頭から(^は行または文字列の先頭を表す記号です。改めて説明します)半角スペースかタブ文字が連続する部分をすべて空文字列に置き換えます。(結果的に消去されることになります)
     ここで * を使っているのは、半角スペースかタブ文字が1文字もなく、いきなり先頭から文字があるケースもあり得るからです。
     もっとも、* の代わりに + を使っても同じことが起こります。この場合マッチは行われないので、そもそも置き換えの対象にはなりません。
     ただ、文字列置換の結果は同じでも、内部で起こっていることには違いがあります。Perlにあるいくつかの特殊変数のうち、$&というのがありますが、これはパターンマッチが成功したとき、マッチした部分が格納される変数です。
     文字列先頭にスペースもタブもないとき、* を使った場合空文字列が$&に記録されますが、+ を使用した時にはマッチングが不成立なので、$&には何も記録されないのです。

    $line = 'Hello world!!!  ';
    $line =~ s/^[ ¥t]*//;
    print "matched: '$&'¥n";

     こんなコードを走らせてみると分かりますが、このコードを走らせるとコーテーションの中身はカラですが、* を + に変えて実行してみると、$&は未定義ということで実行時エラーになります。(事前に別のマッチングが行われていなければ、ですが)

    ニュース・解説

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

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

    【開発環境】

    Intelが、Mac OS X用開発ツールの最初のβ版を、今年の終わりまでに出荷する事を正式に発表したようです。しかし、出荷する予定の開発ツールにはObjective-C対応コンパイラは含まれていないようですね。

    http://www.eweek.com/article2/0,1895,1851752,00.asp

    また、Appleサイトに「Game Building Tools」というタイトルで、ゲーム開発関連のツールが紹介されています。

    http://www.apple.com/games/articles/2005/08/gamebuildingtools/

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

    前回から8月26日の期間中、Apple社のDocumentationサイトには数多くのドキュメントが登録されました。ただし、ほとんどはマイナーチェンジのみとなっています。そこで今回は、その中で初版の物と内容が大幅変更になった物だけをピックアップして記載しておきます。また、新規リリースノートが4つ、新規のデベロッパー向け読み物が2つ登録されました。リリースノートの「High Level Toolbox Release Notes」は、Carbonプログラマー必読です。読み物の「Using PyObjC for Developing Cocoa Applications with Python」については、前号の木下さんの記事を参照してみてください。

    「Attributed Strings Programming Guide」(PDFあり)
    「Automator Programming Guide」(PDFあり)
    「Carbon Event Manager Reference」(PDFあり)
    「Core Endian Reference」(PDFあり)
    「Data Formatting Guide for Core Foundation」
    「Data Formatting Programming Guide for Cocoa」
    「Directory Services Reference」(初版)
    「Disk Arbitration Reference」(初版)
    「DVD Playback Services Reference」(PDFあり)
    「HIArchive Programming Guide」(初版)(PDFあり)
    「HIObject Reference」(PDFあり)
    「Kernel Extension Concepts」(PDFあり)
    「Memory Manager Reference」(PDFあり)
    「Quartz Programming Guide for QuickDraw Developer」(PDFあり)
    「QuickTime Movie Playback Programming Guide」(PDFあり)
    「Spotlight Reference」(初版)
    「What’s New In QuickTime」

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

    リリースノート

    「What’s New In Mac OS X」(PDFあり)
    「Porting to GCC 4.0 Release Notes」
    「High Level Toolbox Release Notes」
    「High Level Toolbox Release Notes (10.4 and earlier)」

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

    「Getting Started with launchd」(読み物)

    http://developer.apple.com/macosx/launchd.html

    「Using PyObjC for Developing Cocoa Applications with Python」(読み物)

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

    前回から8月26日の期間中、新規テクニカルノートは3つ登録されました。新規テクニカルQ&Aの方はひとつ登録されています。TN2035「ColorSync on Mac OS X」では、大幅な改訂がなされています。Mac OS XにおけるColorSyncについては、このテクニカルノートが最新でもっとも詳しい資料となりますので、関連デベロッパーの方はぜひ一読してみてください。

    TN2137「Building Universal Binaries from “configure”-based Open Source Projects」
    TN2149「Obtaining 16 Bits-Per-Color Data with CUPS Raster Printing」
    TN2035「ColorSync on Mac OS X」

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

    QA1295「Java on Intel-based Macintosh Computers」

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

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

    前回から8月26日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが32登録されました。ほとんどが、Xcode 2.1に対応させるために、プロジェクトファイルが再構築され追加された形となっています(旧版Xcode用のプロジェクトファイルも含まれている)。初版のサンプルは「QTMetaData」のみです。これについては、前号の木下さんの記事を参照してください。新プロジェクトでは、InfoダイアログのGeneralで、「Cross-Developer Using Target SDK:」が「Mac OS X 10.4(Universal)」に設定されています。Xcode 2.1をインストールする時に「Mac OS X 10.4 SDK」がカスタムインストールされていないと、Makeでエラーが出てしまします。そんな時には、SDK種類をメニューから「Current Mac OS」に切り替えてから試してみてください。

    「DialogsToHIViews」(HIView関連)
    「ImproveYourImage」(QuickTime関連)
    「KillEveryOneButMe」(Carbon関連)
    「WindowFun」(Carbon関連)
    「IOPrintSuperClasses」(Hardware関連)
    「ExampleIPBCodec」(QuickTime関連)
    「SerialPortSample」(Device Drivers関連)
    「BrideOfMungGrab」(QuickTime関連)
    「CarbonTransparentWindow」(HIView関連)
    「CFNetworkHTTPDownload」(Core Foundation関連)
    「CWCocoaComponent」(Java関連)
    「enetlognke」(Device Drivers関連)
    「HIObjectThreadControlle」(HIObject関連)
    「HISimpleList」(HIView関連)
    「JSheets」(Java関連)
    「LiveVideoMixe」(QuickTime関連)
    「MachPortDump」(Darwin関連)
    「MemoryBasedBundle」(Darwin関連)
    「MovieVideoChart」(QuickTime関連)
    「MyFirstJNIProject」(Java関連)
    「PasteboardPeeker」(Carbon&Cocoa関連)
    「PDFKitLinker2」(Cocoa関連)
    「QCCocoaComponent」(Java関連)
    「QTMetaData」(QuickTime関連)(初版)
    「QuickTimeMovieContro」(QuickTime関連)
    「ScrollAndZoom」(HIView関連)
    「SimpleVideoOut」(QuickTime関連)
    「SocketCancel」(Networking関連)
    「SoftVideoOutputComponent」(QuickTime関連)
    「SpellingChecker-CocoaCarbon」(Cocoa&Carbon関連)
    「StarMenu」(HIView関連)
    「TypeServicesForUnicode」(Text関連)

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

    【デベロップメント SDK】

    前回から8月26日の期間中、Apple社のSDKサイトには新しいSDKが2つ登録されました。両方とも「CoreAudio SDK」ですが、対応しているMac OS Xのバージョンが異なりますので、利用される時には注意してください。

    「CoreAudio SDK v1.3.6」(10.2x-10.3x用)
    「CoreAudio SDK v1.4.2」(10.4用)

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

    2005-08-23

    目次

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

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

     今回はビジネスマッチングシステムの基本的な仕様を紹介しつつ、どのような実現方法があるかを考えていきたいと思います。

    ユーザ

     まずシステムを利用するユーザですが、なるべく多くの人が利用できるようにMOSA会員と非MOSA会員の両方のユーザが利用できることを考えています。またメンテナンスのための管理者によるアクセスも必要になってきます。つまりシステムを利用するユーザには複数のタイプがあるということです。
     以前紹介したユーザEntityにはユーザタイプの情報が含まれていませんでしたので、モデルを拡張しなければなりません。ユーザのタイプによらず、共通した属性(例えば氏名)を管理するのであればEntity内にユーザタイプを識別するためのAttributeを追加することによりモデルを拡張することができます。このときユーザタイプEntityを追加し、ユーザEntityとのRelationを設定すればユーザタイプを一元的に管理できるようになります。

     またタイプごとに異なった属性を管理する必要がある場合ですが、タイプごとの属性が少ないようであれば、まずはユーザEntityに必要なAttributeを追加していくことが考えられます。この場合、ユーザのタイプによっては追加したAttributeを使用したり、使用しなかったりすることになります。こういった属性が多くなればなるほど1つのEntityの構成が煩雑になり、管理もやりにくくなるでしょう。また入力が必須な属性を実現したい場合、ユーザのタイプを考慮して処理する必要が出てきます。

     このような問題を防ぐためにユーザのタイプごとにEntityを定義してしまっては、今度はタイプによらず共通した属性を管理しにくくなっています。こういった場合、オブジェクト指向でのアプローチとしては、各ユーザタイプに共通した属性だけを集約したベースクラスを作成し、そこからタイプごとにサブクラスを定義するといった方法があります。このような構造をリレーショナルデータベースで表現しようとするととたんに難しくなりますが、EOFはEntityの継承をサポートしているため、あくまでもモデル中心に設計をして、継承の関係をもったEntityを定義すれば、自動的にデータベースへのマッピングを実現することができます。
     つまり、ユーザEntityを定義しそこには各ユーザタイプに共通のAttributeのみを定義しておきます。そしてユーザEntityを継承して、MOSA会員用Entityや、非MOSA会員用Entityを追加していくことができ、ユーザタイプに依存したAttributeを定義することができます。このようにEOFの継承機能を利用すれば継承関係をもったオブジェクトの構造をデータベースへとマッピングすることができます。
     ただし、パフォーマンスへの影響も考慮する必要があり、実際にはデータの構造やアクセスパターンをよく検討したうえで利用するのがよいでしょう。

    操作

     ユーザが実行可能な操作としては、まずユーザ情報の登録があります。次にシステムの中核となるビジネスマッピングには大きく分けて次の2つの機能が必要になります。

    ・ユーザ情報を参照/検索して適切な人材を探し出す
    ・案件の情報を掲載し開発者を募集する
    ※実際には個人と法人の区別も考慮する必要があります。

     これは仕事を依頼したいクライアント側からみた機能ですが、逆に仕事を探しているユーザからみると次のような機能が必要になります。

    ・案件情報を参照/検索する

     マッチした人材あるいは案件が見つかった場合、今度は相手にコンタクトをとることになります。これらが基本的な機能となりますが、システムを利用するユーザにはMOSA会員とMOSA非会員の両方を想定しています。このシステムはMOSA会員のためのサービスですので、会員にとって有利なサービスとなる必要がありますし、会員向けに限定した情報も取り扱うことがあるでしょう。
     そこでユーザ情報にはアクセス権の設定が可能である必要が出てきます。つまり各データに対してどのタイプのユーザがアクセスすることができるのかといった情報を管理する必要が出てきます。アクセス権の管理方法としてはユーザ情報をグループ化して個別のEntityとして定義しておけば、Entity単位でのアクセス管理を実現することができます。

     さて今回は、システムの基本的な部分をどのように実現してくかを紹介してきましたが、次回はシステムで管理するユーザ情報を詳しく分析していきたいと思います。

    小池邦人のCarbon API 徒然草(2005/08/19)

    ドラッグ&ドロップの活用(その8)

    今回は、いよいよ「ドラッグ&ドロップの活用」の最終回です。Send処理のドラッグ中にテンポラリ表示される、グレイ枠と半透明画像の登録方法を解説します。ImageWellコントロールに表示されているPICT画像をドラッグ&ドロップし、別アプリケーションに受け渡す処理を想定して話を進めます。

    前回紹介したstartMyDrag()ルーチンで、ドラッグ用のグレイ枠と半透明の画像を作成している箇所は以下の部分です。まず、createRegionMyDrag()ルーチンで、グレイ枠用のRegion(RgnHandle)を作成しています。このRegionは、TrackDrag()に引数として渡すことで、ドラッグが継続される間はマウスカーソルの動きに追随して表示されます。半透明の画像の方を作成しているのは、createImageMyDrag()ルーチンです。こちらの処理は、表示させたい画像のPixMapHandleをSetDragImage()に渡すことで実現します。ここでは、画像のPixMapHandleを得るために、同矩形サイズのGWorldを確保し使用します。ちなみに、半透明の画像表示はオプションですので、対応する画像が無いなどの理由で、そちらの表示は省くことも可能です。その場合には、createRegionMyDrag()だけを実行すればOKです。

        chk1=chk2=1;
        if( rgn1=NewRgn() )
            chk1=createRegionMyDrag( window,chd,rgn1 ); // グレイ枠を作成
        if( rgn2=NewRgn() )
            chk2=createImageMyDrag( window,chd,dref,rgn2,&gptr ); // 半透明画像作成
    


    Send処理が終了した時点で、2つのRegionと1つのGWorldは必要なくなりますので、それぞれ削除しておくことを忘れないでください。この処理を忘れていると、ドラッグ&ドロップを実行する度にメモリーリークが発生することになります。

        if( rgn1 )
           DisposeRgn( rgn1 );     // グレイ枠用のRegionを削除
        if( rgn2 )
           DisposeRgn( rgn2 );     // 半透明画像用のRegionを削除
        if( gptr )
           DisposeGWorld( gptr );  // 半透明画像用のGworldを削除
    


    以下が、グレイ枠表示用のRegionを作成しているcreateRegionMyDrag()ルーチンです。まずは、IsControlActive()により、対象となるImageWellコントロールがアクティブかどうかを確認しています。そして、GetControlBounds()でコントロールの矩形枠を得て、それをRectRgn()でRegionへと変換します。そこからまったく同じRegionを複製し、サイズを上下左右1ピクセルだけ小さくした後に、DiffRgn()により差分を抽出します。これでグレイ枠用のRegionが完成しました。この時に注意する点は、このRegionの座標はグローバル座標でなければいけないということです。そのため、LocalToGlobal()で左上原点をグローバル座標へと変換し、得られたX,Y座標値をOffsetRgn()に渡し、完成したRegionを平行移動させておきます。

    short createRegionMyDrag( WindowRef window,ControlRef chd,RgnHandle rgn )
    {
        short            ret=1;
        RgnHandle        rgn1;
        Rect             drt;
        Point            pt1;
    
        pt1.h=pt1.v=0;
        SetPortWindowPort( window );
        if( IsControlActive( chd ) )      // ImageWellコントロールはアクティブか?
        {
            GetControlBounds( chd,&drt ); // コントロールの矩形枠を得る
            rgn1=NewRgn();                // 新しいテンポラリRegionを作成
            RectRgn( rgn,&drt );          // Regionにコントロールの矩形枠をセット
            CopyRgn( rgn,rgn1 );          // Regionを複製
            InsetRgn( rgn1,1,1 );         // Regionを上下左右1ピクセルだけ縮小
            DiffRgn( rgn,rgn1,rgn );      // 2つのRegionの差分を抽出する
            LocalToGlobal( &pt1 );        // 左上原点のグローバル座標を得る
            OffsetRgn( rgn,pt1.h,pt1.v ); // 完成したRegionの座標を平行移動
            DisposeRgn( rgn1 );           // テンポラリRegionを削除
            ret=noErr;
        }
        return( ret );
    }
    


    次は、ドラッグ時に表示される半透明画像を登録するためのcreateImageMyDrag()ルーチンです。グレイ枠の時と同様に、最初に対象となるImageWellコントロールがアクティブかどうかを確認しています。続いて、コントロール枠の左上をドラッグの基点として、そのグローバル座標を得ておきます。getMyControlWellPict()ルーチンで、コントロールに表示されているPICT画像のPicHandleを得て、自作のfitRect()ルーチンによりコントロール枠内に収まるようにフレームを調整しておきます。その後、コントロール枠と同じサイズのGWorldを作成し、そこにPICT画像を描画します。最後に、GWorldに確保されているPixMapHandle、矩形枠用のRegion、そしてドラッグ開始の基準点などをSetDragImage()に渡して半透明画像の登録は終了します。画像の半透明度は、引数で渡すパラメータにより変更可能です(Drag.hを参照)。

    short createImageMyDrag( WindowRef window,DragReference dref,ControlRef chd,
                                                    RgnHandle rgn,GWorldPtr *gptr )
    {
        Rect             srt,drt,frt;
        short            chk,ret=1;
        PicHandle        pict=0L;
        GWorldPtr        cptr;
        GDHandle         ghd;
        PixMapHandle     phd;
        Point            pt1;
    
        GetGWorld( &cptr,&ghd );
        SetPortWindowPort( window );
        if( IsControlActive( chd ) )      // ImageWellコントロールはアクティブか?
        {
            GetControlBounds( chd,&drt ); // コントロールの矩形枠を得る
            pt1.h=drt.left;               // ドラッグ開始座標の設定
            pt1.v=drt.top;
            LocalToGlobal( &pt1 );        // 矩形枠の左上をグローバル座標へ変換
            if( ! getMyControlWellPict( chd,&pict ) )  // 表示画像のPicHandleを得る
            {
                OffsetRect( &drt,-drt.left,-drt.top );
                srt=(*pict)->picFrame;                 // PICT画像のフレーム枠
                OffsetRect( &srt,-srt.left,-srt.top );
                fitRect( 1,&drt,&srt,&frt );           // 矩形枠調整用の自作ルーチン
                if( ! NewGWorld( gptr,32,&drt,NULL,NULL,0 ) ) // GWorldを作成
                {
                    phd=GetGWorldPixMap( *gptr ); // GWorldのPixMapHandleを得る
                    SetGWorld( *gptr,NULL );      // 描画対象をGWorldに
                    LockPixels( phd );            // PixMapHandleをロック
                    EraseRect( &drt );            // 白色でペイントする
                    DrawPicture( pict,&frt );     // PICT画像を描画する
                    UnlockPixels( phd );          // PixMapHandleをアンロック
                    SetGWorld( cptr,ghd );
                    RectRgn( rgn,&drt );          // GWorld矩形枠のRegionを作成
                    ret=SetDragImage( dref,phd,rgn,pt1,kDragDarkTranslucency );
                }                                 // ドラッグ用半透明画像として登録
            }
        }
        return( ret );
    }
    
    enum {
      kDragStandardTranslucency     = 0L,   // 透明度 65%
      kDragDarkTranslucency         = 1L,   // 透明度 50%
      kDragDarkerTranslucency       = 2L,   // 透明度 25%
      kDragOpaqueTranslucency       = 3L    // 透明ではない
    };
    


    以下は、ImageWellコントロールに表示されているPICT画像のPicHandleを抽出するために用意したgetMyControlWellPict()ルーチンです。表示画像のデータ内容(アイコンなどの場合もある)を抽出するには、ControlButtonContentInfo構造体に適切なパラメータをセットしてから、GetImageWellContentInfo()を実行します。

    short getMyControlWellPict( ControlRef chd,PicHandle *pict )
    {
        short                       ret=1;
        ControlButtonContentInfo    info;
    
        *pict=info.u.picture=NULL;
        info.contentType=kControlContentPictHandle;   // PicHandleを得ることを指示
        if( ! GetImageWellContentInfo( chd,&info ) )  // 表示画像(PicHandle)を得る
        {
            if( info.contentType==kControlContentPictHandle )  // PicHandleを確認
            {
                *pict=info.u.picture; // 得られたPicHandleを引数として返す
                 ret=noErr;
            }
        }
        return( ret );
    }
    


    本サンプルアプリケーションでは、データブラウザに登録された画像ファイルをダブルクリックすることで、スクロールバー付きのウィンドウへ表示することが可能です。次回からは、画像表示用ウィンドウをどう実装するかについて解説していきたいと思います。

    つづく

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、第12回で取りあげた日本語ファイルストリームの扱いを復習しながら、ファイルリストが文字化けを起こす原因を考え、その元凶となるメソッドをSmalltalkシステムならではの便利機能を用いて突き止めてみます。

    ▼文字化けを故意に起こしてみる
     日本語ファイルは、そこで使われる文字コードにマッチしたコンバータオブジェクトを介在させることで、はじめて正しく読み書きできる…ということは第12回で説明したとおりです。つまり、文字化けは、コンバータの不一致により引き起こされるわけです。これは簡単に試すことができます。

     まず、新しいワークスペースを開き(デスクトップメニューから「開く…」→「ワークスペース」)、次のスクリプトをコピー&ペーストした後、あらためて全体を選択し、print it(黄ボタンメニューから「式を表示」もしくはcmd-P)してみてください。ここでShiftJisExample.txtには、第12回でシフトJISコードの日本語文字列を収めたファイルをそのまま利用しています。該当するものがなければ、適当なエディタで同名ファイルを作ってNihongoSqueak7フォルダにあらかじめ入れておく必要があります。

    | file |
    file _ FileStream fileNamed: 'ShiftJisExample.txt'.
    file converter: ShiftJISTextConverter new.
    ^ {file converter. file contents}
    
    " => #(a ShiftJISTextConverter 'シフトJISの日本語文字列') "

     返値の配列の第1要素はコンバータ、第2要素は読みとったファイルの内容を表わしています。ファイルに使われている文字コードがコンバータのそれと一致しているため、文字化けせずに読めるはずです。

     ではコンバータをわざと別のものに変えてみましょう。

    | file |
    file _ FileStream fileNamed: 'ShiftJisExample.txt'.
    file converter: Latin1TextConverter new.
    ^ {file converter. file contents}

     配信されるメールに不都合があるといけないので、結果はここには示しませんが、注文通り文字化けするはずです。ファイルリストにおける文字化けもこれと同じで、内容を表示する際に用いられたファイルストリームのコンバータが正しくシフトJISのものになっていなかったのが原因だと推察できます(簡単のため、そういうことにしておいてください…)。

    ▼edit送信時の文字化けはコンバータの設定とは無関係
     では、editメッセージを送る前に、正しいコンバータを指定していないのが原因か…というとそうでもないようです。次のスクリプトをdo itしてみてください。

    | file |
    file _ FileStream fileNamed: 'ShiftJisExample.txt'.
    file converter: ShiftJISTextConverter new.
    file edit

     変わらず文字化けしたままですね。どうやらファイルリストは、あらかじめ設定されたコンバータは使わずに、独自のコンバータの設定でファイルストリームの読み取りをしているように見受けられます。

    ▼FileListはどんなコンバータ設定をしているのかを調べる
     コンバータの設定には#converter:を使うので、FileListの中で#converter:を起動するためのメッセージ送信を行なっている箇所を突き止めれば、どんなコンバータを割り当てているのかを調べることはできそうです。じつはSmalltalkでは、あるメソッドを起動するためのメッセージ送信がどのクラスのどのメソッドで行なわれているのかについて、ほぼすべてをシステムが把握しているので、こうしたことは簡単に調査できます。

     先ほどのスクリプト中の「converter:」をダブルクリックするなどして選択し「senders of it」(そのメソッドを起動するためのメッセージの送信元)を意味するcmd-Nをタイプします。すると#converter:を起動するためのメッセージ式を含むメソッドの一覧が作られ、その各々の定義を見ることができる特殊なブラウザが画面に現われます。

    [fig.A]#converter:を起動するためのメッセージを含む全メソッド
    http://squab.no-ip.com:8080/mosaren/uploads/45a.png

     上のペインのリスト中、FileListに定義されているメソッド群に注目しましょう。これらの中で、文字コードを明示的に指定していなさそうなのは、名前と定義内容から#readContentsBrief:だけだと分かります(簡単のため、そういうことにしておいてください…)。

    ▼注目メソッドに“印”を付けて、その起動を確認する
     ここで、ちょっとイタズラをして、ファイルリストがファイルの内容を表示するとき実際に、このメソッドを起動しているかどうかを確認してみましょう。

     #readContentsBrief:の定義中どこでもいいのですが、テンポラリ変数の宣言の後にちょうど一行空いているので、そこに次の式を追加します。

    ‘bingo!’ displayAt: 0 @ 0.

     この式は、読んで字の通り、「bingo!」という文字列をビットマップとして画面左上に表示するためのものです。コピーして、ブラウザの該当個所にペーストしたら、コンパイルのため、accept(黄ボタンメニューの「了解」もしくはcmd-S)します。イニシャルを尋ねられたら、適当にタイプしてこれもacceptします。ここで設定したイニシャルはUtilities setAuthorInitialsをdo itすることで、後からいつでも変更可能ですので、本当に適当なもので構いません。

     無事、コンパイルが終わると(Smalltalk ではコンパイルはメソッド単位で行なわれます)、次からこのメソッドが起動するたびに画面の左上にbingo!という文字が現われるようになります。C言語のprintfデバッグにちょっと似ていなくもありませんね。

     実際に、エディタモードのファイルリストを開いてみます。

    (FileStream fileNamed: ‘ShiftJisExample.txt’) edit

     いかがでしょう。画面左上にbingo!の文字は現われましたか? まさにビンゴ。かなりアバウトな探し方でしたが、どうやらこの#readContentsBrief:メソッドで当たりのようです。そうすると、

    f converter: (self defaultEncoderFor: self fullName).

    としているところで、正しいコンバータを指定してやれば文字化けは解消できる、ということになります。

     どうやら問題の核心に近づくことができたようですが、字数のほうがかなりオーバー気味なので、この続きは次回。

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

    ニュース・解説

    今週の解説担当:木下 誠

    ———————————————————————-
    多くのドキュメントがアップデート
    ———————————————————————-

    ADCでは、8/10、11日付けで、多くのドキュメントがアップデートされました。ほとんどはマイナーアップデートで、内容を現状に合わせて更新したり、ドキュメントのカテゴリの再構築等を行ったようです。

    更新されたドキュメントは、Xcodeのアップデート機能を利用して、August 2005 ADC Refrence Libraryとして取得できます。

    ———————————————————————-
    PyObjCの紹介記事
    ———————————————————————-

    スクリプティング言語PythonからCocoaを呼び出す方法を解説したドキュメント、「Using PyObjC for Developing Cocoa Applications with Python」が公開されました。PyObjCを使うことで、Pythonを利用してCocoaアプリケーションを開発することができます。また、XcodeやInterface Builderとも統合されているようで、それらの利点を活かすことができます。

    CocoaはObjective-Cで組み立てられているので、あちこちで動的な特徴を見ることができます。その点を利用するために、Pythonのような柔軟なオブジェクト指向を持つ、スクリプティング言語が似合うのでしょう。Cocoaのブリッジとしては他に、RubyCocoaも古くからありますし、Objective-Cをベースとする新しいスクリプティング言語を作ろうとするCocoaMillなどもあります。

    Cocoaとスクリプティング言語は相性がよく、このまま盛り上がっていけば、サーバなどで活躍する時が来るかもしれません。

    Using PyObjC for Developing Cocoa Applications with Python
    http://developer.apple.com/cocoa/pyobjc.html
    RubyCocoa
    http://rubycocoa.sourceforge.net/doc/index.ja.html
    CocoaMill
    http://cocoamill.sourceforge.jp/cgi-bin/ja/index.cgi?FrontPage

    ———————————————————————-
    QuickTimeのメタデータにアクセスするサンプル
    ———————————————————————-

    QuickTimeのメタデータにアクセスするサンプル、QTMetaDataが公開されました。QuickTimeのMetaData APIを利用して、ムービーの情報を取得します。

    メタデータにアクセスするには、QTMetaDataで始まるAPIを使っているのですが、使用条件を見ると、これらはMac OS X 10.3でも使えるようです。

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

    ———————————————————————-
    Directory ServiceとDisk Arbitrationのリファレンスが公開
    ———————————————————————-

    2つのリファレンスが新規に公開されました。

    1つは、Directory Services Referenceです。Open Directoryをサポートするためのフレームワークです。

    もう1つは、Disk Arbitrationです。ディスクのマウント/アンマウントの監視等を行います。

    Directory Services Reference
    http://developer.apple.com/documentation/Networking/Reference/DirectoryServiceFramework/index.html
    Disk Arbiration
    http://developer.apple.com/documentation/Darwin/Reference/DiscArbitrationFramework/index.html

    ———————————————————————-
    Core Imageプログラミングガイド日本語訳
    ———————————————————————-

    Core Imageプログラミングの導入となるドキュメント「Core Iamge Programming Guide」の日本語訳、「Core Imageプログラミングガイド概論」が登場していました。

    Core Imageの概念から始まり、フィルタの使用方法、カスタムフィルタの作成方法、そしてすべてのフィルタのリファレンスがあります。特に、フィルタのリファレンスは、Core Imageプログラミングに必須のものなので、大変役に立つでしょう。

    Core Imageプログラミングガイド概論
    http://developer.apple.com/ja/documentation/GraphicsImaging/Conceptual/CoreImaging/index.html

    ———————————————————————-
    Objective-Cの連載始まる
    ———————————————————————-

    手前味噌で恐縮なんですが、MYCOM PC WEBで、Objective-CとCocoaを解説する連載、「ダイナミックObjective-C」が始まりました。基本的にObjective-Cの解説ですが、タイトルの通り「動的」ということをキーワードに展開していきます。

    Objective-Cは非常にマイナーな言語ですが、Cocoaでプログラミングするには、避けては通れない言語です。また、最近スクリプティング言語が盛り上がっていますが、それらを語るときに、動的言語ならではの使いやすさ、というものがあります。Objective-Cも、動的な型付けや、メソッドの動的束縛など、動的な特性を多く持っています。そのあたりを、深く掘り下げていく連載になります。

    毎週水曜日掲載です。

    ダイナミックObjective-C

    http://pcweb.mycom.co.jp/column/objc/

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

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

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

    2005-08-09

    目次

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

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

     いよいよ日本でもiTunes Music Store(以下iTMS)のサービスが開始されました。iTMSがWebObjectsで構築されていることはすでにご存知の方もいらっしゃるかと思いますが、iTMS本体以外にも例えばこんなところでWebObjectsが利用されていたりします。

    ・iTunes Link Maker
    http://phobos.apple.com/WebObjects/MZSearch.woa/wa/itmsLinkMaker

     これはiTunes上に特定の曲などを表示させるためのリンク用HTMLを自動生成してくれるサービスです。日本版iTMSがオープンする以前から提供されていたサービスですが、さっそく日本版のiTMSへのリンクも生成できるようになっています。ですが、残念ながら日本語による検索には対応していないようです。
    ※ただし、検索結果に日本語は表示される
     日本でもiTMSがスタートしたことにより、WebObjectsへの注目度も上がってもらいたいものですね。

    モデルファイルの検証

     さて、これまでデータベースやモデル、フレームワークについて取り上げてきました。これからいよいよアプリケーション本体の開発へと入っていきたいと思いますが、ここでモデルファイルの検証方法をご紹介しておきます。
     モデルファイルの情報が正しく設定されていませんと、データベースとオブジェクトのマッピングに問題が生じ、アプリケーションが動作しなくなってしまいます。
     モデルファイルが正しく機能するかを確認するには、実際にアプリケーションから利用してみるという方法があります。アプリケーション本体の開発はこれからだというのに、どうやってアプリケーションから利用するのだということになりますが、WebObjectsではモデルファイルさえあれば自動的にアプリケーションを構築できる機能があるのです。

    Direct To Web

     具体的な方法ですが、Xcodeで”Direct To Web Application”(以下D2W)タイプの新規プロジェクトを作成します。このときプロジェクト作成のアシスタントで動作を確認したいモデルファイルを選択し、プロジェクトに追加します。プロジェクトが自動生成されたら後はビルドと実行をするだけで、検証対象のモデルファイルを利用したアプリケーションが起動します。
     このD2Wのアプリケーションはあらかじめ、データベースにアクセスするための基本的な機能をもっており、各Entityのデータの追加/変更/削除/検索などができてしまいます。また、リレーションの編集機能も備えていますのでデータベースに対して様々な操作を実際に試してみることができます。
     コードを1行も書かずに、モデルに応じたアプリケーションが出来上がりますので、なにか問題が生じたとなると原因はモデルファイルにある確率がかなり高いといえるでしょう。このようにしてモデルファイルを検証できるわけですが、なにもコードを追加しないデフォルトの状態では日本語データを正しく扱うことができませんので、最低限日本語エンコーディング処理のためのコードは追加してあげる必要があります。

     D2Wのアプリケーションは様々なカスタマイズもできるのですが、デフォルトの状態でデータベースにアクセスする基本的な機能を備えているため、モデルファイルの検証や、あるいはマスターデータのメンテナンスといった用途にも用いることができます。
     あくまでもアプリケーションが出来上がるため、モデルファイルの検証は手動でおこなう必要があり、テスト用のデータを登録したらしたで、そのデータをどのようにクリアするかといった課題もありますが、なんといっても手軽にアプリケーションを構築できますので、非常にお手軽です。
     検証対象のモデルファイルは直接プロジェクトに登録してもよいですし、すでにモデルファイルを含んだフレームワークが存在する場合は、フレームワークをプロジェクトに追加して検証をおこなうこともできます。
     D2Wではモデル情報に基づいたアプリケーションが動的に構成されますので、モデルを変更した場合、再ビルドするだけですぐに変更内容が反映されたアプリケーションを実行することができます。
     特にこれから初めてモデルファイルを作成するような方々は、今回紹介したD2Wを利用してモデルファイルが正しく機能することを確認してから、自信をもってアプリケーション本体の開発に移っていくのがよいでしょう。

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

     いや毎日暑いねぇ。こう暑いと勤労意欲の減退もたけなわになる……というのは先般亡くなった永島慎二さんのマンガで覚えた言い回しだったなぁ確か。とにかく承前、レスポンダ・チェインの話を続ける。前回まで、ウィンドウ内に配置されたNSViewの mouseDown: をオーバーライドして、このテのイベントを「処理する順番」が、このチェインによって管理されていることをみた。
     そして同時にこんな、「ただ何かを表示するためだけ」のビューを重ねてその下(というか裏というか)にあるビューにイベントを処理させるなんてことを意識的にやることも少なそうだと指摘した。……意識しないでやってることはあるんだけどね。だって重ねた方のビューの イベントハンドリング・メソッド(mouseDown: など)をオーバーライドしなければ自然そうなるんだから。ここまでよろしいか。

     レスポンダ・チェインの今ひとつの活躍どころについて説明を始める前に、まず各ウィンドウごとに保持されている firstResponder というインスタンス変数について正しい理解をしていただく。これがわかんないとあとが全然わかんなくなるのだ。
     たとえばここに1つのダイアログがあるとする。ダイアログには5つ、NSView(のサブクラス)が配置されている。1つはNSButtonで、あとの4つはNSTextField、そのうちの2つは入力域だとする……。
     もすこし具体的でないとイメージが湧かないか。なんでもいいが、身近なところでいこう。最初の NSTextField はEditableではなく、「アカウント:」という文字列をそのstringValueとして保持している。その右に置かれたNSTextFieldはEditableで、初期値は指定されていない。これらと同じペアがその下にもうひとつありそのEditableでないほうの初期値は「パスワード」。NSButtonの表示は「ログイン」となっている。よく見かけるあれである。
     Interface Builderでこんなダイアログを作成し、まずは「Test Interface」で動かしてみてほしい。キーボードからの入力を受け取るキャレットは、2つのEditableなNSTextFieldのうち最初に作ったほう、すなわち「アカウント」という文字の横のヤツの中で点滅していると思う。いや、どっちを最初に作ったかもうわかんなくなっちゃったヒトは、キャレットがある方が先に作ったもんなのよ。信じてくれ(笑)。
     テストを終了し、このウィンドウのインスペクタ・ウィンドウを開いてほしい。コネクションをみると、アウトレットのところに「initialFirstResponder」というのがあるはずだ。今は何もつながってない。ここに「パスワード」の横のNSTextFieldを結びつけて再度「Test Interface」を行なうと……、キャレットは下の入力域で点滅するようになったでしょ?

     マウスのイベントは、それが発生した時にカーソルの下にあった……て言い方も変だが、ビューがまず最初にそれに応える機会を与えられる。前回みたように、そのビューが応じるつもりがない場合だけ(つうかそれに対応するメソッドをオーバーライドしていないと)、そのビューのインスタンス変数である_nextResponder が参照されイベントがパスされる。
     けれどキーボードからの入力の場合は事情がちょっと違う。上でみたように、ウィンドウに入力域が複数ある場合には、あらかじめどっちの入力域がそれを受け取るのか、ユーザーに見えていないといけないわけだ。いわゆる「アクティブなビュー」である。mouseDown: のように発生場所によって応答の優先権を持つビューが決まらない種類のイベントは、まずこのアクティブなビューに渡される(そしてもしそいつが応答しなければマウスイベントの時と同様、レスポンダ・チェインが辿られる)。このアクティブなビューが「ウィンドウのfirstResponder」であり、Interface Builderでウィンドウにあるアウトレットが「initial firstResponder」であることからも分かるようにこの変数はプログラムやユーザーによって変更されうる。そう、さっきのウィンドウでタブ・キーを押すとキャレットの位置が替わる、あれのことね。
     次回は「ウィンドウごとにfirstResponderがあるなら、アプリケーションのNibファイルを作ると最初っから出来てる『First Responder』ってのはなに?」という話をする予定。ではみなさんよい夏休みを。
    (2005_08_06)

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

    UNIXとしてのMac OS X

    〜Perlについて(18)〜

     こんにちは、高橋真人です。
     さて前回の最初の方で、「条件判断の中で使われるm//演算子にgオプションを指定することには余り意味がない」と言いました。検索する対象がいくつあろうがヒットすることには変わりがないというわけです。
     しかし、実はそうでもないのです。
     前回は、話を複雑にするのを避けるためにあえてこのような説明をしたのですが、if節で使われるような、つまりスカラーコンテキストでm//演算子が使われるときにgオプションを指定してあると、少し興味深い独特の動きをするのです。
     説明のために前回の例に少し手を加えてみます。

    $string = 'aBcdefABCdefabcffabc';
    if ($string =~ /(abc)/gi) {
        print $1, "¥n";
    }
    


     注意してほしい変更点は、検索に使う正規表現のabcの前後を丸カッコで囲ってあるところです。正規表現部分をカッコで囲うと、マッチしたものを記憶するという機能があるのです。記憶されたものは$1という特殊変数(カッコで囲ったところが複数ある場合は、順に$2、$3…と増えていく)に記録されます。
     このカッコで囲って記憶する仕組みは非常に強力な機能なので、いずれ改めて説明しますが、今回は、print演算子に与えている$1という変数にはパターンマッチングの結果が入っているのだと理解してください。
     とりあえず、走らせてみましょう。結果は、

    aBc

    となりました。
     さて、ここでのm//演算子にはgオプションと同時にiオプションも指定されていたので、パターンマッチングには大文字と小文字が区別されず、照合結果として文字列先頭の’aBc’が記録されました。
     それでは、残りの部分はどうなってしまったのでしょう? gオプションを指定しているのだから、あと3回はマッチするはずです。
     実は、スカラーコンテキストで使われた場合、gオプション付きのm//演算子は、最初の一つしか照合しないのです。その代わり、「どこまで調べたか」を内部に記憶しています。そして、次に同様に呼び出された時には、今度は記憶されていた場所から照合を開始するのです。
     実際に試してみましょう。

    $string = 'aBcdefABCdefabcffabc';
    while (1) {
        unless ($string =~ /(abc)/gi) {
            last;
        }
    
        print $1, "¥n";
    }
    print "Done.¥n";

     結果は、

    aBc
    ABC
    abc
    abc
    Done.

    となりました。
     簡単にコードを解説します。ループするごとに、$stringとのパターンマッチングを行い、マッチした結果をプリントしています。マッチしなくなったら終了です。unlessは以前にも触れましたが、ifの逆で、条件判断が不成立の場合に処理を実行します。lastはCでのbreakに匹敵すると思ってください。
     ちなみに、以下のように書いても同じですし、慣れた人にはこちらの方が直接的な表現かもしれません。

    while ($string =~ /(abc)/gi) {
        print $1, "¥n";
    }

     いかがですか?
     上記の例は極めて単純なので、余り価値が分からないかもしれませんが、正規表現では、当然さらに複雑な文字列照合を行えますので、応用範囲は広いと思います。例えばhtmlの中から特定の条件に合うリンクを抽出して、ダウンロードするなどという処理も、このやり方を応用すればできるでしょう。

    ニュース・解説

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

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

    【開発環境】

    iPodユーザ待望の「iTunes Music Store日本版」の開始、2ボタン+ホイールマウスユーザ待望の「Mighty Mouse」の発表、そして「AppleStore渋谷店」の営業開始と、Apple社からの大きな発表が続いています。筆者も、速攻でMighty Mouseを購入して愛用しだしました。当然、将来的にはこのマウスがiMacやPowerMacに標準で添付されることになるでしょう。上部に追加された小さなトラックボールの使い勝手がとても良く、「これを自作アプリにどのように活用しようか?」と、さっそく作戦を練り始めました(笑)。

    まずは、マウスドラッグで行っていたボクセルオブジェクトの3D回転を、このトラックボールに割り振れるようにアプリケーションを改良してみようと考えています。パソコン用の優秀(クール)な周辺機器は、今までのアプリのユーザインターフェースを再考し変化させるきっかけを与えてくれます。まあ、マウス自体の登場ががそうしたパラダイム変化を引き起こした一番の好例なのですが…。今回は、それほど大きな変化ではないのですが、まだまだそうした機会が訪れる可能性があると言うことを、「Mighty Mouse」は我々デベロッパーに教えてくれています。

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

    前回から8月5日の期間中、Apple社のDocumentationサイトには新規ドキュメントが2つ登録されました。加えて、デベロッパー向け読み物が2つ登録されています。最近発表された新機種については、iBookの仕様ドキュメントのみが発表され、Mac miniの方は出てきませんので、今回のMac miniは本当に何も仕様が変更されていないのでしょうね(笑)「Xsan Migration Guide for Xsan 1.1」と、読み物の「plasq’s Small Team Makes Comic Life Media-Rich and Fun」については、前号の木下さんの記事も参照してみてください。

    「Xsan Migration Guide for Xsan 1.1」(PDFあり)SV
    「iBook Developer Note」(PDFあり)HW

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

    「Introduction to Open Source Scripting on Mac OS X」(読み物)

    http://developer.apple.com/internet/opensource/opensourcescripting.html

    「plasq’s Small Team Makes Comic Life Media-Rich and Fun」(読み物)

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

    前回から8月5日の期間中、新規テクニカルノートはひとつだけ登録されましたが、新規テクニカルQ&Aの方は登録されませんでした。このテクニカルノートでは、QuickTimeコンポーネントをUniversal Binaryに対応させるための解説がなされています。途中で’thng’リソースについての話が出てきて、そこでリソース編集用として「Resourcerer」が使われています。リソースの必要性(現状でも)が理解できているのなら、Xcode Toolsにもちゃんとしたリソース編集用ツールを付けて欲しいものです(笑)。このテクニカルノートついては、前号の木下さんの記事も参照してみてください。

    TN2012 「Building QuickTime Components for Mac OS X」

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

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

    前回から8月5日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが25登録されました。QuickTime APIをモダンAPIへと差し替えるためのサンプル提供が続いています。また、Cocoa用のQTKitに関連するサンプルも充実してきました。サンプルソースコードの中には、Universal Binary対応済みのプロジェクトも含まれていますので、試すことが可能な環境を所有されている方は、ぜひチャレンジしてみてください。

    「AlbumToSlideshow」(Final Cut Pro関連)
    「CIAnnotation」(Cocoa関連 )
    「JavaSplashScreen」(Java関連)
    「simpleJavaLauncher」(Java関連)
    「QTKitCreateMovie」(QuickTime関連)
    「QTKitFrameStepper」(QuickTime関連)
    「QTKitProgressTester」(QuickTime関連)
    「QTKitSimpleDocument」(QuickTime関連)
    「QTKitAdvancedDocument」(QuickTime関連)
    「VideoViewer」(QuickTime関連)
    「CryptNoMore」(Security関連)
    「KauthORama」(Security関連)
    「SimpleDial」(Networking関連)
    「SimpleReach」(Networking関連)
    「ThreadsExporter」(QuickTime関連)
    「ThreadsImporter」(QuickTime関連)
    「ThreadsExportMovie」(QuickTime関連)
    「ThreadsImportMovie」(QuickTime関連)
    「BackgroundExporter」(QuickTime関連)
    「CFLocalServer」(Core Foundation関連)
    「CarbonTransparentWindow」(HIView関連)(初版)
    「WhackedTV」(QuickTime関連)
    「DropDraw」(QuickTime関連)
    「ImageApp」(Core Image関連)
    「Fiendishthngs」(QuickTime関連)

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

    【デベロップメント SDK】

    前回から8月5日の期間中、Apple社のSDKサイトには新しいSDKが2つ登録されました。両方ともAudio関連のSDKです。

    「CoreAudio SDK v1.3.6」
    「Apple Loops SDK 1.3.1 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=モサ伝]第170号

    2005-08-02

    目次

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

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

     モデルファイルの説明で1つ解説し忘れていたところがありましたので、今回はその補足からおこなっていきたいと思います。モデルの生成方法は以前説明したのですが、モデルはデータベースとオブジェクトのマッピング情報を保持しています。データを保存するのはデータベースですので、データベースの構築も別途おこなっておく必要があります。
     そのために、まずはデータベースの新規作成が必要になってきますが、こちらはデータベースの管理ソフト上であらかじめおこなっておくのがよいでしょう。OpenBaseを用いる場合は、データベースのエンコーディング指定や、システム起動時の自動起動などが管理ツール上(OpenBaseManager)で設定できます。
     データベースを作成した次は、モデルで定義したEntityやAttributeに対応するテーブルを追加していきます。モデル上にはデータベース上でのカラム名やデータ型を定義してありますので、これらの情報に基づいてテーブルを作成していけばよいわけですが、EOModelerにモデルの情報に基づいてSQLを自動生成し、データベース上にテーブルを作成する機能があります。

     ツールバーの「SQL」ボタンか「Property」メニューの「Generate SQL…」を実行しますと自動生成されたSQLを確認することができます。新規にテーブルを作成する場合は「Create Tables」にチェックをいれ「Execute SQL」ボタンをクリックすることにより、あらかじめモデルの接続情報で設定しておいた接続先のデータベースにSQLを発行することができます。また、EOFは自動的にプライマリーキーを管理しますが、この機能を利用するには「Create Primary Key Support」のチェックも入れておく必要があります。OpenBaseの場合データベースに”EO_PK_TABLE”という名前のテーブルが作成され、このテーブルで他のテーブルのプライマリーキーの管理がおこなわれます。
     モデルを変更し、テーブルの再作成が必要になった場合は、「Drop Table」にもチェックをいれておくことで、テーブルの削除と作成を同時におこなうことができますが、この場合当然古いテーブル上に保存してあったデータは削除されてしまいますので注意が必要です。
     あと注意しなければならないこととしては、データベースのチューニングがあります。EOModelerから自動的に作成したテーブルをそのまま利用しますと、データ件数によってはパフォーマンス上問題があるかもしれません。そのためインデックスの作成などは別途対応する必要が出てきます。データベースに関しては、その他にもテスト用のデータをどのように用意するかや、データベースのバックアップをどうするのかなど、検討しなければならないことは色々とあります。

     さて、これでデータベースとモデル(フレームワーク)の基本的な説明が終わりましたので、今後必要になってくる作業の概要を簡単にまとめておきたいと思います。

    ・プロジェクトの作成
     まずはアプリケーション本体のプロジェクトを作成しましょう。アプリケーションを開発するさいには、前回説明しましたフレームワークを利用するような場合もあるでしょうし、なんらかのライブラリを利用する場合もあるでしょう。フレームワークやライブラリはプロジェクトに登録して利用しますが、開発環境と運用環境でそれぞれ管理をおこなう必要があります。

    ・Webページの作成
     動的に生成するWebページのテンプレートを作成します。標準で付属するツール「WebObjects Builder」を用いてテンプレートを作成します。WebObjectsでは再利用可能なコンポーネントを作成することもできますので、複数のページで共通するような部品(メニューなど)は積極的に共通化しておくことで開発効率を高めることができます。

    ・カスタムEOの作成
     EOFにより、強力なデータベースアクセス機能を利用することができますが、実際にアプリケーションを作成するとなると、アプリケーション固有の機能を追加する必要が出てきます。例えば、データの初期化をおこなったり、ユーザが入力したデータの正当性を検証したりする必要があります。こういった処理を実現するための機能として、EOModelerにはクラスファイルを自動生成する機能があります。この機能を利用しますと各Entityのデータを操作するためのクラスファイルが自動生成されますので、そのクラスを利用して、データの初期化や正当性の検証処理など独自の処理を組み込んでいくことができます。

     他にもテストなど、開発に関する様々な作業がありますが、まずは主な作業の概要をまとめてみました。これらはけっして順番にやっていかなければならないというものではなく、WebObjectsの開発効率のよさを利用して必要な部分から少しずつ動作を確認しながら着手していくことがポイントになります。

    小池邦人のCarbon API 徒然草(2005/07/29)

    ドラッグ&ドロップの活用(その7)

    今回は、前回のファイル複製処理の続きです。startMyDrag()ルーチンの中で登録しているsendDataMyDrag()ルーチンについて詳しく解説します。ドラッグアイテムとして追加されたPromiseHFSFlavor構造体やその他の情報は、このルーチンの中で解析されてファイル複製のために用いられます。

    以下が、「ドラッグ&ドロップの活用(その4)」で解説したstartMyDrag()ルーチンです。ここで再掲載しておきます。実際にファイルの複製を行うsendDataMyDrag()ルーチンは、SetDragSendProc()でシステムに登録しておきます。これにより、sendDataMyDrag()は、ドラッグ開始時ではなくドラッグ終了時(ドロップ時)に、Drag Managerにより呼び出されます。最初に、startMyDrag()の処理内容について、もう少し追加の解説をしておきます。

    short startMyDrag( WindowRef window,ControlRef chd,EventRecord *event )
    {
        short                    chk1,chk2,ret=eventNotHandledErr;
        RgnHandle                rgn1,rgn2;
        GWorldPtr                gptr=NULL;
        DragReference            dref;
        DragSendDataUPP          fptr;
        DragAttributes           att;
        StandardDropLocation     loc;
    
        if( WaitMouseMoved( event->where ) )  // マウスが範囲外へ動くまで待つ
        {
            if( NewDrag( &dref ) ) // 新規のDragReferenceを得る(セッション開始)
                return( 1 );
    
            if( createDataMyDrag( window,chd,dref ) ) // ドラッグ用データを設定する
            {
                DisposeMyDrag( dref );
                return( 1 );
            }
            chk1=chk2=1;
            if( rgn1=NewRgn() )
                chk1=createRegionMyDrag( window,chd,rgn1 ); // ドロップ枠を作成
            if( rgn2=NewRgn() )
                chk2=createImageMyDrag( window,chd,dref,rgn2,&gptr );
                                                            // 半透明画像を作成
            if( chk1==noErr && chk2==noErr )
            {
                fptr=NewDragSendDataUPP( (DragSendDataProcPtr)sendDataMyDrag );
                ret=SetDragSendProc( dref,fptr,0 ) );
                                        // データ受け渡し用のコールバックUPPを実装
                if( ret==noErr )
                    TrackDrag( dref,event,rgn1 );   // ドラッグ&ドロップの開始
                DisposeDragSendDataUPP( fptr );     // コールバックUPPを削除
                if( ret==noErr )
                {
                    GetDragAttributes( dref,&att ); // ドラッグアトリビュートを得る
                    if( (att&kDragInsideSenderApplication)==0 )
                                                    // 別アプリへドロップされたか?
                    {
                        if( ! GetStandardDropLocation( dref,&loc ) )
                        {
                            if( loc==kDragStandardDropLocationTrash )
                                deleteDataMyDrag( window,chd );
                        }   // オブジェクトがゴミ箱へドロップされた場合の処理
                    }
                }
            }
            if( rgn1 )
                DisposeRgn( rgn1 );     // ドロップ枠用のRegionを削除
            if( rgn2 )
                DisposeRgn( rgn2 );     // ドロップ画像用のRegionを削除
            if( gptr )
                DisposeGWorld( gptr );  // ドロップ画像用のGworldを削除
            DisposeDrag( dref );
        }
        return( ret );
    }
    


    GetDragAttributes()で得られたアトリビュート値を調べることで、自分自身のウィンドウ上へのドロップか、別アプリケーションのウィンドウ上へのドロップかを区別することができます。また、もしドラッグアイテムのドロップ先が「Dock」のゴミ箱の中であれば(Mac OS 9ならデスクトップ上のゴミ箱)、GetStandardDropLocation()により返されたStandardDropLocationがkDragStandardDropLocationTrashとなります。よって、もし必要であれば、ドロップしたデータ(ファイルやPICT画像)を削除する処理を追加しておくことも可能です。ここでは、自作のdeleteDataMyDrag()ルーチンがその役割を担っていますが、処理内容はケースバイケースですので、詳細な解説は省略しておきます。

    以下が、ドロップ時にファイルの複製を行うsendDataMyDrag()ルーチンです。まずは、GetFlavorData()でドラッグアイテムとして、PromiseHFSFlavor構造体が送られて来ているかどうかを調べます。もし送られて来ていれば、同様にGetFlavorData()を使い、複製元ファイルのFSSpec構造体(タイプは’fsc ‘)と複製先ファイル名のパスカル文字列(タイプは’str ‘)を得ます。そして、getDropDirectory()ルーチンを使うことで、ドロップ先のフォルダ(ディレクトリ)のFSSpec構造体を得ます。

    pascal short sendDataMyDrag( FlavorType type,long *refcon,ItemReference item,
                                                               DragReference dref )
    {
        FSSpec              fsc0,fsc1,fsc2;
        short               ret=noErr;
        Str255              name;
        long                size;
        PromiseHFSFlavor    ff1;
    
        size=sizeof(PromiseHFSFlavor);
        if( ! GetFlavorData( dref,item,flavorTypePromiseHFS,&ff1,&size,0 ) )
        {                             // PromiseHFSFlavor構造体を受け取る
            if( size==sizeof( PromiseHFSFlavor ) && type==ff1.promisedFlavor )
            {                        // PromiseHFSFlavor構造体かどうかを厳密に確認
                size=sizeof( FSSpec );
                if( ! GetFlavorData( dref,item,'fsc ',&fsc0,&size,0 ) )
                {                   // 複製元ファイルのFSSpec構造体を得る
                    size=sizeof( Str255 );
                    if( ! GetFlavorData( dref,item,'str ',&name,&size,0 ) )
                    {               // 名称変更用のパスカル文字列を得る
                        if( ! getDropDirectory( dref,&fsc1 ) )
                        {           // ドロップ先のフォルダのFSSpecを得る
                            getFolderFSSpec( &fsc1,&fsc2 ); // 複製先DirIDを得る
                            copyString( name,fsc2.name );   // 複製先FSSpecを作成
                            FSpDelete( &fsc2 );             // 重ね書きを行う
                            duplicateFile( &fsc0,&fsc2 );   // ファイルの複製
                            ret=SetDragItemFlavorData( dref,item,ff1.promisedFlavor,
                                                      (Ptr)&fsc2,sizeof(FSSpec),0 );
                                    // Finderにアイコン表示位置を調整させる
                        }
                    }
                }
            }
        }
        return( ret );
    }
    


    以下が、ドロップ先のフォルダ(ディレクトリ)のFSSpecを返すgetDropDirectory()ルーチンです。そのFSSpecをgetFolderFSSpec()ルーチンに渡すことで、そのフォルダ自身のDirIDを得て、そこに新規のファイル名を組み合わせることで、複製先ファイルの完全なFSSpec構造体を作成しています。それを自作のduplicateFile()ルーチンに渡して、ファイルの複製を実行します。

    OSErr getDropDirectory( DragReference dragRef,FSSpecPtr fssOut )
    {
        AEDesc    dropLocAlias={ typeNull, nil };
        AEDesc    dropLocFSS={ typeNull, nil };
        OSErr     err1,err=noErr;
        FSSpecPtr fss;
    
        if( ! ( err=GetDropLocation( dragRef,&dropLocAlias ) ) )
        {                                                // ドロップされた場所を得る
            if( dropLocAlias.descriptorType!=typeAlias ) // Aliasタイプか?
                err=paramErr;
            else
            {
                if( ! ( err=AECoerceDesc( &dropLocAlias,typeFSS,&dropLocFSS ) ) )
                {                                       // FSSpec構造体へ変換
                    fss=(FSSpecPtr) *(dropLocFSS.dataHandle );
                    BlockMoveData( fss,fssOut,minimumBytesForFSSpec(fss) );
                                                       // 得られたFSSpecを引数で返す
                    err=AEDisposeDesc( &dropLocFSS );  // FSSpec用のAEDescを削除
                }
            }
            if( dropLocAlias.dataHandle )              // Handleは確保されているか?
            {
                err1=AEDisposeDesc( &dropLocAlias );   // Alias用のAEDescを削除
                if( ! err )
                    err=err1;
            }
        }
        return( err );
    }
    
    short getFolderFSSpec(FSSpec *sfsc, FSSpec *dfsc)
    {
        CInfoPBRec   crec;
        short        ret;
    
        crec.hFileInfo.ioCompletion=0L;
        crec.hFileInfo.ioNamePtr=(StringPtr)sfsc->name;
        crec.hFileInfo.ioVRefNum=sfsc->vRefNum;
        crec.hFileInfo.ioFDirIndex=0;
        crec.dirInfo.ioDrDirID=sfsc->parID;
        ret=PBGetCatInfo( &crec,0 );        // 指定フォルダのカタログ情報を得る
        if( ! ret && ( crec.hFileInfo.ioFlAttrib&0x10 ) )  // フォルダである
        {
            *dfsc=*sfsc;
            dfsc->parID=crec.dirInfo.ioDrDirID; //そのフォルダ自身のDirIDを得る
        }
        return( ret );
    }
    


    それでは、処理の最後のSetDragItemFlavorData()は、いったい何をしているのでしょうか? 実はこの処理を追加することで、複製が完了したファイルのFSSpecをFinderに教えることができます。結果として、Finderは複製済みのファイルのアイコンをドロップした位置にちゃんと移動して表示してくれます。この処理を行わないと、複製されたファイルはウィンドウ上のドロップされた位置ではなく、ディフォルト位置に表示されてしまいます。
    sendDataMyDrag()の最後の1ラインを削除すると、ドロップ終了後のアイコン表示がどうなるのかを、ぜひ試してみてください。

    次回は、いよいよ「ドラッグ&ドロップの活用」の最終回です。ドラッグを実行中にテンポラリ表示される半透明の画像の作成と登録方法を解説します。例えばQuickTime PlayerからMovieをドラッグすると、ドラッグ中に小ぶりの半透明画像が表示されますが、そうした画像の作り方を紹介します。

    つづく

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

     本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、簡易ファイラであるファイル・リストに備え付けのテキストエディタ機能についてです。

     ファイル・リストは、Finderなどの一般的なファイラが持つディレクトリ・ブラウザ機能の他に、テキストエディタの機能を備えています。下の大きめのペインはそのためのもので、選択したファイルの内容は即座にこのペインに表示されます。選択したファイルがテキストファイルなら、その内容の確認はもちろん、編集して保存することも可能です。編集後の内容を保存するには、下のペインの黄ボタンメニューから「了解」(英語メニューではaccept)を選択します。キーボードショートカットはcmd-Sです。

     Macのアプリと違い、ファイル・リストは保存の際、常に重ね書きの確認をとりにきます。重ね書きでよいときは、ポップアップから「overwrite that file」を選びます。名前を変えて保存したいときは「choose another name」のほうを選びます。改めて、a FillInTheBlank(入力欄オブジェクト)を使って保存先を訊ねてくるので、そこで適当なファイル名を入力して「了解」します。

    [fig.A]重ね書きの確認ポップアップ
    http://squab.no-ip.com:8080/mosaren/uploads/44a.png

     なお、ポップアップの「cancel」やファイル名入力欄の「取消」を選んだとき、エラー(ノーティファイア)が表示されますがこれは無視して(閉じてしまって)構いません。

     大きなファイルは、とりあえず最初の5000バイトだけが表示されます。下のペインの黄ボタンメニューから「get entire file」を選択することで、強制的に全体を読み込むことが可能です。ただ、ファイル・リストのテキストエディタ機能はあまり凝ったしくみにはなっていません。むやみに巨大なファイルを読み込もうとすると、なにかと支障をきたすことがあるので注意してください。もっとも、このファイル・リストに限らず、Squeakシステム自体、大きなサイズの情報を扱うことは苦手なのですが…。

     開こうとするファイルがテキストではなくバイナリ形式の場合は、ちょうど、Macでテキストエディタを使ってバイナリファイルを強制的に開いたときと同じ状態になります。その内容は意味をなしませんが、黄ボタンメニューから「view as hex」を選んで表示モードを十六進表記に切り替えることで、ある程度の対応は可能です。ただ、モード切り換え後は編集結果を保存できないなどの制約がありますから、あくまでオマケ的な機能だと割り切ったほうがよいでしょう。

     ファイル・リストは、上のペインにあるディレクトリブラウザの機能を切り離して、下のペインだけ、つまりテキストエディタとしてのみ機能させることも可能です。じつは、これまで何度か出てきた

    (FileList fileNamed: ‘test.txt’) edit

    という式は、test.txtというファイルを、このテキストエディタ“モード”のファイル・リストで開くためのものでした。ファイルストリームへのeditの送信によって起動するメソッドの定義は次のようになっています。

    FileStream >> edit
       FileList openEditorOn: self editString: nil.

     これと同じことは、デスクトップメニューの「開く…」→「ファイル…」でポップアップからファイル名でファイルを選んで開く作業でもできます。

     テキストエディタモードで動くファイル・リストのウインドウの見た目は、ワークスペースのそれにたいへんよく似ています。これは、両者がまったく同じクラスに属するGUIオブジェクト(ウインドウ、テキスト編集枠)により構成されているためで、まあ当然といえばそれまでです。ただ、それぞれの“中核”にある(つまりMVCでいうところの「モデル」として働く)オブジェクトが別物であるため、その振る舞いには違いが生じるカラクリになっています。目に付きやすい所では、たとえば、両者では黄ボタンメニューの内容が異なります。

    [fig.B]同じGUIオブジェクトでもモデルが違えば振る舞いも違ってくる
    http://squab.no-ip.com:8080/mosaren/uploads/44b.png

     さて。最後に、もともとの話題であった日本語ファイルについて。残念ながらNihongo7では、日本語ファイルのファイル・リストでの扱いにはちょっとした問題があります。普通に開いただけでは、ファイルの内容が文字化けしてしまうのです。たとえば、第42回で作ったシフトJISのファイル「ShiftJisExample.txt」(もしくは、Macのテキストエディタで作成した適当な日本語テキストファイル)を「開く…」→「ファイル…」や次の式で開こうとしても文字化けしてしまい、その内容は正しく表示されません。

    (FileStream fileNamed: ‘ShiftJisExample.txt’) edit

     Nihongo6まではきちんと表示されていたのですが、多言語化機構の公式英語版への取り込みに際して行なわれた仕様見直しの影響で、ファイル・リストの表示には常にa Latin1TextConverterが使われるようになってしまったのがこの文字化けの原因です。黄ボタンメニューの表示モードの切り換え「view as encoded text」で適切な文字コードを選択することで、とりあえずこの問題は回避できます。

    [fig.C]文字コードの切り換え
    http://squab.no-ip.com:8080/mosaren/uploads/44c.png

     ただ、ファイルを開くたび、文字コードをいちいち切り換えるのは面倒ですし、十六進表示モードへの切り換え時同様、編集後の保存ができないなど、使い勝手の面での不満も残ります。そこで次回は、.txtまたは.textという拡張子のファイルを開いたときだけは、デフォルトのa Latin1TextConverterの代わりにa ShiftJISTextConverterを使用してくれるように、ファイル・リストの機能をちょっとだけいじってみることにします。

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

    ニュース・解説

    今週の解説担当:木下 誠

    ———————————————————————-
    CodeWarrior 10が秋に登場、
    PowerPlantおよびPowerPlant Xがオープンソース化
    ———————————————————————-

    ADHOC (The Advanced Developers Hands On Conference)にて、Metrowerksのセッション「Bash Metrowerks」が行われ、その中でCodeWarrior 10の登場、PowerPlant、PowerPlant X、Constructorのオープンソース化が発表されたそうです。

    セッションに参加された方のノートによると、

    ・CodeWarrior 10は、秋に登場。ターゲットはMac OS X 10.2
    ・Intelチップ用のコンパイルは行なわれない。PowerPlantは、Intelホスト上では、少しの作業で動く
    ・PowerPlant、PowerPlant X、Constructorはオープンソース化、IDEはオープンソース化されない
    ・CodeWarrior 10でおそらく最後、サポートは今年の終わりまで
    ・x86関連は、Nokiaが買収

    などが明らかになったそうです。

    事実上、CodeWarriorは終焉、Intel対応は行われない、ということになりました。ただし、PowerPlantとPowerPlant Xがオープンソース化されるので、有志によるIntel対応の道が開けた、と言えるでしょう。

    The Advanced Developers Hands On Conference
    http://www.adhocconference.com/
    Driss-A-Blog: The CodeWarrior roadmap
    http://www.drissman.com/blog/archives/2005/07/29/the_codewarrior_roadmap.html

    ———————————————————————-
    Core Dataプログラミングガイド日本語訳
    ———————————————————————-

    アップルジャパンのサイトに、Core Dataプログラミングガイドの日本語訳が登場していました。Tigerから搭載されている、Cocoaのモデルレイヤーを受け持つCore Dataですが、データベースを由来とする技術なので、そちらの分野で使われる用語が多く見られます。日本語訳の登場は、理解の助けになるでしょう。

    ここ数ヶ月、アップルジャパンはいままでとは比べ物にならない勢いで、ドキュメントの日本語訳を公開しています。まだまだごくわずかなドキュメントしか翻訳されていませんが、この傾向が維持されることを期待したいところです。

    Core Dataプログラミングガイド
    http://developer.apple.com/ja/documentation/cocoa/Conceptual/CoreData/index.html

    ———————————————————————-
    Xsan 1.1への移行ガイド
    ———————————————————————-

    6月に発表されたXsan 1.1への、移行ガイド「Xsan Migration Guide」が公開されました。Xsan 1.0から1.1への移行の説明になります。

    PantherおよびTiger上でXsanを動作させている場合の、移行手順が説明されています。

    Xsan Migraion Guide
    http://images.apple.com/server/pdfs/20050725_Xsan_Migration_Guide.pdf

    ———————————————————————-
    Comic Lifeの開発チームの紹介
    ———————————————————————-

    最近、ADCで中小のソフトウェアベンダーがよく紹介されていますが、今回はComic Lifeを開発したplasqが紹介されています(plasq Shows What a Small Team Can Do: Comic Life Is Media-Rich and Fun to Use)。Comic Lifeは、今年のWWDCでApple Design Awardを受賞した、グラフィックソフトです。

    記事では、plasqがCocoa、Core Image、.Mac、iPhotoといった技術を使って、小さいチームでアプリケーションを作り上げた事例が紹介されています。

    plasq Shows What a Small Team Can Do: Comic Life Is Media-Rich and Fun to Use
    http://developer.apple.com/business/macmarket/plasq.html

    ———————————————————————-
    サンプル、Technical NoteのUniversal Binary化続く
    ———————————————————————-

    7月の初めから、ADCのサンプルが多数更改され続けています。この多くは、Universal Binary化を行うためのものです。今週も、この更改が多く行われました。

    また、QuickTimeコンポーネントの作成を解説したTechnical Note、「TN2012: Building QuickTime Components for Mac OS X」も更新されました。これも、Universal Binaryに対応するためのものです。

    TN2012: Building QuickTime Components for Mac OS X
    http://developer.apple.com/technotes/tn/tn2012.html

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

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