この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
2005/12/12 更新
Windowsが管理する座標系には次の2種類が存在する。
以下の画面は、これら2つの座標系を図示したものだ。
スクリーン座標とは、画面の左上隅の点を基準とした絶対的な座標系である。
一方のクライアント座標とは、Windowsアプリケーションが持つ「ウィンドウ領域」の中に含まれる描画可能な領域(これを「クライアント領域」と呼ぶ)を基準にした座標系である(ここではクライアント<座標>とクライアント<領域>という単語の違いに注意すること)。つまりクライアント座標は、クライアント領域の原点からの相対的な位置を示す座標系である(なお本稿ではクライアント領域とウィンドウ領域の違いの説明は割愛するが、詳しくは「TIPS:クライアント領域やウィンドウ領域の座標を取得するには?」を参照してほしい)。
なおWindows OSレベルでは、デスクトップ上のGUI要素はすべてウィンドウとして管理されている。例えばボタンなどのコントロールも1つのウィンドウである。そのウィンドウそれぞれがクライアント領域を持っているため、すべてのウィンドウはクライアント座標を持っていることになる。
このように.NETアプリケーションでは2種類の座標系が存在するわけだが、Windowsアプリケーションでの座標の取り扱いは、基本的にクライアント座標で行われる。このようになっているのは、Windowsアプリケーションでは基本的にクライアント領域内にしか描画やコントロールの配置などを行わないためだ。
しかし.NETの一部のメソッドやプロパティでは、クライアント座標ではなく、スクリーン座標を取り扱うものがある。代表的なものでいえば、マウス・カーソルの座標などがそれである(マウス・カーソルの座標の扱いについては、「TIPS:カーソルの位置を取得・設定するには?」を参照してほしい)。
このようなプロパティから取得したスクリーン座標の点(位置)の情報を、ウィンドウ内部の処理で使用する際には、それをいったんクライアント座標に変換しなければならないケースが非常に多い。これは、(前述したように)ウィンドウ内部の処理では、クライアント座標による計算が基本となっているからだ。また逆に、ウィンドウ内部のクライアント座標をこのようなプロパティに設定したい場合には、すべてスクリーン座標に変換したうえで行う必要がある。
実際にスクリーン座標の点(位置)をクライアント座標に変換するには、そのウィンドウのPointToClientメソッドを利用すればよい。例えば、スクリーン座標の点をフォームのクライアント座標に変換するには、フォームのPointToClientメソッドを呼び出せばよいし、スクリーン座標の点をボタンのクライアント座標に変換したい場合は、ボタンのPointToClientメソッドを呼び出せばよい。
なおPointToClientメソッドは、パラメータにPoint型(System.Drawing名前空間)の値を取り、戻り値としてPoint型の値を返す。要するに、パラメータが変換前の座標で、戻り値が変換後の座標だ。
以下のサンプル・プログラムは、このPointToClientメソッドの利用例である。このサンプル・プログラムでは、マウス・カーソルの位置をスクリーン座標で取得した後、フォームのクライアント座標とボタンのクライアント座標へ変換している。そしてそれぞれの座標をラベル・コントロール上に表示している。この一連の処理を10ミリ秒ごとに繰り返している(10ミリ秒ごとに処理を実行する方法の詳細は「TIPS:タイマにより一定時間間隔で処理を行うには?(Windowsタイマ編)」を参考にしていただきたい)。
private void timer1_Tick(object sender, System.EventArgs e)
{
// マウス・カーソルのスクリーン座標での位置を取得
label1.Text = Cursor.Position.ToString();
// フォームを基準に(スクリーン座標を)クライアント座標に変換
Point formClientCurPos = this.PointToClient(Cursor.Position);
label2.Text = formClientCurPos.ToString();
// ボタンを基準に(スクリーン座標を)クライアント座標に変換
Point btnClientCurPos = button1.PointToClient(Cursor.Position);
label3.Text = btnClientCurPos.ToString();
}
Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer1.Tick
' マウス・カーソルのスクリーン座標での位置を取得
label1.Text = Cursor.Position.ToString()
' フォームを基準に(スクリーン座標を)クライアント座標に変換
Dim formClientCurPos As Point = Me.PointToClient(Cursor.Position)
label2.Text = formClientCurPos.ToString()
' ボタンを基準に(スクリーン座標を)クライアント座標に変換
Dim btnClientCurPos As Point = _
button1.PointToClient(Cursor.Position)
label3.Text = btnClientCurPos.ToString()
End Sub
このサンプル・プログラムを実際に実行したのが次の画面である。この画面ではマウス・カーソルはボタン・コントロールの左上隅に位置している。
逆にクライアント座標の点(位置)をスクリーン座標に変換するには、ウィンドウのPointToScreenメソッドを利用すればよい。例えば、フォームのクライアント座標の点をスクリーン座標に変換するにはフォームのPointToScreenメソッドを呼び出せばよいし、ボタンのクライアント座標の点をスクリーン座標に変換したい場合はボタンのPointToScreenメソッドを呼び出せばよい。
なおPointToScreenメソッドも、先ほどのPointToClientメソッドと同様に、パラメータにPoint型(System.Drawing名前空間)の値を取り、戻り値としてPoint型の値を返す。パラメータが変換前の座標で、戻り値が変換後の座標だ。
Copyright© Digital Advantage Corp. All Rights Reserved.