我正在开发一个C#VSTO Excel加载项,并且有一些功能可以在单击功能区按钮后启动WPF窗口。
我有这个窗口,我将高度设置为屏幕高度的80%,宽度为屏幕宽度的60%。但是,如果用户将其DPI设置为超过100%,则此操作无效,我的WPF窗口将在其屏幕可视区域之外增长。
所以,在做了一些谷歌搜索后,我发现我必须考虑缩放因子到我的计算中。我指的是How to get Windows Display settings?来获取比例因子。
我的问题是,有更简单的方法吗?在Javascript / CSS中,我们可以使用80vh和60vw,但到目前为止,我没有在C#中看到这样有用的功能。
我觉得我必须编写代码来处理这些场景,而不是仅仅有一个代码来计算我想要的窗口大小相对于屏幕大小,这是荒谬的。
这是我现在的代码:
var scaleFactor = GetScalingFactor();
var handle = (IntPtr) Application.Hwnd;
var screen = Screen.FromHandle(handle);
var winHeight = screen.WorkingArea.Height * scaleFactor * 0.8;
var winWidth = screen.WorkingArea.Width * scaleFactor * 0.6;
private static float GetScalingFactor()
{
var g = Graphics.FromHwnd(IntPtr.Zero);
var desktop = g.GetHdc();
var xDpi = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSX);
return 96 / (float) xDpi;
}
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
public enum DeviceCap
{
VERTRES = 10,
DESKTOPVERTRES = 117,
/// <summary>
/// Logical pixels inch in X
/// </summary>
LOGPIXELSX = 88,
/// <summary>
/// Logical pixels inch in Y
/// </summary>
LOGPIXELSY = 90
// http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
}
答案 0 :(得分:0)
你问题的有趣部分是你希望这很简单。 您可以将设备独立像素计算为特定显示器上的乘数并应用它。
我的设置为125%,这给了我.8:
Matrix m = PresentationSource.FromVisual(fe)
.CompositionTarget.TransformToDevice;
double dpiFactor = 1 / m.M11;
另一种方法是最初使窗口最大化。 渲染完成后,您知道这将大大超出显示器的大小,您可以获得窗口的实际宽度和实际高度。 然后计算* .8和* .6,大致给出你想要的尺寸。 我认为这对你的目的来说已经足够了,没有人在他们的监视器上拿这个标尺。由于窗口镀铬和最大化会产生细微差别,这会因操作系统而异。希望这是学术性的。
如果您不喜欢窗户跳跃,那么您可以将其变成动画功能。 使窗口透明,最初没有样式。 在居中的网格中显示内容。 将高度和宽度设置为您计算的大小。 然后设置窗口的大小。 不要为窗户的高度和宽度设置动画。 (它先做一个然后做另一个。)