メニュー
Infomation
■お知らせ
[スパム対策]コメントにURLを含めると自動的に削除されます。
■このサイトについて
一応残していますが、全時代の遺物。全ての情報は古く役に立ちません 連絡先:メールアドレス
■日記更新情報
RSSRSS|RSS(本文のみ)|lirs
実験&リサーチ
巡回先
製作環境
 

 



2004|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|11|12|
2011|01|
2014|05|08|
2017|07|
2018|03|
2020|08|10|
2021|11|

2009年07月09日(Thursday) [長年日記]

_ [日記][コンピュータ] マルチモニタでも大丈夫なデスクトップの領域を得る方法

Windowsにおいて、ウインドウの位置を保存しておいて次回起動時に復元するといった事は普通の設計です。

しかしながら、保存した時とデスクトップのサイズが変わっていたりしてウインドウが画面外に行ってしまうという心配がちょっとあります。

特にウインドウがマウスで触れないと移動も出来ないような設計だと困ってしまいます。


なので、最初にウインドウがモニタの表示領域に入っているのかをチェックする必要があります。

で、やりがちなミスが以下のパターン。


//間違ったやりかた、デスクトップの領域を取得

rt.left = 0;

rt.top = 0;

rt.right = GetSystemMetrics( SM_CXSCREEN );

rt.bottom = GetSystemMetrics( SM_CYSCREEN );


上記では確かにデスクトップのサイズが取得出来るのですが、実はプライマリモニタだけの領域です。

マルチモニタ環境においては一番左上の座業は0ではなく負の値である事もあります。


上をちょっと改良してSM_CXSCREEN,SM_CYSCREENの代わりにSM_CXVIRTUALSCREEN,SM_CYVIRTUALSCREENを使うと仮想デスクトップ領域が得られます。

つまり全てのモニタを囲む大きな矩形領域です。

更にSM_XVIRTUALSCREEN,SM_YVIRTUALSCREEN でデスクトップの左上の座標が得られます。


しかしながらこれでも不安が残ります。

各モニタのサイズが違ったら仮想デスクトップの中に無効な領域が存在することになるからです。


じゃどうすれば良いのかって事ですがMonitorFromWindow()を使えば一発解決です。

このAPIはウインドウを指定して、そのウインドウが複数あるモニタの表示領域と一番多く重なるモニタのハンドルを返してくれます。

そしてMONITOR_DEFAULTTONULLを指定すると全く重なる領域がない場合にはNULLが返ります。

こんな感じで。


if(!MonitorFromWindow(hWnd,MONITOR_DEFAULTTONULL)){

//有効なモニタの中に入ってない

}



まぁ、これだと1ピクセルでも重なっていればOKって事になってしまって、そんなのユーザーが見つけられねぇよって事になりそうではあります。

その場合は姉妹品(?)のMonitorFromPoint()を使って自分で座標の重なり具合をチェックすればOKです。



タイトルにした「デスクトップの領域を得る方法」が書いてないですね。

領域自体を数値として取得したいならば、途中に書いた方法で仮想デスクトップ領域を得て満足するか、もっと完全な領域を取得したかったらGetMonitorInfo()を使えばいいかと思います。


最近のコメント

364,000 at 2008.06.14
Copyright (c) Suika KNOnline.NET