我必须实现保存窗口最后位置的功能。当应用程序启动时,需要获取并恢复此位置。如何在.NET c#中使用Win32 GetMonitorInfo()?
现在可能是第二台显示器被拆除。如果最后一个位置在现在不可见的监视器上(换句话说,保存的坐标在可见坐标之外),则应该捕获这种情况,并将坐标设置为默认位置而不是最后位置。
为了检索关于显示器的信息,我需要使用Win32。我做这件事并不容易。
我创建了一个助手类:
public static class DisplayHelper
{
private const int MONITOR_DEFAULTTONEAREST = 2;
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int GetSystemMetrics(int nIndex);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern UInt32 MonitorFromPoint(Point pt, UInt32 dwFlags);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern bool GetMonitorInfo(UInt32 monitorHandle, ref MonitorInfo mInfo);
public static void GetMonitorInfoNow(MonitorInfo mi, Point pt)
{
UInt32 mh = MonitorFromPoint(pt, 0);
mi.cbSize = (UInt32)System.Runtime.InteropServices.Marshal.SizeOf(typeof(MonitorInfo));
mi.dwFlags = 0;
bool result = GetMonitorInfo(mh, ref mi);
}
}
而这些是我尝试创建monitorInfo的和矩形类:
[StructLayout(LayoutKind.Sequential)]
public class MonitorInfo
{
public UInt32 cbSize;
public Rectangle2 rcMonitor;
public Rectangle2 rcWork;
public UInt32 dwFlags;
public MonitorInfo()
{
rcMonitor = new Rectangle2();
rcWork = new Rectangle2();
cbSize = (UInt32)System.Runtime.InteropServices.Marshal.SizeOf(typeof(MonitorInfo));
dwFlags = 0;
}
}
[StructLayout(LayoutKind.Sequential)]
public class Rectangle2
{
public UInt64 left;
public UInt64 top;
public UInt64 right;
public UInt64 bottom;
public Rectangle2()
{
left = 0;
top = 0;
right = 0;
bottom = 0;
}
}
我使用这个代码,这样获得的可视监控:
//80 means it counts only visible display monitors.
int lcdNr = DisplayHelper.GetSystemMetrics(80);
var point = new System.Drawing.Point((int) workSpaceWindow.Left, (int) workSpaceWindow.Top);
MonitorInfo monitorInfo = new MonitorInfo();
DisplayHelper.GetMonitorInfoNow(monitorInfo, point);
最后一个方法在尝试执行时会引发异常
bool result = GetMonitorInfo(mh, ref mi);
任何建议,我需要做什么来解决这个问题?
感谢Gabe,我忘记提及我的应用程序是用WPF编写的。理论上,我将无法访问System.Windows.Forms.Screen,除非它也适用于WPF? – Houman 2011-06-08 13:41:22
@Kave:只需添加一个对System.Windows.Forms.dll的引用,就可以在WPF中使用它。 – Gabe 2011-06-08 13:43:39
@Gabe - 这可能会更容易,但我不确定是否会为任何优化加载一个类/方法的5MB程序集。更不用说它的依赖关系;-) – CodeNaked 2011-06-08 13:55:12