dev*_*os1 95 .net wpf alt-tab winforms
我已经成为.NET开发人员已有好几年了,这仍然是我不知道如何正确完成的事情之一.通过Windows窗体和WPF中的属性很容易从任务栏隐藏窗口,但据我所知,这并不能保证(或必然会影响)它从Alt+ ↹Tab对话框中隐藏.我已经看到隐形窗口显示在Alt+中↹Tab,我只是想知道什么是保证窗口永远不会出现(可见或不可见)Alt+ ↹Tab对话框的最佳方法.
更新:请参阅下面我发布的解决方案.我不允许将自己的答案标记为解决方案,但到目前为止,它是唯一有效的解决方案.
更新2:弗朗西·佩诺夫现在有一个看起来很不错的正确解决方案,但我自己没有尝试过.涉及一些Win32,但避免了屏幕外窗口的蹩脚创建.
Fra*_*nov 88
更新:
根据@donovan,现代WPF通过设置ShowInTaskbar="False"和Visibility="Hidden"XAML 本地支持这一点
.(我还没有对此进行测试,但仍然决定提高评论的可见性)
原始答案:
在Win32 API中有两种方法可以从任务切换器隐藏窗口:
WS_EX_TOOLWINDOW扩展窗口样式 - 这是正确的方法.不幸的是,WPF不支持像Win32一样灵活地控制窗口样式,因此窗口WindowStyle=ToolWindow最后会显示默认WS_CAPTION和WS_SYSMENU样式,这会导致它有一个标题和一个关闭按钮.另一方面,您可以通过设置删除这两种样式WindowStyle=None,但是不会设置WS_EX_TOOLWINDOW扩展样式,并且不会从任务切换器隐藏窗口.
要WindowStyle=None在任务切换器中隐藏一个带有WPF窗口的WPF窗口,可以采用以下两种方式之一:
WS_EX_TOOLWINDOW扩展样式.我个人更喜欢第二种方法.然后,我做了一些高级的事情,比如在客户区扩展玻璃并在标题中启用WPF绘图,所以一点点互操作不是一个大问题.
这是Win32互操作解决方案方法的示例代码.首先,XAML部分:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300"
ShowInTaskbar="False" WindowStyle="None"
Loaded="Window_Loaded" >
Run Code Online (Sandbox Code Playgroud)
这里没什么太花哨的,我们只是用WindowStyle=None和声明一个窗口ShowInTaskbar=False.我们还为Loaded事件添加了一个处理程序,我们将修改扩展窗口样式.我们不能在构造函数中完成这项工作,因为那时还没有窗口句柄.事件处理程序本身非常简单:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WindowInteropHelper wndHelper = new WindowInteropHelper(this);
int exStyle = (int)GetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE);
exStyle |= (int)ExtendedWindowStyles.WS_EX_TOOLWINDOW;
SetWindowLong(wndHelper.Handle, (int)GetWindowLongFields.GWL_EXSTYLE, (IntPtr)exStyle);
}
Run Code Online (Sandbox Code Playgroud)
和Win32互操作声明.我已从枚举中删除了所有不必要的样式,只是为了使示例代码保持较小.此外,遗憾的SetWindowLongPtr是,在Windows XP上的user32.dll中找不到入口点,因此通过SetWindowLong而不是路由调用.
#region Window styles
[Flags]
public enum ExtendedWindowStyles
{
// ...
WS_EX_TOOLWINDOW = 0x00000080,
// ...
}
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
Run Code Online (Sandbox Code Playgroud)
Dan*_*ett 38
在表单类中,添加以下内容:
protected override CreateParams CreateParams
{
get
{
var Params = base.CreateParams;
Params.ExStyle |= 0x80;
return Params;
}
}
Run Code Online (Sandbox Code Playgroud)
就这么简单; 有魅力!
dev*_*os1 21
我找到了一个解决方案,但它并不漂亮.到目前为止,这是我尝试过的唯一可行的方法:
Window w = new Window(); // Create helper window
w.Top = -100; // Location of new window is outside of visible part of screen
w.Left = -100;
w.Width = 1; // size of window is enough small to avoid its appearance at the beginning
w.Height = 1;
w.WindowStyle = WindowStyle.ToolWindow; // Set window style as ToolWindow to avoid its icon in AltTab
w.Show(); // We need to show window before set is as owner to our main window
this.Owner = w; // Okey, this will result to disappear icon for main window.
w.Hide(); // Hide helper window just in case
Run Code Online (Sandbox Code Playgroud)
在这里找到它.
更通用,可重复使用的解决方案会很好.我想你可以创建一个单独的窗口'w',并将其重用于应用程序中需要隐藏Alt+的所有窗口↹Tab.
更新:好了,所以我所做的就是移动上面的代码,减去this.Owner = w位(和移动w.Hide()后w.Show(),其正常工作)到我的应用程序的构造,建立一个公共静态Window叫OwnerWindow.每当我想要一个窗口展示这种行为时,我只需设置this.Owner = App.OwnerWindow.效果很好,只涉及创建一个额外(和不可见)窗口.您甚至可以设置this.Owner = null是否要在Alt+ ↹Tab对话框中重新显示该窗口.
感谢Ivan Onuchin在MSDN论坛上的解决方案.
更新2:您还应该ShowInTaskBar=false启用w以防止它在显示时在任务栏中短暂闪烁.
小智 10
为什么这么复杂?试试这个:
me.FormBorderStyle = FormBorderStyle.SizableToolWindow
me.ShowInTaskbar = false
Run Code Online (Sandbox Code Playgroud)
从这里获取的想法:http://www.csharp411.com/hide-form-from-alttab/
小智 8
下面是什么呢,无论你正试图从隐藏窗口的风格的伎俩,Alt+ ↹Tab.
将以下内容放入表单的构造函数中:
// Keep this program out of the Alt-Tab menu
ShowInTaskbar = false;
Form form1 = new Form ( );
form1.FormBorderStyle = FormBorderStyle.FixedToolWindow;
form1.ShowInTaskbar = false;
Owner = form1;
Run Code Online (Sandbox Code Playgroud)
基本上,您使表单成为不可见窗口的子窗口,该窗口具有正确的样式和ShowInTaskbar设置,以使其不在Alt-Tab列表之外.您还必须将自己的表单的ShowInTaskbar属性设置为false.最重要的是,它与您的主要表单的样式无关,并且完成隐藏的所有调整只是构造函数代码中的几行.
| 归档时间: |
|
| 查看次数: |
52213 次 |
| 最近记录: |