Лучший способ скрыть окно от переключателя программы Alt-Tab?

95
задан Andrii Omelchenko 16 August 2017 в 09:58
поделиться

9 ответов

Обновление:

Согласно @donovan, современные дни WPF поддерживает это исходно посредством установки ShowInTaskbar="False" и Visibility="Hidden" в XAML. (Я еще не протестировал это, но тем не менее решил ударить видимость комментария)

Исходный ответ:

существует два способа скрыть окно от переключателя задачи в Win32 API:

  1. для добавления WS_EX_TOOLWINDOW расширенный стиль окна - это - правильный подход.
  2. для создания этого дочерним окном другого окна.

, К сожалению, WPF не поддерживает как гибкое управление стилем окна как Win32, таким образом окно с WindowStyle=ToolWindow заканчивается со значением по умолчанию WS_CAPTION и WS_SYSMENU стили, который заставляет это иметь подпись и близкую кнопку. С другой стороны, можно удалить эти два стиля установкой WindowStyle=None, однако который не установит WS_EX_TOOLWINDOW, расширенный стиль и окно не будут скрыты от переключателя задачи.

, Чтобы иметь окно WPF с [1 111], который также скрыт от переключателя задачи, каждый может любой из двух путей:

  • идут с примером кода выше и делают окно, которое дочернее окно маленького скрытого окна инструментов
  • изменяет стиль окна, чтобы также включать WS_EX_TOOLWINDOW расширенный стиль.

я лично предпочитаю второй подход. С другой стороны я делаю некоторый усовершенствованный материал как расширение стекла в клиентской области и включении WPF, тянущий в подписи так или иначе, таким образом, определенные interop не являются большой проблемой.

Вот является пример кода для Win32 interop подходом решения. Во-первых, часть 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" >

Ничто также не полагает здесь, мы просто объявляем окно с [1 113] и 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);
    }

И Win32 interop объявления. Я удалил все ненужные стили из перечислений, только для хранения примера кода здесь маленьким. Кроме того, к сожалению, 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
88
ответ дан Franci Penov 24 November 2019 в 05:50
поделиться

Лично, насколько я знаю, что это не возможно, не сцепляясь в окна некоторым способом, я даже не уверен, как это было бы сделано или если это возможно.

В зависимости от Ваших потребностей, разрабатывая Ваш контекст приложения как NotifyIcon (системный лоток) приложение позволит ему работать, не показывая в ALT + ВКЛАДКА. ОДНАКО При открытии формы та форма будет все еще следовать за стандартной функциональностью.

я могу вскопать свою статью блога о создавании приложения, которое является ТОЛЬКО NotifyIcon по умолчанию, если Вы хотите.

-1
ответ дан Mitchel Sellers 24 November 2019 в 05:50
поделиться

Не показывайте форму. Используйте невидимость.

Больше здесь: http://code.msdn.microsoft.com/TheNotifyIconExample

0
ответ дан TheUberOverLord 24 November 2019 в 05:50
поделиться

В XAML устанавливает ShowInTaskbar = "Ложь":

<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>

Редактирование: Это все еще показывает его в Alt+Tab, который я предполагаю, просто не в панели задач.

1
ответ дан Philipp Schmid 24 November 2019 в 05:50
поделиться

Я нашел решение, но это не симпатично. До сих пор это [только 1 111] вещь, которую я попробовал, это на самом деле работает:

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' и снова использовать его для всех окон в Вашем приложении, которое должно быть скрыто от Высокого звука + в +№Tab .

Обновление: хорошо поэтому то, что я сделал, было переместить вышеупомянутый код, минус this.Owner = w бит (и перемещение w.Hide() сразу после w.Show(), который хорошо работает) в конструктора моего приложения, создавая общедоступные помехи Window названный OwnerWindow. Каждый раз, когда я хочу, чтобы окно показало это поведение, я просто установил this.Owner = App.OwnerWindow. Работает отлично, и только включает создание одного дополнительного (и невидимый) окно. Можно даже установить this.Owner = null, если Вы хотите, чтобы окно вновь появилось в Высоком звуке + в диалоговое окно +№Tab .

Благодаря Ivan Onuchin на форумах MSDN для решения.

Обновление 2: необходимо также установить ShowInTaskBar=false на w, чтобы препятствовать тому, чтобы он высветился кратко в панели задач, когда показано.

21
ответ дан Andrii Omelchenko 24 November 2019 в 05:50
поделиться

Свойства формы 1:
FormBorderStyle: Sizable
WindowState: свернутый
ShowInTaskbar: False

private void Form1_Load(object sender, EventArgs e)
{
   // Making the window invisible forces it to not show up in the ALT+TAB
   this.Visible = false;
}>
0
ответ дан 24 November 2019 в 05:50
поделиться

Почему так сложно? Попробуйте следующее:

me.FormBorderStyle = FormBorderStyle.SizableToolWindow
me.ShowInTaskbar = false

Идея взята отсюда: http://www.csharp411.com / hide-form-from-alttab /

10
ответ дан 24 November 2019 в 05:50
поделиться

Вот что делает трюк, независимо от стиля окна, которое вы пытаетесь скрыть от 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;

По сути, вы делаете вашу форму дочерней для невидимого окна, которое имеет правильный стиль и настройку ShowInTaskbar, чтобы не попасть в список Alt-Tab. Вы также должны установить свойство ShowInTaskbar вашей собственной формы в false. Лучше всего то, что не имеет значения, какой стиль имеет ваша главная форма, а вся настройка для выполнения скрытия - это всего несколько строк в коде конструктора.

8
ответ дан 24 November 2019 в 05:50
поделиться

см. Это: (из 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);
2
ответ дан 24 November 2019 в 05:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: