所以已經有關于這個主題的各種問題(從 4 到 5 年前),我已經按照他們提出了以下解決方案,以避免我的視窗對 Win D(顯示桌面)命令做出反應:
public partial class MainWindow : Window
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hP, IntPtr hC, string sC, string sW);
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public MainWindow()
{
InitializeComponent();
Loaded = OnWindowLoaded;
}
private void OnWindowLoaded(object sender, RoutedEventArgs e)
{
IntPtr nWinHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Progman", null);
nWinHandle = FindWindowEx(nWinHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
SetParent(new WindowInteropHelper(this).Handle, nWinHandle);
}
}
但是,這似乎對我不起作用(上面的代碼在一個全新的專案中)。
任何人都可以解釋 WinAPI 是否有任何更改,這是否仍然有效?這是我在幾乎所有關于這個主題的問題上遇到的答案。
我在跑步:
- 版本:Windows 10 專業版
- 版本:21H2
- 構建:19044.1645
- 體驗:Windows 功能體驗包 120.2212.4170.0,
uj5u.com熱心網友回復:
好的,所以我找到了適合我的解決方案,我知道將視窗設定為桌面的子視窗有其問題/風險,但對于仍然需要這樣做的人,這是我發現的:
“SHELLDLL_DefView”桌面視窗并不總是“Progman”的子視窗,有時它是“WorkerW”視窗的子視窗。這就是為什么我原來的問題中的代碼對我不起作用的原因。
因此,您無需找到“Progman”視窗并找到“SHELLDLL_DefView”子視窗,而是需要列舉所有視窗并找到具有“SHELLDLL_DefView”作為子視窗的視窗。
這是通過EnumWindows函式 ( https://www.pinvoke.net/default.aspx/user32.enumwindows )完成的
下面的代碼是上面 pinvoke.net 鏈接中的一個示例和以下 2 個答案的混搭:
- https://stackoverflow.com/a/60856252/9420881
- https://stackoverflow.com/a/66832500/9420881
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hP, IntPtr hC, string sC,
string sW);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumWindows(EnumedWindow lpEnumFunc, ArrayList
lParam);
public delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles);
public static bool GetWindowHandle(IntPtr windowHandle, ArrayList
windowHandles)
{
windowHandles.Add(windowHandle);
return true;
}
private void SetAsDesktopChild()
{
ArrayList windowHandles = new ArrayList();
EnumedWindow callBackPtr = GetWindowHandle;
EnumWindows(callBackPtr, windowHandles);
foreach (IntPtr windowHandle in windowHandles)
{
IntPtr hNextWin = FindWindowEx(windowHandle, IntPtr.Zero,
"SHELLDLL_DefView", null);
if (hNextWin != IntPtr.Zero)
{
var interop = new WindowInteropHelper(_window);
interop.EnsureHandle();
interop.Owner = hNextWin;
}
}
}
現在,我的 WPF 在按預期顯示桌面/Win D 后保留在桌面上。
uj5u.com熱心網友回復:
有一些 Windows 操作不能被開發者覆寫,例如:
- 始終在主任務欄上顯示托盤圖示
- 覆寫 Win D 以始終在桌面上顯示您的視窗
- 強制通知始終顯示
這些是 Windows 作業系統的策略,以確保用戶始終處于控制之中,而不是開發人員。
話雖如此,您可以嘗試另一種方法來使您的“小部件”可見。我可以建議以下內容:
- 創建一個 1 秒的System.Threading.Timer
- 在計時器的回呼中,檢查是否有任何可見的桌面視窗。如果沒有(即由于 Win D 或用戶只是關閉/最小化每個視窗),則使您的小部件視窗可見。
在我看來,顯示小部件的 1 秒延遲對您的 UX 來說是一筆不小的開銷。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/462549.html
