.NETアプリ
Location
トップレベルのFormのLocationはスクリーン座標でフォームの左上の座標を表す。
ControlのLocationはコンテナからの相対座標の左上を表す。コントロールのスクリーン座標を知りたいときは、コンテナのPointToScreenにコントロールの相対座標を渡す。
最大化しているとき
フォームが最大化あるいは最小化しているときは、最大化する前のフォームの座標をRestoreBoundsから取得できる。
座標の保存
最大化しているときはRestoreBoundsを保存する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private void Form1_FormClosed ( object sender , FormClosedEventArgs e )
{
Profile . WriteBool ( SECTION_LOCATION , KEY_MAXIMIZED ,
_isMinimizedFromMaximized || WindowState == FormWindowState . Maximized , IniPath ) ;
int x , y , width , height ;
if ( WindowState == FormWindowState . Normal )
{
x = Location . X ;
y = Location . Y ;
width = Width ;
height = Height ;
}
else
{
x = RestoreBounds . X ;
y = RestoreBounds . Y ;
width = RestoreBounds . Width ;
height = RestoreBounds . Height ;
}
Profile . WriteInt ( SECTION_LOCATION , KEY_X , x , IniPath ) ;
Profile . WriteInt ( SECTION_LOCATION , KEY_Y , y , IniPath ) ;
Profile . WriteInt ( SECTION_LOCATION , KEY_WIDTH , width , IniPath ) ;
Profile . WriteInt ( SECTION_LOCATION , KEY_HEIGHT , height , IniPath ) ;
}
座標の復元
このコードでは保存された座標がスクリーン上にあるかどうかは確認していない。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void Form1_Load ( object sender , EventArgs e )
{
bool maxed ;
int x , y , width , height ;
Profile . GetBool ( SECTION_LOCATION , KEY_MAXIMIZED , false , out maxed , IniPath ) ;
Profile . GetInt ( SECTION_LOCATION , KEY_X , 0 , out x , IniPath ) ;
Profile . GetInt ( SECTION_LOCATION , KEY_Y , 0 , out y , IniPath ) ;
Profile . GetInt ( SECTION_LOCATION , KEY_WIDTH , 640 , out width , IniPath ) ;
Profile . GetInt ( SECTION_LOCATION , KEY_HEIGHT , 480 , out height , IniPath ) ;
if ( maxed )
{
Location = new Point ( x , y ) ;
Size = new Size ( width , height ) ;
WindowState = FormWindowState . Maximized ;
}
else
{
Location = Location = new Point ( x , y ) ;
Size = new Size ( width , height ) ;
}
}
Win32アプリ
最大化しているとき
ウインドウが最小化されていてリストアしたとき最大化するかどうかはGetWindowPlacement()で調べることができる。WPF_RESTORETOMAXIMIZEDが立っていれば、リストアしたとき最大化する。
.NETではフォームが最小化されていて、リストアしたとき最大化するのかどうかを調べる方法はないと思われるので、Resizeイベントでその状態かどうかのフラグを用意する。
private void Form1_Resize ( object sender , EventArgs e )
{
_isMinimizedFromMaximized = false ;
if ( WindowState == FormWindowState . Minimized )
{
if ( _lastWindowState == FormWindowState . Maximized )
{
_isMinimizedFromMaximized = true ;
}
}
_lastWindowState = WindowState ;
}
マルチスクリーン
マルチスクリーンのスクリーン座標はモニタをつなげて1つのスクリーンとみなせるような座標になる。
あるスクリーン座標がモニタ内にあるかは以下のように調べられる。(コードはC++/CLI)
bool IsPointInScreen ( System :: Drawing :: Point pt )
{
for each ( System :: Windows :: Forms :: Screen ^ s in System :: Windows :: Forms :: Screen :: AllScreens )
{
if ( s -> WorkingArea . Contains ( pt ) )
{
return true ;
}
}
return false ;
}