デスクトップ全体のサイズを確認するにはどうすればよいですか?「作業領域」でも「画面解像度」でもありません。どちらも1つの画面のみを参照します。各モニターに一部しか表示されていない仮想デスクトップの全幅と高さを知りたい。
11 に答える
2つのオプションがあります。
PresentationFramework.dll
SystemParameters.VirtualScreenWidth SystemParameters.VirtualScreenHeightSystem.Windows.Forms.dll
SystemInformation.VirtualScreen.Width SystemInformation.VirtualScreen.Height
WPFアプリケーションを開発する場合は、最初のオプションを使用してください。
少しのLINQを使用して、この回答を最新のものにするときが来たと思います。これにより、1つの式でデスクトップ全体のサイズを簡単に取得できます。
Console.WriteLine(
Screen.AllScreens.Select(screen=>screen.Bounds)
.Aggregate(Rectangle.Union)
.Size
);
私の最初の答えは次のとおりです。
私はあなたが欲しいものはこのようなものだと思います:
int minx, miny, maxx, maxy;
minx = miny = int.MaxValue;
maxx = maxy = int.MinValue;
foreach(Screen screen in Screen.AllScreens){
var bounds = screen.Bounds;
minx = Math.Min(minx, bounds.X);
miny = Math.Min(miny, bounds.Y);
maxx = Math.Max(maxx, bounds.Right);
maxy = Math.Max(maxy, bounds.Bottom);
}
Console.WriteLine("(width, height) = ({0}, {1})", maxx - minx, maxy - miny);
これがすべてを物語っているわけではないことを覚えておいてください。複数のモニターをずらしたり、非長方形に配置したりすることができます。したがって、(minx、miny)と(maxx、maxy)の間のスペースのすべてが表示されているわけではない可能性があります。
編集:
私はちょうどコードが使用することで少し簡単になるかもしれないことに気づきましたRectangle.Union:
Rectangle rect = new Rectangle(int.MaxValue, int.MaxValue, int.MinValue, int.MinValue);
foreach(Screen screen in Screen.AllScreens)
rect = Rectangle.Union(rect, screen.Bounds);
Console.WriteLine("(width, height) = ({0}, {1})", rect.Width, rect.Height);
小切手:
SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height
モニターの物理的なピクセルサイズを取得するには、これを使用できます。
static class DisplayTools
{
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
private enum DeviceCap
{
Desktopvertres = 117,
Desktophorzres = 118
}
public static Size GetPhysicalDisplaySize()
{
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
IntPtr desktop = g.GetHdc();
int physicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.Desktopvertres);
int physicalScreenWidth = GetDeviceCaps(desktop, (int)DeviceCap.Desktophorzres);
return new Size(physicalScreenWidth, physicalScreenHeight);
}
}
これは質問に答えるものではありませんが、すべての画面内のウィンドウのポイント(場所)に関する追加の洞察を追加するだけです。
以下のコードを使用して、ポイント(たとえば、ウィンドウの最後の既知の場所)がデスクトップ全体の範囲内にあるかどうかを確認します。そうでない場合は、ウィンドウの場所をデフォルトのpBaseLocにリセットします。
コードはタスクバーや他のツールバーを考慮していません。
使用例:ウィンドウの場所をステーションAからデータベースに保存します。ユーザーは2台のモニターでステーションBにログインし、ウィンドウを2台目のモニターに移動し、ログアウトして新しい場所を保存します。ステーションAに戻ると、上記のコードを使用しない限り、ウィンドウは表示されません。
私のさらなる解決策は、ユーザーIDとステーションのIP(&winLoc)を特定のアプリのデータベースまたはローカルユーザー設定ファイルに保存してから、そのステーションとアプリのユーザー設定を読み込むことを実装しました。
Point pBaseLoc = new Point(40, 40)
int x = -500, y = 140;
Point pLoc = new Point(x, y);
bool bIsInsideBounds = false;
foreach (Screen s in Screen.AllScreens)
{
bIsInsideBounds = s.Bounds.Contains(pLoc);
if (bIsInsideBounds) { break; }
}//foreach (Screen s in Screen.AllScreens)
if (!bIsInsideBounds) { pLoc = pBaseLoc; }
this.Location = pLoc;
「実際の」画面サイズを取得する最良の方法は、ビデオコントローラーから直接値を取得することだと思います。
using System;
using System.Management;
using System.Windows.Forms;
namespace MOS
{
public class ClassMOS
{
public static void Main()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_VideoController");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("CurrentHorizontalResolution: {0}", queryObj["CurrentHorizontalResolution"]);
Console.WriteLine("-----------------------------------");
Console.WriteLine("CurrentVerticalResolution: {0}", queryObj["CurrentVerticalResolution"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}
これでうまくいくはずです;)ご挨拶..。
の境界を使用できますSystem.Drawing。
このような関数を作成できます
public System.Windows.Form.Screen[] GetScreens(){
Screen[] screens = Screen.AllScreens;
return screens;
}
そして、次のような変数で画面1、2などを取得できます。
System.Windows.Form.Screen[] screens = func.GetScreens();
System.Windows.Form.Screen screen1 = screens[0];
次に、画面の境界を取得できます。
System.Drawing.Rectangle screen1Bounds = screen1.Bounds;
このコードを使用すると、、などのすべてのプロパティを取得できWidthますHeight。
このメソッドは、LeftとTopに最小値を使用し、RightとBottomに最大値を使用して、すべての画面の境界を含む長方形を返します。
static Rectangle GetDesktopBounds() {
var l = int.MaxValue;
var t = int.MaxValue;
var r = int.MinValue;
var b = int.MinValue;
foreach(var screen in Screen.AllScreens) {
if(screen.Bounds.Left < l) l = screen.Bounds.Left ;
if(screen.Bounds.Top < t) t = screen.Bounds.Top ;
if(screen.Bounds.Right > r) r = screen.Bounds.Right ;
if(screen.Bounds.Bottom > b) b = screen.Bounds.Bottom;
}
return Rectangle.FromLTRB(l, t, r, b);
}
依存関係のない仮想ディスプレイのサイズを取得する
public enum SystemMetric
{
VirtualScreenWidth = 78, // CXVIRTUALSCREEN 0x0000004E
VirtualScreenHeight = 79, // CYVIRTUALSCREEN 0x0000004F
}
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(SystemMetric metric);
public static Size GetVirtualDisplaySize()
{
var width = GetSystemMetrics(SystemMetric.VirtualScreenWidth);
var height = GetSystemMetrics(SystemMetric.VirtualScreenHeight);
return new Size(width, height);
}
SM_XVIRTUALSCREENなどから派生した値は物理座標であり、コントロールパネルの画面スケーリング125%、150%、175%での論理座標と等しくありません。
多くのウィンドウ操作がまだ利用できないか、利用できない可能性があることがわかります。私はPInvoke.User32nugetパッケージで最大の成功を収めました。
var screenX = PInvoke.User32.GetSystemMetrics(PInvoke.User32.SystemMetric.SM_CXSCREEN);
var screenY = PInvoke.User32.GetSystemMetrics(PInvoke.User32.SystemMetric.SM_CYSCREEN);