2018-4-15-WPF-at-Alt+Tab-hide window

title author date CreateTime categories WPF hide window in Alt+Tab lindexi 2018-04-15 10:13:40 +0800 201...
title author date CreateTime categories WPF hide window in Alt+Tab lindexi 2018-04-15 10:13:40 +0800 2018-3-1 11:32:9 +0800 WPF

Recently, we are developing a Toast window, because this window cannot be closed after display, because the user may keep the window displayed, so only Hide. But I will see this window in the switch window, so I found a way to make WPF window not display in the switch window.

Now, as long as the WPF program is set not to be displayed in the taskbar, and the window Visibility="Hidden" is set, it can not be displayed in the switching window. The setting method can be to add the following code in xaml

ShowInTaskbar="False" Visibility="Hidden"

But as you can see, if there is BitmapCache and a hidden window, the software cannot render after the screen is locked. Please see github , so don't use this method. So what else is there besides this method?

In fact, when switching between windows and not displaying windows, windows are required to be: WS_EX_TOOLWINDOW or other window's child window, but you can see that Toast is not a child window of other windows, so you can only set the window.

Because as long as the window is set to WS_EX_TOOLWINDOW will not be displayed in the switching window, so you need to use some special code.

First, get the window handle after the Load of the window. Note that it is not added after SourceInitialized

public ToastWindow() { InitializeComponent(); Loaded += ToastWindow_Loaded; }

Then use the code of hidden window in Load

private void HideAltTab() { var windowInterop = new WindowInteropHelper(this); var exStyle = GetWindowLong(windowInterop.Handle, GWL_EXSTYLE); exStyle |= WS_EX_TOOLWINDOW; Win32.SetWindowLong(windowInterop.Handle, GWL_EXSTYLE, exStyle); }

If you copy the above code directly, you can't run it, because you need to write several functions

The first function is ExtendedWindowStyles. Please see below. Actually, WS is used_ EX_ TOOLWINDOW

<script src=" https://gist.github.com/lindexi/21e4e640d53b3dcac3e6a6c69fc09db8.js"></script>

If you can't see the code above, look ExtendedWindowStyles code from msdn

#region Window styles public enum GetWindowLongFields { // ... GWL_EXSTYLE = (-20), // ... } [DllImport("user32.dll")] public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex); public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong) { int error = 0; IntPtr result = IntPtr.Zero; // Win32 SetWindowLong doesn't clear error on success SetLastError(0); if (IntPtr.Size == 4) { // use SetWindowLong Int32 tempResult = IntSetWindowLong(hWnd, nIndex, IntPtrToInt32(dwNewLong)); error = Marshal.GetLastWin32Error(); result = new IntPtr(tempResult); } else { // use SetWindowLongPtr result = IntSetWindowLongPtr(hWnd, nIndex, dwNewLong); error = Marshal.GetLastWin32Error(); } if ((result == IntPtr.Zero) && (error != 0)) { throw new System.ComponentModel.Win32Exception(error); } return result; } [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)] private static extern IntPtr IntSetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)] private static extern Int32 IntSetWindowLong(IntPtr hWnd, int nIndex, Int32 dwNewLong); private static int IntPtrToInt32(IntPtr intPtr) { return unchecked((int)intPtr.ToInt64()); } [DllImport("kernel32.dll", EntryPoint = "SetLastError")] public static extern void SetLastError(int dwErrorCode); #endregion

See: https://stackoverflow.com/a/551847/6116637

31 May 2020, 09:09 | Views: 6083

Add new comment

For adding a comment, please log in
or create account

0 comments