Ko-Window アプリケーションの作成スタイル Ko-Window のアプリケーションを作る時に、ある程度標準化すべき点についてまと めます。 ●オプションスイッチの統一 -x, -y, -h, -v オプションはウィンドウの位置や大きさを決める重要なオプショ ンで、各種ウィンドウマネージャーや KF がこれらオプションを指定してプログラム を起動することがあります。ですから、可能な限りサポートし、もしくは意味を変更 しないで使用するようにして下さい。 -x, -y, -h, -v オプションの解析は、AnalyzeArgs() (winop.a) を使います。 <例> argc= AnalyzeArgs( argc, argv, &x, &y, &h, &v ); -h, -v オプションが不要な場合は、&h, &v の部分に NULL を与えて下さい。 その他のオプションに対しては特に決まりはありませんので、アプリケーション側 で判断して使用するようにして下さい。ただし慣例的に、-a は表示アトリビュート の指定、-f は表示フォントサイズの指定に使われます。強制ではありませんが、筆 者はだいたい次のような使い分けをしているので参考にして下さい。 -a 表示アトリビュート -f フォントサイズ -c 表示の横桁幅指定 (Command.win, tview など) -F 1行分のドット数 (tview, view など) -l ウィンドウなどの行数の指定 (MiniTERM, ro, k20 など) ●マウスボタンの使い方は? 特に決まりはありませんが、ウィンドウ背景やタイトルバー上では、マウスの右ボ タンはウィンドウマネージャーのポップアップメニューを表示するために使われるの で、それにならうのが普通です。またライブラリルーチンもだいたい左ボタンがクリッ クによるアクションや Clip 時の範囲指定、右ボタンがメニューに使うよう作られて います。 筆者は、新しいものを考案していく上では足かせがないのがフリーソフトウエアな らではの利点だと考えています。だから、使いやすさ、便利さを追及した上でなら、 可能性がある限りどんな操作方法でも可でしょう。 ただし、プログラム上の手抜き、または特に理由もポリシーも無しに他のシステム の単なる真似、によってこれまでの Ko-Window アプリケーションらと大きく異なり 混乱を招きかねない操作方法を採用するのは、好ましくありません。 ●ウィンドウ間インターフェース Ko-Window のアプリケーションプログラミングにおける、最重要視すべき点です。 EventUser の各種データ送受信に対しては、可能な限り対応するよう必ず努力して 下さい。 簡単にいえば、例えば起動後にファイル名を得る必要があるアプリケーションでは kf からファイルを受け取れるようにして下さい、ということです。また同様に、内 部で持っているファイル名等の所有している情報は、外に発信できるようにして下さ い。 これはどうせ有用じゃないから、という心配は無用。とにかく転送できるようにし ておけば、応用がききます。例えば sreport.win や timer.win の時計でも、時刻と いう文字列を他のウィンドウへ転送できるわけです。もちろんアプリケーションによっ ては Clip Board を使うのもいいでしょう。 文字列に限らず、bitmap なら Sheet (UserSheet)、グラフィック画像なら UGraphic (UserGraphic)、PCM に関しては PowerWave(作:CAB氏) のドキュメントにフォーマッ トの規定があります。 以下いくつかの具体例です。 ・外部データの受取 (1) ファイル名を得たい場合 <例> 受け取ったファイル名からすぐアクションを起こす場合(画像ローダーなど) ----------------------------------------------------------------------------- case EventUser: switch( info->ComData ){ case UserPaste: case UserString: file_read( info->ComBuffer ); return TRUE; case UserStrings: { char *pptr= info->ComBuffer; for(; *pptr ;) file_read( *pptr++ ); } /*受け取れるファイル名が1つのみならループする必要はない file_read( *(char**)info->ComBuffer ); など */ return TRUE; } return FALSE; ----------------------------------------------------------------------------- もしファイル名をキー入力するための部分があるなら、UserString/UserPaste は 上記のようにそのままファイル名とせず、キー入力文字列として自分自身に転送する ようにするといいでしょう。corlib.a にある ClipGetKeyBoard() などの関数が便利 です。その場合でも UserStrings で受け取ったファイル名は、そのままアクション を起こして構いません。 <例> UserPaste/String はキー入力として渡すが Strings(KFからの転送)の場合はそ のままアクションを起こす ----------------------------------------------------------------------------- case EventUser: switch( info->ComData ){ case UserPaste: case UserString: return ClipGetKeyBoardAll( wp, info ); case UserStrings: { char *pptr= info->ComBuffer; for(; *pptr ;) file_read( *pptr++ ); } return TRUE; } return FALSE; ----------------------------------------------------------------------------- (2) Sheet データを得る場合 (Ko-Window の bitmap) Sheet データのリアルタイム受け取りは、パターンデータを扱うアプリケーション では重要です。ですが、それ以外にも例えばゲームでゲーム中のキャラクタをいきな り UserEvent で受け取ってそのまま使用してしまう、なんてことができるでしょう。 (例えば shotZ の自機デザインなどはこれに対応しています) <例> UserSheet の受取、 UserString/Strings のファイル名は、Sheetファイルと見 なしデータとしてロードできるようにすることもある。 ----------------------------------------------------------------------------- case EventUser: switch( info->ComData ){ case UserSheet: copy_sheet( info->ComBuffer ); return TRUE; } return FALSE; ----------------------------------------------------------------------------- 受け取ったデータは、必ず自分のアプリケーション上にコピーしなければなりません。 (3) 画像を受け取る場合 画像データは UserGraphic としてフォーマットが定義されました。UserGraphic.doc を参照して下さい。受け取り方は Sheet の場合とほとんど同じです。また関連ライ ブラリとして gvlib.a も用意しました。こちらも合せて参照して下さい。 (4)そのほか 受け取れるのはデータだけではありません。コマンドを受け取ることができるアプ リケーションはかなり多く存在します。例えば Command.win は外部からイベントに よってプログラムを走らせることができたり、KF は内部コマンドを全部外部のイベ ントで実行できたり、プレイヤーは音楽操作を外部のイベント送信でコントロールで きたり、します。そのコマンド送受信の方法は大きく分けて2種類存在します。 ・UserString を使う場合 UserString で送られてきた文字列がコマンド名ならそれを解釈し て実行します。例えばプレイヤーでは、"Play:" という文字列が送 られてきたら再生を開始する、といった感じです。ファイル名も受 け取れるようにしているアプリケーションの場合は、ファイル名と 区別できる形になっていなければなりません。(た問えば "Play:" のように、最後にコロンをつけるなど) この方法は、送信側に特に工夫が要らず簡単で、応用がききやすい ためかなりよく使われます。ただし、エディタなどキー入力を必要 とするアプリケーションでは、UserString をそのまま文字列のデー タとして受け取りたいので、この方法をコマンド判定に使うのはあ まりよくありません。 ・アプリケーション専用の User インターフェースを設ける場合 例えば info->UserData が 'COM' なら、info->ComBuffer を文字 列としてその内容をコマンドとして判定して実行する、というもの です。Command.win など UserString はそのままデータとして判断 した方が良いものではこの方法を使っています。UserData の決め 方は user.doc を参照して下さい。また送信するデータは、 UserString 同様に info->ComBuffer は単純な文字列のポインタと して、コマンド判断を行うようにして下さい。例えば数値を送る場 合も "set:123" などのように数値の文字列として送受信します。 文字列であれば、usend や wsh からイベントを送信する処理が簡 単に書けてたいへん都合がいいからです。 ・外部へのデータの送信 内部でもっている文字列などは、可能な限り送信できるように作っておくといいで しょう。単一行の文字列の場合、例えばファイル名の場合は、ポインタを与えて UserSendOperation() を使いダイレクト転送するだけです。これだと極めて簡単で、 またアプリケーションの負担になりません。 <例> ----------------------------------------------------------------------------- case EventMouseSwitch: if( info->LeftON ){ UserSendOperation( wp, info, UserString, FileName ); return TRUE; } return FALSE; ----------------------------------------------------------------------------- UserSendOperation() は文字列だけでなく、Sheet や UGraphic といった画像や、 PCM データでもそのまま使用することができます。 まとめたテキストや、または任意部分を切り出して送るような場合は Clip Board 経由で clip & paste を使います。これは ClipSetOperation() を使うと便利です。 ClipSetOperation() は tvlib のソースでも使われています。ぜひ参考にして下さい。 この辺は Ko-Window アプリケーションの連係、自由度をあげる部分でもあるので、 ぜひこだわって作り、素晴らしいアプリケーションに仕上げて下さい。 ---- 1995 11/27 初期公開版 小笠原博之 oga@dgw.yz.yamagata-u.ac.jp DenDenNET: DEN0006 COR.