Alt-Tab 프로그램 전환기에서 창을 숨기는 가장 좋은 방법은 무엇입니까?


101

나는 몇 년 동안 .NET 개발자로 일해 왔으며 이것은 여전히 ​​내가 제대로하는 방법을 모르는 것들 중 하나입니다. Windows Forms 및 WPF의 속성을 통해 작업 표시 줄에서 창을 숨기는 것은 쉽지만 내가 알 수있는 한 Alt+ ↹Tab대화 상자 에서 숨겨지는 것을 보장하거나 영향을 미치지는 않습니다 . 나는 본 적이 보이지 않는 창에 표시 Alt+ ↹Tab, 난 그냥하는 창을 보장하는 가장 좋은 방법이 무엇인지 궁금하네요 결코 에 (표시 여부) 표시되지 Alt+의 ↹Tab대화.

업데이트 : 아래 게시 된 솔루션을 참조하십시오. 내 답변을 해결책으로 표시 할 수는 없지만 지금까지 작동하는 유일한 답변입니다.

업데이트 2 : 이제 꽤 괜찮아 보이지만 직접 시도하지는 않은 Franci Penov의 적절한 솔루션이 있습니다. 일부 Win32를 포함하지만 화면 밖의 창을 제대로 생성하지 않습니다.


13
시스템 트레이 앱이 좋은 예입니다
— TravisO

3
내 앱이 UAC 대화 상자와 같은 모달 인터페이스를 표시 할 때 "디밍"효과를 제공하기 위해 전체 화면 반투명 검정색 창을 사용하기 때문에 한 가지 이유가 있습니다. 이것은 대화 형 창이 아니기 때문에 Alt-Tab 대화 상자에 표시 할 필요가 없습니다.
— devios1

8
앱이 자체 모달 대화 상자를 표시 할 때 전체 데스크톱을 어둡게하지 않는 것이 좋습니다. 바탕 화면을 어둡게하면 OS 수준 작동을 제안합니다. 대부분의 사람들은 안전한 데스크톱이 아니라는 것을 이해할 수있을만큼 충분한 지식을 얻지 못했을 것입니다.
— Franci Penov

3
"속성을 통해 작업 표시 줄에서 창을 숨기는 것은 쉽습니다." 이 속성은 ShowInTaskbar입니다 (레코드 용).
— greenoldman 2010 년

문제는 작업 표시 줄이 아닌 Alt-Tab에서 창을 숨기는 것입니다.
— Alexandru Dicu

답변:


93

최신 정보:

@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확장 된 스타일이 설정 되지 않고 창이 작업 전환기에서 숨겨지지 않습니다.

WindowStyle=None작업 전환기에서도 숨겨 지는 WPF 창을 가지려면 다음 두 가지 방법 중 하나를 사용할 수 있습니다.

  • 위의 샘플 코드를 사용하여 창을 작은 숨겨진 도구 창의 자식 창으로 만듭니다.
  • WS_EX_TOOLWINDOW확장 된 스타일 도 포함하도록 창 스타일을 수정합니다 .

개인적으로 두 번째 접근 방식을 선호합니다. 그런 다음 클라이언트 영역에서 유리를 확장하고 어쨌든 캡션에서 WPF 그리기를 활성화하는 것과 같은 고급 작업을 수행하므로 약간의 상호 운용성은 큰 문제가 아닙니다.

다음은 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" >

아무것도 너무 우리가 함께 창을 선언, 여기에 공상하지 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);
}

그리고 Win32 interop 선언. 샘플 코드를 작게 유지하기 위해 열거 형에서 불필요한 스타일을 모두 제거했습니다. 또한 불행히도 SetWindowLongPtrWindows 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

2
이것을 확인하지 않았지만 당신이 말하는 것을 아는 것 같습니다. :) 다시해야 할 경우 이것을 염두에 두겠습니다.하지만 다른 솔루션이 잘 작동하기 때문에 (그리고이 책에 대한 책을 닫은 지 한참이 지났습니다) 나는 뭔가를 망치고 깨뜨리고 싶지 않습니다. . 감사!
— devios1

1
완벽하게 작동합니다! 감사!
— Anthony Brien

나를 위해 잘 작동합니다. 그러나 나는 다음과 같이 dll을 가져와야하는 것을 싫어한다 : P
— J4N

8
@ J4N - :-) 땐 P / 호출의 비트와 함께이의 아무것도 잘못
— FRANCI Penov

1
이것은 WPF에서 나를 위해 작동하지 않았습니다. 하지만 놀아 본 후에는 XAML에서 ShowInTaskbar = "False"및 Visibility = "Hidden"을 설정하는 것이 훨씬 더 쉬운 해결책을 찾았습니다. 특별한 핀 보크가 필요하지 않습니다.
— donovan

40

양식 클래스 안에 다음을 추가하십시오.

protected override CreateParams CreateParams
{
    get
    {
        var Params = base.CreateParams;
        Params.ExStyle |= 0x80;

        return Params;
    }
}

그것만큼 쉽습니다. 매력을 발휘합니다!


3
이 작업을 수행하려면 ShowInTaskbar를 false로 설정해야합니다.
— Nick Spreitzer 2013 년

20

해결책을 찾았지만 예쁘지 않습니다. 지금까지 이것이 실제로 작동 하는 유일한 시도입니다.

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+ 에서 숨겨야하는 앱의 모든 창에 재사용 할 수 있다고 가정합니다 ↹Tab.

업데이트 : 좋아, 그래서 제가 한 것은 위의 코드를 이동했다, 마이너스 this.Owner = w(및 이동 비트 w.Hide()직후 w.Show()공공 정적 만들어 내 응용 프로그램의 생성자에 벌금을 작동) Window라는를 OwnerWindow. 창에서이 동작을 나타내 길 원할 때마다 간단히 this.Owner = App.OwnerWindow. 훌륭하게 작동하며 하나의 추가 (및 보이지 않는) 창만 생성하면됩니다. + 대화 상자 this.Owner = null에 창이 다시 나타나도록 설정할 수도 있습니다 .Alt↹Tab

솔루션에 대한 MSDN 포럼의 Ivan Onuchin에게 감사드립니다.

업데이트 2 : 당신은 설정해야합니다 ShowInTaskBar=false에 w표시 할 때 작업 표시 줄에서 잠시 깜박이는 것을 방지 할 수 있습니다.


이 문제에 대한 Win32 interop 솔루션도 있습니다.
— Franci Penov

흥미롭게도이 접근 방식을 사용하고 있지만 숨겨진 창 (주 앱 창을 소유자로 사용)을 피하고 Alt-Tab에 표시되지 않습니다.
— Dave

1
듀얼 모니터 구성에서 두 번째 화면도 음의 좌표를 가질 수 있다고 생각합니다.
— Thomas Weller 2014

@ThomasW. 당신 말이 맞을 것입니다. 오프셋을 사용하는 -100000것이 아마도 더 좋을 것입니다.
— devios1 2014

이것은이 문제에 대한 정말 나쁜 해킹입니다.
— Alexandru Dicu


10

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로 설정해야합니다. 무엇보다도 메인 폼의 스타일이 무엇인지는 중요하지 않으며, 숨김을 달성하기위한 모든 조정 작업은 생성자 코드에서 몇 줄이면됩니다.


잠깐 ... 이것은 C # 또는 C 또는 C ++ ??? 나는 정말 C 가족의 n00b입니다 ...
— Sreenikethan I

3

왜 그렇게 많은 코드를 시도합니까? FormBorderStyle속성을로 설정하십시오 FixedToolWindow. 도움이되기를 바랍니다.


2

그것을 참조하십시오 :( 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);

여기에 'Handle'이 var handle = new WindowInteropHelper (this) .Handle에 의해 획득 될 수 있다고 추가합니다.
— Alexandru Dicu

1

XAML에서 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>

편집 : 작업 표시 줄이 아닌 Alt + Tab에 여전히 표시됩니다.


예, 그게 문제입니다. ShowInTaskbar는 예상대로 Alt + Tab 대화 상자에 영향을주지 않습니다.
— devios1

1

자동으로 true로 변경 될 때마다 기본 양식의 가시성을 false로 설정하려고했습니다.

private void Form1_VisibleChanged(object sender, EventArgs e)
{
    if (this.Visible)
    {
        this.Visible = false;
    }
}

완벽하게 작동합니다 :)


2
가장 쉬운 솔루션 일뿐만 아니라 저에게도 매우 잘 작동했습니다.
— Daniel McQuiston

1

폼에 테두리가 없도록하려면 폼의 생성자에 다음 문을 추가해야합니다.

this.FormBorderStyle = FormBorderStyle.None;
this.ShowInTaskbar = false;

그리고 파생 된 Form 클래스에 다음 메서드를 추가해야합니다.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        // turn on WS_EX_TOOLWINDOW style bit
        cp.ExStyle |= 0x80;
        return cp;
    }
}

자세한 내용은



0

Form1 속성 :
FormBorderStyle : 크기 조정 가능한
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;
}>

-1

개인적으로 내가 아는 한 어떤 방식으로 창문에 연결하지 않고는 이것이 가능하지 않다. 나는 그것이 어떻게 될지 또는 가능한지조차 확신하지 못한다.

필요에 따라 애플리케이션 컨텍스트를 NotifyIcon (시스템 트레이) 애플리케이션으로 개발하면 ALT + TAB에 표시되지 않고 실행될 수 있습니다. 그러나 양식을 열면 해당 양식은 여전히 ​​표준 기능을 따릅니다.

원하는 경우 기본적으로 NotifyIcon 만있는 응용 프로그램을 만드는 방법에 대한 내 블로그 기사를 찾아 볼 수 있습니다.



저는 이미 NotifyIcons에 정통합니다. 감사합니다. 문제는 Alt + Tab에서 열려있는 (비대화 형 또는 최상위) 창을 숨기고 싶다는 것입니다. 흥미롭게도 Vista 사이드 바가 Alt + Tab에 표시되지 않는다는 것을 알았습니다. 그래서 몇 가지 방법이 있어야합니다.
— devios1

창 유형을 변경하지 않고 다양한 조각과 조각을 보면 (redbeard 게시 됨) 이렇게하는 방법을 모르겠습니다.
— Mitchel Sellers
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.