授業で配布したチャットプログラムをもとに[手書き文字]機能への拡張をします。 手書き文字機能とは、
という機能です。 手書きチャットとはこの手書き文字機能をネットワークの上に乗せたものです。 すなわちネットワーク上の複数(課題では2名)の利用者が同じキャンバスを共有しあい、お互い好きなように手書き文字を書きあえるという仮想の伝言板です(下図)。
以上が機能仕様です。 次にアプリケーションプロトコルについて述べます。
アプリケーション層のプロトコルについて説明します。まず、トランスポート層のプロトコルとしてTCP/IP:ストリームソケットを用います。 利用するポート番号は十進の10000とします。 アプリケーション層のメッセージは以下に述べる2種類のみから構成されます。
マウスを使って自由線を描く時、まずマウスのボタンを押した時に座標を取得します。 次にボタンを押したままマウスを動かした時に座標を取得します。 (その検出方法はあとで述べます)そして、これらの座標間を線でつなぎます。 ここで、これらの座標データは保持しておく必要があります。 なぜなら、再描画するために必要となるからです。 そこで、これらの座標を格納しておくテーブルの例を表1に示します。 今回の、サンプルプログラムでは次のようなテーブルを自分用と相手用の2つを定義しています。
表1:座標格納テーブルの例
点番号 | 1 | 2 | 3 | 4 | 5 | 6 | ・・・ |
ペンダウンフラグ | 0 | 1 | 1 | 1 | 0 | 1 | ・・・ |
X座標 | 109 | 120 | 135 | 140 | 350 | 298 | ・・・ |
Y座標 | 9 | 25 | 50 | 120 | 238 | 240 | ・・・ |
ペンダウンフラグが1の時は、マウスの左ボタンを押して動かすことを意味しており、1つ前の座標とその座標を線で結ぶというフラグです。 表1で説明すると、点番号2は1つ前の点番号1と線で結びなさいということになります。 また、ペンダウンフラグ0は線の始点であることを表しています。 つまり、表1の点番号1~4までが1つの線分で点番号5~が別の線分である事を示しています。
今回必要とするマウスボタンの状態は、マウスボタンを押した時とマウスボタンを押したまま動かした時の2つです。 このうち前者のメッセージは授業中で参照したホームページに掲載されています。 後者についてあまり詳しく説明されていないので補足します。
WM_MOUSEMOVEメッセージを検出した後に“ボタンが押されているかどうか”を検出しなくてはなりません。 ウィンドウ関数の引数(WPARAM型)には、押されたキーのASCIIコードが入ってきます。 この引数がMK_LBUTTONであるかどうかでマウスの左ボタンが押されているか調べる事ができます。 表2にWPARAM型引数の種類を示します。
表2:MOUSEMOVE時のWPARAM型引数の種類
引数(WPARAM型) | 状態 |
MK_CONTROL | Ctrlキーが押されている |
MK_LBUTTON | マウスの左ボタンが押されている |
MK_RBUTTON | マウスの右ボタンが押されている |
MK_SHIFT | Shiftキーが押されている |
実際に送受信されるものは簡略化のため文字列で行います。 そのため、取得した整数の座標を文字列に変換しなければなりません。 その時、注意しなければならないのは整数→文字列の変換です。 チャットプログラムのプロトコルでは文字列でペンダウンフラグ1バイト、X座標3バイト、Y座標3バイトです。 これを守らないととんでもない座標が相手に送られてします。 たとえ座標が2桁であっても1桁であっても3バイトで送らなければなりません。
例:[0002034] ―――― ペンダウンフラグ0、X座標2、Y座標34
意図的に再描画命令を発行する方法にInvalidateRect()がある事は「再描画」のところで説明しました。 この命令の第2引数をNULLにした場合、画面全体に再描画が行われます。 この手書きチャットプログラムにおいて、この引数をNULLにしてしまうと再描画命令が頻繁に発行されるため、画面のちらつきが激しくなってしまいます。 これを抑えるために第2引数を長方形の領域(クリッピング領域)を指定するRECT構造体へのポインタにします。 つまり、このクリッピング領域を指定する事で実際に再描画が行われる範囲を限定する事ができます。 この領域を指定するRECT構造体には以下のような4つのメンバがあります。
manabaで提出する。