如何解决C# 桌面背景显示的位置可能不正确?
嗨,我目前正在创建一个动画桌面背景,它使用 axWindowsMideaPlayer 循环播放视频文件我使用 WMP 并将其句柄设置为桌面句柄,它在单显示器设置上运行良好,但在多台显示器上失败。为什么它失败是因为显示器可以有自己的设置位置,如主屏幕的左/右/左上/左上/右上/上/下/左下和右下,这将它们的位置放在底片中等等..我的问题是如何我可以在每台显示器上正确放置每个 WMP 吗?这是我目前所拥有的,
这就是我获得每台显示器的方式...
public class displayInfo
{
public bool isPrimary { get; set; }
public int ScreenHeight { get; set; }
public int ScreenWidth { get; set; }
public Rect MonitorArea { get; set; }
public Rect WorkArea { get; set; }
public string DeviceName { get; set; }
}
/// <summary>
/// Collection of display information
/// </summary>
public class displayInfoCollection : List<displayInfo>
{
// size of a device name string
private const int CCHDEVICENAME = 32;
/// <summary>
/// The MONITORINFOEX structure contains information about a display monitor.
/// The GetMonitorInfo function stores information into a MONITORINFOEX structure or a MONITORINFO structure.
/// The MONITORINFOEX structure is a superset of the MONITORINFO structure. The MONITORINFOEX structure adds a string member to contain a name
/// for the display monitor.
/// </summary>
[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Auto)]
internal struct MONITORINFOEX
{
/// <summary>
/// The size,in bytes,of the structure. Set this member to sizeof(MONITORINFOEX) (72) before calling the GetMonitorInfo function.
/// Doing so lets the function determine the type of structure you are passing to it.
/// </summary>
public int Size;
/// <summary>
/// A RECT structure that specifies the display monitor rectangle,expressed in virtual-screen coordinates.
/// Note that if the monitor is not the primary display monitor,some of the rectangle's coordinates may be negative values.
/// </summary>
public Rect Monitor;
/// <summary>
/// A RECT structure that specifies the work area rectangle of the display monitor that can be used by applications,/// expressed in virtual-screen coordinates. Windows uses this rectangle to maximize an application on the monitor.
/// The rest of the area in rcMonitor contains system windows such as the task bar and side bars.
/// Note that if the monitor is not the primary display monitor,some of the rectangle's coordinates may be negative values.
/// </summary>
public Rect WorkArea;
/// <summary>
/// The attributes of the display monitor.
///
/// This member can be the following value:
/// 1 : MONITORINFOF_PRIMARY
/// </summary>
public uint Flags;
/// <summary>
/// A string that specifies the device name of the monitor being used. Most applications have no use for a display monitor name,/// and so can save some bytes by using a MONITORINFO structure.
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr,SizeConst = CCHDEVICENAME)]
public string DeviceName;
public void Init()
{
this.Size = 40 + 2 * CCHDEVICENAME;
this.DeviceName = string.Empty;
}
}
[DllImport("user32.dll")]
private static extern bool EnumdisplayMonitors(IntPtr hdc,IntPtr lprcclip,EnumMonitorsDelegate lpfnEnum,IntPtr dwData);
[DllImport("user32.dll",CharSet = CharSet.Auto)]
private static extern bool GetMonitorInfo(IntPtr hMonitor,ref MONITORINFOEX lpmi);
/*
[DllImport("user32.dll")]
static extern bool GetMonitorInfo(IntPtr hMonitor,ref MONITORINFO lpmi);
*/
/// <summary>
/// Returns the number of displays using the Win32 functions
/// </summary>
/// <returns>collection of display Info</returns>
public static displayInfoCollection Getdisplays()
{
displayInfoCollection col = new displayInfoCollection();
EnumdisplayMonitors(IntPtr.Zero,IntPtr.Zero,delegate (IntPtr hMonitor,IntPtr hdcMonitor,ref Rect lprcMonitor,IntPtr dwData)
{
MONITORINFOEX mi = new MONITORINFOEX();
mi.Size = (int)Marshal.SizeOf(mi);
bool success = GetMonitorInfo(hMonitor,ref mi);
if (success)
{
displayInfo di = new displayInfo();
di.ScreenWidth = (mi.Monitor.Right - mi.Monitor.Left);
di.ScreenHeight = (mi.Monitor.Bottom - mi.Monitor.Top);
di.MonitorArea = mi.Monitor;
di.WorkArea = mi.WorkArea;
di.isPrimary = Convert.ToBoolean(mi.Flags);
di.DeviceName = mi.DeviceName;
col.Add(di);
}
return true;
},IntPtr.Zero);
return col;
}
}
这就是我尝试调用和使用它的方式,但它会根据显示器的位置放置 WMP。
displayInfoCollection dic = displayInfoCollection.Getdisplays();
int count = 0;
int totalPosX = 0;
int totalPosY = 0;
displayInfo dInfo = null;
List<displayInfo> di = dic.OrderByDescending(d => d.isPrimary).ToList();
var or = Systeminformation.VirtualScreen;
foreach (displayInfo dm in di)
{
bool zeroOutX = false;
bool zeroOutY = false;
if (dm.isPrimary)
{
totalPosX = or.Left > 0 ? or.Left : -or.Left;
totalPosY = or.Top > 0 ? or.Top : -or.Top;
dInfo = dm;
}
else
{
bool left = false;
bool top = false;
bool right = false;
bool bottom = false;
bool topLeft = false;
bool topRight = false;
bool bottomLeft = false;
bool bottomright = false;
int posY = dm.MonitorArea.Top > 0 ? dm.MonitorArea.Top : -dm.MonitorArea.Top;
if (dm.MonitorArea.Left < 0)
{
left = true;
}
else
right = dm.MonitorArea.Left > 0;
if (dm.MonitorArea.Top < 0)
{
top = true;
}
else
bottom = dm.MonitorArea.Top > 0;
bool center = (dm.MonitorArea.Left > 0 ?
dm.MonitorArea.Left : -dm.MonitorArea.Left) > 0 ||
(dm.MonitorArea.Left > 0 ?
dm.MonitorArea.Left : -dm.MonitorArea.Left) < dInfo.ScreenWidth;
topLeft = left && top;
topRight = right && top;
bottomLeft = left && bottom;
bottomright = right && bottom;
if (topLeft || topRight || bottomLeft || bottomright || left || right)
{
if (dm.MonitorArea.Left < 0)
zeroOutX = true;
else
totalPosX += dInfo.ScreenWidth;
if (dm.MonitorArea.Top < 0)
zeroOutY = true;
else
totalPosY += dm.MonitorArea.Top;
}
dInfo = dm;
}
display display = new display(dm.DeviceName,dm.ScreenWidth,dm.ScreenHeight,zeroOutX ? 0 : totalPosX,zeroOutY ? 0 : totalPosY,Controls,count);
displays.Add(display);
count++;
}
我在这个问题上找不到太多帮助,并尝试了很多方法来做到这一点,它的 ac# windows 表单,我是编程新手,我的知识有限,任何帮助都将提前感谢。
解决方法
EnumDisplaySettings 函数为以下五个设置值 DEVMODE 成员:
- dmBitsPerPel
- dmPelsWidth
- dmPelsHeight
- dmDisplayFlags
- dmDisplayFrequency
(不包括dmPosition
),您应该尝试使用EnumDisplaySettingsEx
,并指定DM_POSITION
以获得正确的dmPosition
值。
感谢所有帮助我找到问题解决方案的人,如果有人需要知道的话。
var or = SystemInformation.VirtualScreen;
foreach (DisplayInfo dm in dic)
{
int x = or.Left > 0 ? or.Left : -or.Left;
int y = or.Top > 0 ? or.Top : -or.Top;
if (dm.isPrimary)
{
Rect rect = new Rect();
rect.Left = x;
rect.Top = y;
rect.Right = rect.Left + dm.ScreenWidth;
rect.Bottom = rect.Top + dm.ScreenHeight;
dm.MonitorArea = rect;
}
else
{
Rect rect = new Rect();
rect.Left = x + dm.MonitorArea.Left;
rect.Top = y + dm.MonitorArea.Top;
rect.Right = rect.Left + dm.ScreenWidth;
rect.Bottom = rect.Top + dm.ScreenHeight;
dm.MonitorArea = rect;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。