如何在.NET c#中使用Win32 GetMonitorInfo()?
|
我必须实现一个保存窗口最后位置的功能.当应用程序启动时,需要获取并恢复该位置.
现在可能会拆除第二台显示器.如果最后一个位置在现在不可见的监视器上(换句话说,保存的坐标在可见坐标之外),则应捕获此情况并将坐标设置为默认位置而不是最后位置. 为了检索有关监视器的信息,我需要使用Win32.我不容易做这项工作. 我创建了一个Helper CLass: 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",ExactSpelling = true)]
private static extern UInt32 MonitorFromPoint(Point pt,UInt32 dwFlags);
[DllImport("user32.dll",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和Rect类: [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); 有什么建议我需要做些什么来解决这个问题? 解决方法
您应该使用
System.Windows.Forms.Screen而不是调用本机API.它应该包含您需要的所有内容,并且更易于使用.
如果您只引用System.Drawing和System.Windows.Forms,编写自己的应该非常简单.这两个都应该工作: static Screen ScreenFromPoint1(Point p)
{
System.Drawing.Point pt = new System.Drawing.Point((int)p.X,(int)p.Y);
return Screen.AllScreens
.Where(scr => scr.Bounds.Contains(pt))
.FirstOrDefault();
}
static Screen ScreenFromPoint2(Point p)
{
System.Drawing.Point pt = new System.Drawing.Point((int)p.X,(int)p.Y);
var scr = Screen.FromPoint(pt);
return scr.Bounds.Contains(pt) ? scr : null;
}
如果您更喜欢自己进行Win32调用,那么您需要调用的函数的正确P / Invoke签名(即您从反编译.Net DLL获得的内容)是: [DllImport("User32.dll",CharSet=CharSet.Auto)]
public static extern bool GetMonitorInfo(HandleRef hmonitor,[In,Out]MONITORINFOEX info);
[DllImport("User32.dll",ExactSpelling=true)]
public static extern IntPtr MonitorFromPoint(POINTSTRUCT pt,int flags);
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto,Pack=4)]
public class MONITORINFOEX {
public int cbSize = Marshal.SizeOf(typeof(MONITORINFOEX));
public RECT rcMonitor = new RECT();
public RECT rcWork = new RECT();
public int dwFlags = 0;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=32)]
public char[] szDevice = new char[32];
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTSTRUCT {
public int x;
public int y;
public POINTSTRUCT(int x,int y) {
this.x = x;
this.y = y;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int left;
public int top;
public int right;
public int bottom;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 修改oracle数据库用户名及密码的方法
- NAND / NOR Flash read / write speed reference
- c# – 定义了boundedcapacity的贪婪和非贪婪数据流块之间的
- 如何以编程方式限制我的c#应用程序的带宽使用?
- Cocos Studio和Cocos2d-x版本对应关系 附1.6Cocostudio版本
- ruby-on-rails – Rails / execjs找不到Node.js.
- Ruby中一些基本语法知识点的罗列汇总
- sqlite3 判断数据库和表的状态
- 如何避免PIC16f877A项目中有浮点到字符串转换的堆栈溢出?
- ruby – 是否可以在命名空间中获取所有可用的耙子任务的列表
