Ko-Window プログラマーズマニュアル 「ルートイベント」 ●ルートイベントとは イベントは最初まず、ルートウィンドウに対して発生します。ルートウィンドウで はこれをどのウィンドウに送るべきかを判断し、それぞれのアプリケーションへ伝わ ります。 各プロセスは、このルートイベントの受理時に割り込むことができるようになって います。割り込み可能なのは EventRedraw, EventMouseSwitch, EventMouseMove, EventKey の4つです。 これらの処理に割り込んで代わりに処理を行い、TRUE を返すとサーバー側のデフォ ルトの処理は行われません。つまり完全にルートイベントを乗っ取ったことになりま す。例えば、各ウィンドウへのイベント送信を自分で処理し、帰ってきた値が FALSE だったらポップアップメニューを出す、なんていうことが可能です。これは実際にウィ ンドウマネージャーが、アプリケーション上でマウス右ボタンでメニューを出すため の処理に使っています。 また FALSE を返した場合は引き続きデフォルト処理が行われるため、ルートのイベ ント発生時にちょっとだけフラグを立てたい、というような場合に使用することがで きます。例えばスクリーンセーバーであれば、キーやマウスの入力が行われたかどう か、このルートイベントの発生を見て判断することができます。 ●ルートイベントの取り方 ルートイベントの処理ルーチンは、各プロセスにつき1つだけ定義することができ ます。その処理ルーチンのアドレスを WindowSetRootEvent() によって登録します。 もしプログラム実行中にルートイベントの処理を止めたい場合には、この関数へ NULL を渡して下さい。プロセスが終了すると、このルートイベントの処理ルーチンは勝手 に解除されます。 例 RootExec() { return FALSE; } WindowMain() { .. WindowSetRootEvent( RootExec ); } ●実際にルートイベントを処理する例 #include __toupper( code ) { if( code >= 'a' && code <= 'z' ) return code- 0x20; } RootExec( wp, info ) WindowID wp; EventInfo *info; { if( info->option == EventKey ){ info->KeyCode= __toupper( info->KeyCode ); } return FALSE; } WindowMain() { WindowSetRootEvent( RootExec ); } これは極めて極悪なプログラムの例です。Root の EventKey を乗っ取り、入力さ れたすべての文字を大文字にしてから返しています。(注: 日本語処理はしていませ んので漢字は化ける可能性があります) プロセスを止めるには Command.win 上から kill して下さい。この例ではルートイベント処理に割り込んでいるだけで、実際の 処理は全部デフォルトのルーチンに任せています。 このようにウィンドウプログラムでイベントに割り込むことで、日本語変換 FEP なども作れるかもしれません。 #include RootExec( wp, info ) WindowID wp; EventInfo *info; { WindowID cwp= WindowGetChild( wp, info ); WindowSendEvent( cwp, info ); return TRUE; } WindowMain() { WindowSetRootEvent( RootExec ); } このプログラムは、おそらく実行しても何の変哲もなかったように感じるかもしれ ません。ですが実際は、すべてのルートイベントを乗っ取り、自分で各ウィンドウへ イベントを転送してデフォルトルーチンへは一切使っていません。つまり完全に処理 を乗っ取っています。 さまざまなウィンドウマネージャーのソースを参考にすると、この辺の処理がどう 使われているのかわかるでしょう。 1994/9/9 小笠原博之 oga@dgw.yz.yamagata-u.ac.jp DenDenNET: DEN0006 COR.