プログラム講座 中級編24
- テロッパー -
 中級編24です。今回は「テロッパー」という事でウィンドウを表示して、そこに文字を流します。インターネット上からデータを引っ張ってきてニュースや天気予報でも流せば実用的かもしれませんが、ここでは単純に文字を流してみます。文字だけでなく時刻もリアルタイムに変更して流すことにします。
◆Toolboxでの文字の表示
 Future BASICで文字を表示する場合PRINT命令を使います。このプログラムではPRINTは使用せずにToolboxを使って文字を表示しています。Toolboxを使って文字を表示するには次の命令を使います。
CALL DRAWSTRING(文字列)
 文字列の所には直接文字を指定しても良いですし、文字列変数で指定しても大丈夫です。つまり、「私の誕生日は2月15日」という文字を表示させる場合、以下に示す2つの方法のどちらでもOKです。
- (1)
 - CALL DRAWSTRING("私の誕生日は2月15日")
 - (2)
 - A$ = "私の誕生日は2月15日"
- CALL DRAWSTRING(A$)
 
 
 DRAWSTRINGの場合PRINT命令と違って自動的にウィンドウの右まで表示したら左に表示するような事はしません。単純に文字を表示するだけです。表示する位置もPRINT命令では指定できますが、DRAWSTRINGは現在のペンの位置から表示します。ペンの位置は線を引いたり座標を移動させたり、長方形を書いた最後の座標になります。DRAWSTRINGを使って文字を表示する場合、あらかじめ表示するペンの位置(座標)を指定しておかなければなりません。ペンの位置を指定するには次の命令を使います。
CALL MOVETO(X座標,Y座標)
 これであらかじめ表示する座標を指定します。ウィンドウの表示部分の左上が(0,0)で右下にいくに従って増加していきます。
文字を移動させるには、この表示座標をずらしていきます。座標をずらしていき、文字が流れ終わったら、また右にX座標を設定します。
◆文字列の幅を求める
 Macで文字を表示すると等幅フォントでない限り文字幅が一定にはなりません。つまりプロポーショナルという事です。固定幅のフォントであれば、文字数×文字幅で文字列の横幅を求める事ができます。しかしプロポーショナルフォントでは、簡単に求めることはできません。文字によって文字幅が異なるためです。
 幸いToolboxには、指定した文字列の幅を求める関数が用意されています。文字列の幅を求めるには
文字列幅 = FN STRINGWIDTH(文字列)
のようにします。これで文字列の文字幅を求める事ができます。注意しなければいけないのは、現在設定されているフォントとフォントサイズによって結果が異なると言うことです。つまり使用前にフォントとサイズを指定しておく必要があります。
◆カーソルアニメーション
  ついでに10秒間ほどマウスボタンを押したり、ウィンドウを移動させたりするイベントが発生しない場合、カーソルの形を変更するようにします。カーソルの形状を変更するには、
CURSOR 形状番号
のようにします。通常の矢印カーソルやI (アイビーム)カーソルなどは、次のように指定するだけでカーソル形状が変化します。
CURSOR _arrowCursor	矢印カーソル
CURSOR _iBeamCursor	I (アイビーム)カーソル
CURSOR _watchCursor	時計カーソル
 他にも指定できるものもありますが、通常この3つで十分でしょう。今回はカーソルアニメーションという事であらかじめリソースエディタで、アニメーションするカーソルリソースを作成しておきます。カーソルリソースはCURSです。今回は128番から133番まで作成しました。AMIGAよろしくZZZとなりアニメーションします。
 リソースエディタでカーソル形状を作成したカーソルを設定表示するには
CURSOR カーソルリソース番号
のようにします。このカーソルリソース番号を128番から133番まで繰り返せばカーソルアニメーションができあがりです。
 Future BASICには非常に都合の良いことに、カーソルアニメーションのように128, 129, ..., 132, 133, 128, 129, ...のように繰り返す命令があります。それはDEF CYCLEという命令で以下のように指定します。
DEF CYCLE(最小値,最大値,変化させる変数)
これで自動的に変数の値が最小値から最大値まで変化し最大値を超えたら最小値に戻ります。
◆終わりに
 文字のテロップだけでなく、画像のテロップも可能です。画像を流すには、あらかじめPICTファイルかリソースを読み込んでおいて表示するようにします。画像を手軽に表示させるには、CALL DRAWPICTURE命令を使えばよいでしょう。
 次回も予告通りにいきそうもありませんf(^^; Future BASIC Toolsもあるんだけど、全然使っていないという(汗)。FAQも用意したいし、なかなか難儀です・・・
◆今回のプログラムリスト
RESOURCES "telop.res"
OUTPUT FILE "FutureTelopper"
'------------------------ "定数" ---------------------------
_msgOffset = 100:                                 ' "100ピクセル余白を用意する"
_fontSize = 24
_windowLX = 480:                                  ' "ウィンドウの横幅"
_windowLY = 36:                                   ' "ウィンドウの縦幅"
_gIdleMax = 600:                                  ' "10秒イベントがなかったらカーソル形状を変える(1 sec = 60 ticks)"
_cursorMin = 128:                                 ' "カーソルリソースの最初の値"
_cursorMax = 133:                                 ' "カーソルリソースの最後の値"
_cursorTime = 20:                                 ' "アニメーション間隔"
'-------------------- "グローバル変数" ----------------------
gQuit_flag = _false
gTelopMessage$ = "Program By KaZuhiro FuRuhata..."
gMsg$ = "":                                       ' "実際に表示するメッセージ"
gTelopLen% = 0:                                   ' "メッセージの横幅"
gX% = 0:                                          ' "X座標"
gY% = 0:                                          ' "Y座標"
gIdleTime% = 0:                                   ' "アイドリング時間"
gIdleFlag% = _false:                              ' "カーソル形状が変化しているかどうかのフラグ"
gCursorPat% = _cursorMin:                         ' "カーソルパターン"
END GLOBALS
'------------------------------------------------------
' "テロップメッセージをウィンドウに表示する"
'------------------------------------------------------
LOCAL FN displayMessage
  CALL MOVETO(gX%,gY%)
  CALL DRAWSTRING(gMsg$)
  gIdleTime% = gIdleTime% + 1
  ticks& = FN TICKCOUNT:                          ' "Tick数を求める"
  IF (ticks& MOD _cursorTime > 0) OR gIdleFlag% = _false THEN EXIT FN:' "アニメーションする時間でなければ関数処理終了"
  CURSOR gCursorPat%
  DEF CYCLE(_cursorMin,_cursorMax,gCursorPat%)
END FN
'------------------------------------------------------
' "テロップメッセージを左に移動させる"
'------------------------------------------------------
LOCAL FN moveTelop
  gX% = gX% - 1
  IF gX% < -gTelopLen% THEN gX% = _windowLX
  FN displayMessage
  gMsg$ = gTelopMessage$+"("+TIME$+")"
  gTelopLen% = FN STRINGWIDTH(gMsg$) + _msgOffset:' "メッセージの横幅を求める"
END FN
'------------------------------------------------------
' "アップデートイベントを処理"
'------------------------------------------------------
LOCAL FN eventProc
  evnt = DIALOG(0)
  IF evnt = _wndRefresh THEN FN displayMessage
  LONG IF evnt <> 0
    gIdleFlag% = _false
    CURSOR _arrowCursor
    gIdleTime% = 0
  END IF
END FN
'------------------------------------------------------
' "カーソル形状更新"
'------------------------------------------------------
LOCAL FN setCursor
  evnt = DIALOG(0)
  LONG IF evnt = 0
    IF gIdleTime% > _gIdleMax THEN gIdleFlag% = _zTrue
  XELSE
    gIdleTime% = 0
  END IF
END FN
'------------------------------------------------------
' "メニュー構築"
'------------------------------------------------------
LOCAL FN initMenu
  APPLE MENU "Future Telopper について..."
  
  ' "ファイルメニュー"
  MENU 1,0,_enable,"ファイル"
  MENU 1,1,_enable,"/Q終 了"
END FN
'------------------------------------------------------
' "Aboutの処理"
'------------------------------------------------------
LOCAL FN ABOUT
  err% = FN ALERT(128,0)
END FN
'------------------------------------------------------
' "メニュー分岐処理"
'------------------------------------------------------
LOCAL FN doMenu
  menuID = MENU(_menuID):                         ' "メニューバー項目を得る"
  itemID = MENU(_itemID):                         ' "選択項目番号を得る"
  
  SELECT menuID
    CASE 255,127
      SELECT itemID
        CASE 1
          FN ABOUT:                               ' "About...が選択されたので呼び出す"
      END SELECT
    CASE 1 :                                      ' "終了メニュー"
      SELECT itemID
        CASE 1:
          gQuit_flag = _zTrue
      END SELECT
  END SELECT
  MENU
END FN
' "初期化"
ON TIMER(-1) FN moveTelop
ON MENU FN doMenu
ON DIALOG FN eventProc
FN initMenu
WINDOW OFF
WINDOW #1,"Future Telopper",(4,42)-(4 + _windowLX,42 + _windowLY),_dialogMovable
TEXT _sysFont,_fontSize,_boldBit%+_italicBit%,_srcCopy
gMsg$ = gTelopMessage$+"("+TIME$+")"
gTelopLen% = FN STRINGWIDTH(gMsg$) + _msgOffset:  ' "メッセージの横幅を求める"
gX% = 0:                                          ' "X座標を0にする"
gY% = USR FONTHEIGHT - 4:                         ' "Y座標(フォントの高さを求める)"
' "メインルーチン"
DO
  HANDLEEVENTS
  FN setCursor
UNTIL gQuit_flag