プログラム講座 初級編16

- ピクチャーフィールドを使おう -

 初級編16です。今回は「ピクチャーフィールドを使おう」について説明します。ピクチャーフィールドはFuture BASICの機能の中でも非常に便利なものです。このピクチャーフィールドを有効に利用することで、見栄えの良いアプリケーションを手軽に作成する事が可能になります。




ピクチャーフィールドとエディットフィールド
 ピクチャーフィールドと同様のものにエディットフィールドがあります。これらは、表示するものが「画像かテキストか」だけの違いで枠指定などは、どちらも似たような感じで指定する事ができます。
 ピクチャーフィールドはPICT画像を表示させることができます。PICTファイル画像や加工した画像の表示、リソースであっても表示させることができます。おまけに、アップデートイベント(書き換え)も自動的に処理されますので、非常に楽に画像を表示させることが可能です。
 非常に便利なピクチャーフィールドですが、1つだけ注意事項があります。それはID番号は「他のピクチャーフィールドおよびエディットフィールド」と同じであってはならない、という点です。これをのぞけば極楽でしょうf(^^;



ピクチャーフィールドの指定方法
 ピクチャーフィールドの指定方法は以下のようになっています。

PICTURE FIELD #ID,PICT,RECT,TYPE,JUST

  • #ID
     フィールド番号を指定します。他のエディットフィールド、ピクチャーフィールドと異なる番号にしてください。範囲はマニュアルには書かれていませんが-2147483647〜2147483647までです。負数を指定してもピクチャーフィールドは表示されます。

  • PICT
     PICT画像を表示します。"リソース名"とすると指定された名前のPICTリソースを表示します。%pictResID%とすると指定された番号のPICTリソースを表示します。&pictHandle&とすると指定されたPICT画像を表示します。この場合、画像のハンドルを指定します。表示する画像のハンドルはピクチャーフィールドで使用している間は絶対に破棄しないでください。

  • RECT
     ピクチャーフィールドの表示範囲を指定します。ピクチャーフィールドの指定範囲であって表示する画像の表示範囲ではありませんので注意して下さい。表示する画像と同じサイズにするには、あらかじめPICT画像の大きさを読み込んでおく必要があります。

  • TYPE
     ピクチャーフィールドの枠表示等を指定します。以下のものが設定できます。


     上記の指定方法に加えて以下の属性も指定できます。

    _framedNoCR枠付き、クリック時の反転なし
    _framed枠付きクリック反転あり
    _noFramedNoCR枠なしクリック反転なし
    _noFramed枠なしクリック反転あり
    _statNoFramed枠なし固定画像
    _statFramed灰色の画像、枠付き固定
    _statNoFramedGray灰色の画像、枠なし固定
    _statFramedInv反転画像枠付き
    _statNoFramedInv反転画像枠なし
    _statKeepBg固定フィールドで背景を消さない
    _noOutlineアウトラインなし
    _stat2Norm固定標準
    _stat2Gray固定灰色
    _stat2Inv固定反転
    _hilite表示色で強調
    _round円形枠
    _rounder角丸四角形(やや角丸)
    _roundest角丸四角形
    _boldBox強調枠

  • JUST
     ピクチャーフィールドの表示位置を指定します。以下のものが設定できます。

    _scaledPict画像をフィールドのサイズに合わせる
    _centerPict画像サイズは変更せずフィールド中央に配置
    _cropPict画像サイズは変更せずに左上に配置。表示しきれない部分は切り捨て

     今回はピクチャーフィールドは画像サイズに一致させますので、以下のように指定してあります。

    PICTURE FIELD #1,&pictHandle&,(0,0)-(gWinLX,gWinLY),_noFramedNoCR

     フィールド番号1に読み込んだPICT画像ハンドルを指定、画像サイズに合わせてピクチャーフィールドを設定という意味になります。



    PICT画像の横幅、縦幅を求める
     ピクチャーフィールドを画像のサイズに合わせるには、読み込んだPICTファイルの中から取り出さなければなりません。画像のサイズを求める部分は幸いにしてマニュアルに記載されていますので、そのまま流用させてもらいましょう。以下が横幅、縦幅を求めるプログラムです。

    rect;8 = [pictHandle&]+_picFrame: ' "PICTの画像の矩形を取り出す"
    gWinLX = rect.right - rect.left: ' "右側の座標を取り出す"
    gWinLY = rect.bottom - rect.top: ' "下側の座標を取り出す"

     画像のサイズは矩形で記録されており、特定の場所にあります。この場所を指定する場合は定数として_picFrameを使用します。直接数値で指定する事も可能ですが(定数ウィンドウで調べることが出来ます)、定数で指定しておくのが良いでしょう。というのは将来サイズが格納されている場所が変更された場合を考えてみましょう。直接数値で指定した場合、指定した部分を全て直さなければなりません。これが定数で指定してあれば何の変更もなく、ただコンパイル(ビルド...)するだけです。手間を考えれば定数で指定しておく方が楽だというのがわかるでしょう。



    PICTハンドルを指定する
     読み込んだPICT画像をピクチャーフィールドに表示できるようにしましょう。これはピクチャーフィールドを設定する時にPICT画像ハンドル(今回のプログラムではpictHandle&という名前です)を指定するだけです。
     あとは何もしなくても、できあがりです。アップデートイベント云々やオフスクリーン云々という面倒な部分は何もありません。



    終わりに
     ピクチャーフィールドを使えば、アプリケーションのツールバーやメニューパレットを簡単に実現する事ができます。クリックしたかどうかも検知できますので、ピクチャーフィールドを配置してやれば、あとはどれが押されたのかを調べるだけです。
     次回はアプリケーションソフトで、よく見られる「ツールパレット」を実現してみましょう。



    今回のプログラムリスト
    '------------------------------------------------------------- ' "PICTファイルをオープンしてウィンドウに描画する" '------------------------------------------------------------- '-------------------- グローバル変数の定義 ------------------- gWinLX = 320 gWinLY = 240 gQuitFlag = _false: '"終了フラグ" filename$ = "": ' "ファイル名" pictHandle& = 0 END GLOBALS '------------------------------------------------------------- ' "PICTファイルをオープンしてハンドルを返す" ' "ハンドルの戻り値が0の場合は読み込めなかったかキャンセルされた" '------------------------------------------------------------- LOCAL FN openPictFile DIM rect;8: ' "矩形座標は8バイト必要" pictHandle& = 0: ' "ハンドルの値を0に設定" filename$ = FILES$(_fOpen,"PICT",,vRefNum%): ' "ファイルオープンダイアログでファイルを選択" LONG IF filename$<>"": ' "空文字の時はキャンセルボタンが押された時です" OPEN "I",#1, filename$,,vRefNum%: ' "ファイルを開く" fileSize& = LOF(1,1): ' "ファイル番号1の(オープンされた)ファイルサイズを求める" pictHandle& = FN NEWHANDLE(fileSize&): ' "ファイルサイズ分メモリを確保します" LONG IF pictHandle&: ' "0以外だったらメモリ確保できた!" err = FN HLOCK(pictHandle&): ' "ハンドルをロックしてメモリが動かないようにします" LONG IF err = 0 READ FILE#1, [pictHandle&], fileSize&: ' "一気にファイルからメモリに読み込みます" BLOCKMOVE [pictHandle&]+512,[pictHandle&],fileSize& - 512:' "先頭512バイトは予約領域なので削除します" err = FN HUNLOCK(pictHandle&): ' "ハンドルロックを解除して512バイトハンドルサイズを小さくします" err = FN SETHANDLESIZE(pictHandle&, fileSize&-512) err = FN HLOCK(pictHandle&): ' "再度ハンドルをロックして画像サイズを読み出します" rect;8 = [pictHandle&]+_picFrame: ' "PICTの画像の矩形を取り出す" gWinLX = rect.right - rect.left: ' "右側の座標を取り出す" gWinLY = rect.bottom - rect.top: ' "下側の座標を取り出す" err = FN HUNLOCK(pictHandle&) END IF END IF CLOSE #1: ' "オープンしたファイルを閉じます" END IF END FN '------------------------------------------------------------- ' "新しくウィンドウを開く" '------------------------------------------------------------- LOCAL FN newWin IF pictHandle& THEN err = FN DISPOSHANDLE(pictHandle&):' "PICTハンドルを破棄" FN openPictFile: ' "PICT画像を読み込む" LONG IF pictHandle& WINDOW CLOSE #1 WINDOW #1,filename$,(0,0)-(gWinLX,gWinLY),_dialogMovable:' "ウィンドウを開きます" PICTURE FIELD #1,&pictHandle&,(0,0)-(gWinLX,gWinLY),_noFramedNoCR:' "枠なしのピクチャーフィールドを設定します" END IF END FN '------------------------------------------------------------- ' "メニュー構築" '------------------------------------------------------------- LOCAL FN initMenu MENU 1,0,_enable,"ファイル" MENU 1,1,_enable,"/O開く..." MENU 1,2,_enable,";" MENU 1,3,_enable,"/Q終 了" END FN '------------------------------------------------------------- ' "メニュー分岐処理" '------------------------------------------------------------- LOCAL FN doMenu menuID = MENU(_menuID): ' "どのメニューバー項目かな?" itemID = MENU(_itemID): ' "選択項目は何かな? IF menuID = 1 AND itemID = 1 THEN FN newWin IF menuID = 1 AND itemID = 3 THEN gQuitFlag = _true:' "終了フラグ" MENU: ' "メニューのハイライトを元に戻します" END FN '------------------------------------------------------------- ' "メインルーチン" '------------------------------------------------------------- ON MENU FN doMenu: ' "メニューイベントの処理先" FN initMenu: ' "メニュー初期化" WINDOW OFF DO HANDLEEVENTS: ' "メインイベントループ処理" UNTIL gQuitFlag END