正如您在影像中看到的,我想在 Launch 視窗(即 WinForms 應用程式)的位置打開一個固定大小的 WPF 視窗。如何確保將要打開的 WPF 視窗放置在該啟動視窗的任何一側完全可見的位置。Windows 桌面的右鍵選單中也有類似的行為,就好像您單擊螢屏的最邊緣,它會在左側打開背景關系選單,如果您在螢屏中間,它會打開任一側。
我已經嘗試了一些事情,而且這個 SO 答案也是,但仍在弄清楚如何計算 Windows 的邊界,使其在可見區域內。

uj5u.com熱心網友回復:
該程序將是:
- 使用其句柄獲取視窗的矩形。
- 獲取視窗所在的監視器的句柄。
- 使用其句柄獲取監視器的資訊(特別是作業區域的矩形)。
- 計算可用空間的方向。
using System;
using System.Runtime.InteropServices;
public enum Direction { None, TopLeft, TopRight, BottomRight, BottomLeft }
public static class WindowHelper
{
public static Direction GetAvailableDirection(IntPtr windowHandle)
{
if (!GetWindowRect(windowHandle, out RECT buffer))
return Direction.None;
System.Drawing.Rectangle windowRect = buffer;
IntPtr monitorHandle = MonitorFromWindow(windowHandle, MONITOR_DEFAULTTO.MONITOR_DEFAULTTONULL);
if (monitorHandle == IntPtr.Zero)
return Direction.None;
MONITORINFO info = new() { cbSize = (uint)Marshal.SizeOf<MONITORINFO>() };
if (!GetMonitorInfo(monitorHandle, ref info))
return Direction.None;
System.Drawing.Rectangle workingAreaRect = info.rcWork;
bool isWindowAlignedTop = (windowRect.Top - workingAreaRect.Top) < (workingAreaRect.Bottom - windowRect.Bottom);
bool isWindowAlignedLeft = (windowRect.Left - workingAreaRect.Left) < (workingAreaRect.Right - windowRect.Right);
return (isWindowAlignedTop, isWindowAlignedLeft) switch
{
(true, true) => Direction.BottomRight,
(true, false) => Direction.BottomLeft,
(false, true) => Direction.TopRight,
(false, false) => Direction.TopLeft
};
}
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(
IntPtr hWnd,
out RECT lpRect);
[DllImport("User32.dll")]
private static extern IntPtr MonitorFromWindow(
IntPtr hwnd,
MONITOR_DEFAULTTO dwFlags);
private enum MONITOR_DEFAULTTO : uint
{
MONITOR_DEFAULTTONULL = 0x00000000,
MONITOR_DEFAULTTOPRIMARY = 0x00000001,
MONITOR_DEFAULTTONEAREST = 0x00000002,
}
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetMonitorInfo(
IntPtr hMonitor,
ref MONITORINFO lpmi);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct MONITORINFO
{
public uint cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public static implicit operator System.Drawing.Rectangle(RECT rect)
{
return new System.Drawing.Rectangle(
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top);
}
}
}
請注意,呼叫應用程式必須有一個應用程式清單,其中包括 DPI 意識以便正確計算。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/448336.html
上一篇:WPF中的EventHandler-一個元素的更改會影響另一個元素
下一篇:在MVVM中處理事件
