! Phi::WinControl

すべての Window Control の基本クラス

!! super class

[[Phi::Control]]

!! properties

!!! ime_mode : Fixnum ([[Phi-ImeMode]])

!!! ime_name : String

!!! parent_ctl3d =

!!! showing : Boolean
本当に見えているかどうか。この control が見えていれば,その親は見えており,親の親も見えている。

!!! tab_order : Fixnum
tab order とは [Tab] を押したときに focus を受け取る順序のことだ。 form が最初に表示されたとき, tab_order が 0 の Control が focus を得る。特に指定しなくても tab_order は Component が form に追加された順に 0, 1, 2, ... となる。


各 Component は親の中で unique な tab order をひとつ持つ。これは,ある Component の tab_order を別の Component と同じ値に変更すると,残りのすべての Component の tab_order の値が変わることを意味する。
p a.tab_order #==> 6
p b.tab_order #==> 3
p c.tab_order #==> 4

a.tab_order = 3

p a.tab_order #==> 3
p b.tab_order #==> 4
p c.tab_order #==> 5
親に入った Control 数よりも大きい値を指定すると,その Control は最後に回される。それは指定値を受け取らず,確実に最後になるような数値を得る。

: 注意: tab_order が意味を持つのは, tab_stop が true で,その Control が親を持つ場合だけだ。 Form の tab_order は,ほかの Form を親として指定しないかぎり使われない。


tab_order が -1 の Control には親がないので, [Tab] を押してもそれに移ることはできない。


親 Control を tab order から削除するには, tab_stop を false に設定する。

!!! tab_stop : Boolean
タブ操作で移動できるかどうか。


tab_stop が true ならば self は tab order に入る。 tab_stop が false ならば self は tab order に入らないため,ユーザは Tab を押しても self へ移動できない。

: 注意: Form の tab_stop は,ほかの Form を親として指定しないかぎり意味を持たない。

!! methods

!!! focused? : Boolean
focus があるかどうか。

!!! begin_drag(immediate, threshold=-1) : nil
control のドラッグを開始します。


begin_drag を呼び出すと,ドラッグ操作を開始できます。 [[Phi::Control#drag_mode]] が DM_MANUAL の場合,ドラッグを開始するには begin_drag を呼び出さなくてはなりません。

: immediate : Boolean: true ならば,マウスポインタは [[Phi::WinControl#drag_cursor]] に変わり,すぐにドラッグが始まります。 false ならば,マウスポインタは [[Phi::WinControl#drag_cursor]] の値に変わらず, threshold で指定したピクセル数ほどマウスポインタを移動するとドラッグが始まります。
: threshold : Fixnum: 呼び出し側が 0 未満の ''threshold'' 値 ( デフォルト値など ) を渡した場合, begin_drag は [[Phi::Mouse#drag_threshold]] を使います。


''immediate'' を false に設定すると, drag and drop または drag and dock 操作を開始する前に Control で mouse click の受け付けができます。

!! event handler

!!! arg1

以下の記述で戻り値として「arg1」とかかれている場合には、引数の一番目をハンドラの戻り値として返さなければならないことを意味しています。


メソッド形式の場合には「return key」(arg1 が key の場合)とし、手続きブロック形式の場合にはブロックの最後もしくは break で抜ける直前(※)に「key」と書いて引数を評価する形でシステムに戻します。


※ メソッド形式ではメソッド定義の途中で「return key」と書いて抜けることができます。ブロック形式の場合には途中で抜けるには「return」ではなく「break」を使います。他にもスコープの違い、引数の違いなどの違いがあります。( [[WinControl]]#on_key_down の説明に両者を対比した例がありますので参考にしてください)。

!!! on_enter : nil
control が focus を受け取ったときに呼ばれる。


enter event は form から form への切り替え時や,その application と別の Windows application との切り替え時には発生しません。


例えば, Phi::Panel と Phi::GroupBox のように別々の container の中の control 間を切り替えると, container の中の control の enter event の前にその container の enter event が発生します。


同様に, Container 外の別の Control に focus が移った場合, Container 内の Control の exit event の後で, Container の exit event が発生します。


例えば, [ OK ] Button の付いた form に 3 つの Phi::RadioButton を持つ Phi::GroupBox があり,その focus が現在 [ OK ] に合っているとします。


Phi::RadioButton の 1 つが click されたとすると,まず [ OK ] の exit event ,次に Phi::GroupBox の enter event ,そして click された Phi::RadioButton の enter event が発生します。


この状態から [ OK ] を click すると, Phi::RadioButton の exit event ,次に Phi::GroupBox の exit event ,最後に [ OK ] の enter event が発生します。

!!! on_exit : nil
focus が control から別の control へ移ったときに呼ばれる。


exit event は form から from への切り替え時や,その application と別の Windows application との切り替え時には発生しません。

: 注意: [[Phi::WinControl#active_control]] は exit event が発生する前に更新されます。

!!! on_get_site_info([rect, can_dock], dock_client, pos) : arg1
control の dock 情報を返す。

: dock_client : Control: dlag される control

: pos : Point: 
: rect : Rect: [[Phi::WinControl#dock_client]] の dock 先となる長方形

: can_dock : Boolean: [[Phi::WinControl#dock_client]] が sender に dock できるかどうか


on_get_site_info を記述すると,ドラッグされたオブジェクトをドッキング可能な場所があれば,それについての情報を使って [[Phi::DragDockObject]] を初期化できる。 on_get_site_info は [[Phi::WinControl#on_dock_drop]] の前に呼ばれる。 on_get_site_info は [[Phi::WinControl#dock_site]] が true の場合にのみ発生する。

!!! on_dock_drop(source, x, y) : nil
control に別の control がドッキングされたときに発生します。

: source : [[Phi::DragDockObject]]: ドロップされるオブジェクトについての情報

: x : Fixnum: 
: y : Fixnum: マウスポインタの座標


on_dock_drop を記述すると, control に別の control がドッキングされたときに実行する特定の処理を指定できます。 on_dock_drop は, [[Phi::WinControl#dock_site]] が true の場合にのみ発生することがあります。


!!! on_dock_over(accept, source, x, y, state) : arg1
control の上に別の control がドラッグされたときに発生します。

: accept : Boolean: control がドッキング用にドラッグされたオブジェクトを受け付けるかどうか
: source : [[Phi::DragDockObject]]: ドラッグされるオブジェクトについての情報

: x : Fixnum: 
: y : Fixnum: マウスポインタの座標

: state : DragState: 現在のドラッグ状態


on_dock_over を記述すると,ウィンドウ control の上にドラッグされたドッキング可能な control が, dock_client として受け入れられるかどうかを指定できます。 on_dock_over は, [[Phi::WinControl#on_get_site_info]] によって ''source'' が初期化された後で発生します。 on_dock_over は [[Phi::WinControl#dock_site]] が true の場合にのみ発生します。

!!! on_key_down(key, shift) : arg1
control に focus がある間に任意のキーを押すと呼ばれる。


すべてのキーに反応するわけではなく、on_key_press にしか反応しないキーや on_key_press には反応せずに on_key_down にしか反応しないキーもあります。一般に文字キー、ret キー、xxキーは on_key_press で対応し、それ以外のファンクションキー(矢印キー)などは on_key_down で対応します。何が反応するかについてはそれぞれのイベントハンドラを仮に作成して p key を書いてみれば分かりますので、あらかじめ調べておいてください。

: key : Fixnum: キーボード上のキー


英数字キー以外は仮想キーコードを使って指定する。英数字キーは「?A」「?1」のように記述します。英字は大文字でなければなりません。仮想キーコードは Win::VK_ で始まる定数として定義されています。

[[Win-VirtualKeyCode]]

: 例 1: 仮想キーコードを列挙する。
Ruby -r phi -e "puts Win.constants.select{|i| /^VK_/ =~ i}.sort"
: 例 2:  require "phi" ; include Phi
form = Form.new
form.on_key_down = proc{|sender,key,shift|
  case key
    when ?A             ;   p "hit '?A'"
    when Win::VK_ESCAPE ;   p "hit 'VK_ESCAPE'"
    when Win::VK_F5     ;   p "hit 'VK_F5'"
    when Win::VK_TAB    ;   p "hit 'VK_TAB'"    ## not feel
    when Win::VK_PRINT  ;   p "hit 'VK_PRINT'"  ## not feel
  else                  ;   p "hit '%d'" % [key]
  end
}
form.show ; mainloop

: shift : ShiftState: [ Shift ], [ Alt ], [ Ctrl ], mouse button の状態。SS_SHIFT, SS_ALT, SS_CTRL で判断します。

: arg1 : == key : Fixnum: 引数の key を変更した値を返します。0 を返した場合にはキー入力を無効にします。変更の有無に関わらず必ず key の値を返してください。

: 例 1: メソッド定義での記述によるキー入力の無効化
require "phi" ; include Phi
form = Form.new :form, "[→]キーを無効にします"
edit1 = Edit.new form, :edit , "test1"
def edit1.on_key_down( key, shift )
  if key == 39
    print "[→]キーを無効にしました\n"
    key = 0
  end
  return key  ## 必ず key を返す必要があります。
end
form.show ; mainloop
: 例 2: 手続きブロックでの記述によるキー入力の無効化
require "phi" ; include Phi
form = Form.new :form, "[→]キーを無効にします"
edit1 = Edit.new form, :edit , "test1"
edit1.on_key_down = proc { |sender, key, shift|
  if key == 39
    print "[→]キーを無効にしました\n"
    key = 0
  end
  key ## ブロックの最後で key を評価する形で返します。
}
form.show ; mainloop

!!! on_key_up(key, shift) : arg1
押したキーから指を離したときに呼ばれる。

!!! on_key_press(key) : arg1
ASCII キーを押したときに呼ばれる。

: key : Fixnum: 押されたキーの Char 値


ASCII でないキー ( [ Shift ], [ F1 ] など ) は key_press event を生成しない。


キーの組み合わせは key_press event を 1 つだけ生成する。例えば, [ Shift ] + [ A ] を押すと, [ CapsLock ] がオフならば ''key'' は ?A の値となる。


ASCII でないキーまたはキーの組み合わせに応答したい場合は, [[Phi::WinControl#on_key_down]] あるいは [[Phi::WinControl#on_key_up]] を使う。