Лучший способ скрыть окно от переключателя программ Alt-Tab?
Я был разработчиком .NET в течение нескольких лет, и это все еще одна из тех вещей, которые я не знаю, как правильно делать. Легко скрыть окно с панели задач через свойство как в Windows Forms, так и в WPF, но, насколько я могу судить, это не гарантирует (или обязательно даже влияет), что оно скрыто от Alt+↹ диалог. Я видел невидимка окна появляются в Alt+↹ и мне просто интересно, что это лучший способ гарантировать окно будет никогда появляются (видимые или нет) в Alt+↹ диалог.
обновление: пожалуйста, смотрите мое опубликованное решение ниже. Мне не разрешено отмечать свои собственные ответы как решение, но пока это единственный, который работает.
обновление 2:
13 ответов:
обновление:
согласно @donovan, modern days WPF поддерживает Это изначально, через настройку
ShowInTaskbar="False"
иVisibility="Hidden"
в XAML. (Я еще не проверял это, но тем не менее решил поднять видимость комментария)оригинальный ответ:
есть два способа скрыть окно от переключателя задач в Win32 API:
- добавить
WS_EX_TOOLWINDOW
расширенный стиль окна - это право подход.- чтобы сделать его дочерним окном другого окна.
к сожалению, WPF не поддерживает такой гибкий контроль над стилем окна, как Win32, поэтому окно с
WindowStyle=ToolWindow
заканчивается по умолчаниюWS_CAPTION
иWS_SYSMENU
стили, что заставляет его иметь заголовок и кнопку закрытия. С другой стороны, вы можете удалить эти два стиля, установивWindowStyle=None
, но это будет не то!--5--> расширенный стиль и окно не будут скрыты от переключатель задач.чтобы иметь окно WPF с
WindowStyle=None
это также скрыто от переключателя задач, можно одним из двух способов:
- перейдите к приведенному выше образцу кода и сделайте окно дочерним окном небольшого скрытого окна инструмента
- измените стиль окна, чтобы также включить
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" >
ничего особенного здесь, мы просто объявляем окно с
WindowStyle=None
иShowInTaskbar=False
. Мы также добавляем обработчик к загруженному событию, где мы будем изменять расширенный стиль окна. Мы не можем сделать эту работу в конструкторе, так как в этот момент еще нет дескриптора окна. Этот сам обработчик событий очень прост: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); }
и объявления взаимодействия Win32. Я удалил все ненужные стили из перечислений, просто чтобы сохранить пример кода здесь маленький. Кроме того, к сожалению
SetWindowLongPtr
точка входа не найдена в user32.dll на Windows XP, следовательно, трюк с маршрутизацией вызова через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
внутри класса формы добавьте следующее:
protected override CreateParams CreateParams { get { var Params = base.CreateParams; Params.ExStyle |= 0x80; return Params; } }
это так просто, как это; работает Шарм!
я нашел решение, но это не красиво. До сих пор это только что я пробовал, что на самом деле работает:
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
нашел здесь.
более общее, многоразовое решение было бы неплохо. Я полагаю, вы можете создать одно окно " w " и использовать его для всех окон в вашем приложении, которые должны быть скрыты от Alt+↹.
обновление: хорошо, так что я сделал это переместите приведенный выше код, минус
this.Owner = w
бита (и двигаясьw.Hide()
сразу послеw.Show()
, который отлично работает) в конструктор моего приложения, создавая публичный статическийWindow
под названиемOwnerWindow
. Всякий раз, когда я хочу, чтобы окно демонстрировало это поведение, я просто устанавливаюthis.Owner = App.OwnerWindow
. Работает отлично, и только включает в себя создание одного дополнительного (и невидимого) окна. Вы даже можете установитьthis.Owner = null
если вы хотите, чтобы окно вновь в Alt+↹ диалог.спасибо Иван Онучин перешел на форумы MSDN для решения.
обновление 2: вы также должны установить
ShowInTaskBar=false
onw
чтобы предотвратить его кратковременное мигание на панели задач при отображении.
зачем так сложно? Попробуйте это:
me.FormBorderStyle = FormBorderStyle.SizableToolWindow me.ShowInTaskbar = false
идея взята отсюда:http://www.csharp411.com/hide-form-from-alttab/
вот что делает трюк, независимо от стиля окна, которое вы пытаетесь скрыть от Alt+вкладка↹.
поместите следующее В конструкторе формы:
// Keep this program out of the Alt-Tab menu ShowInTaskbar = false; Form form1 = new Form ( ); form1.FormBorderStyle = FormBorderStyle.FixedToolWindow; form1.ShowInTaskbar = false; Owner = form1;
по существу, вы делаете свою форму дочерним элементом невидимого окна, которое имеет правильный стиль и настройку ShowInTaskbar, чтобы не попасть в список Alt-Tab. Необходимо также задать свойству ShowInTaskbar собственной формы значение false. Лучше всего, это просто не делает неважно, какой стиль имеет ваша основная форма, и все настройки для выполнения скрытия-это всего лишь несколько строк в коде конструктора.
почему так много кодов? Просто установите
FormBorderStyle
propety toFixedToolWindow
. Надеюсь, это поможет.
смотрите его: (от http://bytes.com/topic/c-sharp/answers/442047-hide-alt-tab-list#post1683880)
[DllImport("user32.dll")] public static extern int SetWindowLong( IntPtr window, int index, int value); [DllImport("user32.dll")] public static extern int GetWindowLong( IntPtr window, int index); const int GWL_EXSTYLE = -20; const int WS_EX_TOOLWINDOW = 0x00000080; const int WS_EX_APPWINDOW = 0x00040000; private System.Windows.Forms.NotifyIcon notifyIcon1; // I use two icons depending of the status of the app normalIcon = new Icon(this.GetType(),"Normal.ico"); alertIcon = new Icon(this.GetType(),"Alert.ico"); notifyIcon1.Icon = normalIcon; this.WindowState = System.Windows.Forms.FormWindowState.Minimized; this.Visible = false; this.ShowInTaskbar = false; iconTimer.Start(); //Make it gone frmo the ALT+TAB int windowStyle = GetWindowLong(Handle, GWL_EXSTYLE); SetWindowLong(Handle, GWL_EXSTYLE, windowStyle | WS_EX_TOOLWINDOW);
в XAML set ShowInTaskbar= "False":
<Window x:Class="WpfApplication5.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ShowInTaskbar="False" Title="Window1" Height="300" Width="300"> <Grid> </Grid> </Window>
Edit: это все еще показывает его в Alt+Tab я думаю, просто не в панели задач.
Я попытался установить видимость основной формы в false всякий раз, когда она автоматически изменяется на true:
private void Form1_VisibleChanged(object sender, EventArgs e) { if (this.Visible) { this.Visible = false; } }
он отлично работает :)
не показывать форму. Используйте невидимость.
подробнее здесь:http://code.msdn.microsoft.com/TheNotifyIconExample
Свойства Формы Form1:
FormBorderStyle: Sizable
WindowState: Свернуто
ShowInTaskbar: Falseprivate void Form1_Load(object sender, EventArgs e) { // Making the window invisible forces it to not show up in the ALT+TAB this.Visible = false; }>
Если вы хотите, чтобы форма была без полей, то вам нужно добавить следующие операторы в конструктор формы:
this.FormBorderStyle = FormBorderStyle.None; this.ShowInTaskbar = false;
и вы должны добавить следующий метод в производном классе форма:
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; // turn on WS_EX_TOOLWINDOW style bit cp.ExStyle |= 0x80; return cp; } }
лично, насколько я знаю, это невозможно без подключения к окнам каким-то образом, я даже не уверен, как это будет сделано или если это возможно.
в зависимости от ваших потребностей, разработка контекста приложения в качестве приложения NotifyIcon (system tray) позволит ему работать без отображения в ALT + TAB. Однако, если вы откроете форму, эта форма будет по-прежнему следовать стандартной функциональности.
Я могу откопать свою статью в блоге о создании приложение, которое является только NotifyIcon по умолчанию, если вы хотите.