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