メニューの作り方(ShowMenuの仕様) (last-mod: 2010-12-17)

メニューを生成、表示、選択アイテムの実行を行なうメソッドにはShowMenuとShowMenu2があります。
ShowMenu2はキーフォーカスを奪わない擬似メニューを表示する以外はShowMenuと同じです。

戻り値

実行されたメニューアイテムの戻り値を返します。ESC, ALT等でキャンセルされた場合、Nilを返します。

引数

メニューを表示する座標x, yが初めの二つの引数になり、その後はキャプションとして表示される文字列とそのメニューアイテムが選択決定されたときに実行されるブロックが交互に置かれます。キャプション内の&に続く文字がキーアクセラレータになること、TAB以降が右寄せになることなどは、Windowsの仕様です。座標に-1を指定した場合、キャレット(テキスト入力インジケータ?)の位置になります。

ShowMenu(0 0 'item&1' ['item1'] 'item&2' ['item2'])

特定のキャプション文字列によって、特殊な処理がなされます。
+で始まるキャプションと-に挟まれた引数はサブメニューを作ります。先頭の+を取り除いたものがサブメニューのキャプションになります。

ShowMenu(0 0
  'item&1' ['item1']
  '+&sub'
    'sub&1' ['sub1']
    'sub&2' ['sub2']
  '-'
  'item&2' ['item2'])

空文字列はセパレータになります。

ShowMenu(0 0
  'item&1' ['item1']
  ''
  'item&2' ['item2'])

?で始まるキャプションはグレー化されます。先頭の?を取り除いたものと同じように扱われます。

ShowMenu(0 0
  'item&1' ['item1']
  ''
  '?+&sub'
    'sub&1' ['sub1']
    'sub&2' ['sub2']
  '-'
  '?item&2' ['item2'])

!で始まるキャプションはチェックされます。先頭の!を取り除いたものと同じように扱われます。

ShowMenu(0 0
  'item&1' ['item1']
  ''
  '!+&sub'
    'sub&1' ['sub1']
    'sub&2' ['sub2']
  '-'
  '!item&2' ['item2'])

*で始まるキャプションは動的なサブメニューになります。ユーザがそのサブメニューを初めて開くときに続くブロックが実行され、その戻り値が引数の配列として解釈され、それにより作られたサブメニューが表示されます。先頭の*を取り除いたものがサブメニューのキャプションになります。

ShowMenu(0 0
  'item&1' ['item1']
  '*&sub' [
    {
      'sub&1' ['sub1']
      'sub&2' ['sub2']
    }
  ]
  'item&2' ['item2'])

@で始まるキャプションはアイコンの指定になります。(ShowMenu2のみで、ShowMenuでは無視される。)次に来るメニューアイテムが指定の対象になります。アイコン文字列の書式はGiraffe.Event.GetIconと同じです。

ShowMenu2(0 0
  '@C:\WINDOWS\system32\moricons.dll,0' 'item&1' ['item1']
  '@C:\WINDOWS\system32\moricons.dll,1' 'item&2' ['item2'])

\で始まるキャプションは普通のアイテムになります。ようするに、エスケープ文字です。

ShowMenu(0 0
  '\+item&1' ['item1']
  '\\item&2' ['item2'])

ScriptフォルダにあるGUID_menu.giraffeを利用して、メニューをキャレットの位置に出して動的に生成したGUIDをペーストするスクリプトを作ります。
GUID_menu.giraffeは、メニュー生成用の配列を返すだけでなく、そのメニューで使われるメソッドの定義もします。

ShowMenu(
  -1 -1
  include('GUID_menu').@ //.@による引数展開
).toss&
`Nil[ //キャンセル
].|
`str[
  set-cb(str)
  EmulatePasteKey
]

GUID_menu内でメソッドが定義されるため、@による呼び出しではなく、includeにしなければいけません。呼び出し側のコンテキストにメソッドを定義させるためです。
サブメニュー化したい場合は、

include('GUID_menu').@

を、

'*&GUID' [include('GUID_menu')]

とします。