MOSA Multi-OS Software Artists

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

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

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

2005-12-06

目次

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

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

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

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

Application.java

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

     public Application() {
         super();
         System.out.println("Welcome to " + this.name() + "!");

         /* ** Put your application initialization code here ** */
          // Encoding
          WOMessage.setDefaultEncoding("UTF-8");

         // Request Handler
         setDefaultRequestHandler(
             requestHandlerForKey(directActionRequestHandlerKey()));
     }


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

Welcome to MOSAJobMatch!

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

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

WOMessage.setDefaultEncoding(“UTF-8″);

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

WOMessage.defaultURLEncoding();

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

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

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

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

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

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

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

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

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


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

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

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

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

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

short setupViwerWindow( WindowRef window,CGImageRef image )
{
    HIViewRef    iview,sview,cview;
    short        ret=1;
    HISize       hmax;          // ウィンドウサイズの制限を代入するのに用いる
    Rect         drt;
    HIRect       vrt;

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


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

void setupViwerWindowEvent( WindowRef window )
{
    EventTypeSpec    list[]={
                              { kEventClassCommand,kEventCommandUpdateStatus },
                              // メニューのアップデートを確認
                              { kEventClassWindow, kEventWindowClose }
                              // ウィンドウのクローズボタン(閉じる)に対応
                            };

    InstallWindowEventHandler( window,myViwerWindowEventHandler,
                                   GetEventTypeCount(list),list,window,NULL );
                // 2種類のCarbon Eventに対応するCarbon Event Handlerを実装する
}

pascal OSStatus myViwerWindowEventHandler( EventHandlerCallRef myHandler,
                                                EventRef event,void *userData )
{
    short            ret=eventNotHandledErr;
    WindowRef        wptr=NULL;
    unsigned long    ekind;
    short            part;
    long             cls;
    HICommand        cmd;
    Point            pt;

    cls=GetEventClass( event );  // イベントクラスを得る
    ekind=GetEventKind(event);    // イベントの種類を得る
    if( cls==kEventClassCommand ) // イベントクラスがkEventClassCommandの場合
    {
        switch( ekind )
        {
            case kEventCommandUpdateStatus: // メニューのアップデートを確認

                GetEventParameter( event,kEventParamDirectObject,typeHICommand,
                                            NULL,sizeof(HICommand),NULL,&cmd );
                                            // 選択されたメニューの情報を得る
                ret=mainteViewerWindowMenu( wptr,cmd.menu.menuRef );
                                            // メニューメンテナンス自作ルーチン
                break;
        }
    }
    else if( cls==kEventClassWindow ) // イベントクラスがkEventClassWindowの場合
    {
        GetEventParameter( event,kEventParamDirectObject,typeWindowRef,NULL,
                                                sizeof(WindowRef),NULL,&wptr );
                                      // 対象となるウィンドウのWindowRefを得る
        switch( ekind )
        {
            case kEventWindowClose: // ウィンドウのクローズボタンに対応

                disposeMyWindow( wptr ); // ウィンドウを破棄する自作ルーチン
                ret=noErr;
                break;
        }
    }
    return( ret );
}


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

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

つづく

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ニュース・解説

今週の解説担当:木下 誠

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

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

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

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

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

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

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

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

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

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

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

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