Der beste Weg, um ein Fenster aus dem Alt-Tab-Switcher Programm zu verbergen?
Frage
Ich bin jetzt ein .NET Entwickler für mehrere Jahre und das ist immer noch eines der Dinge, ich weiß nicht, wie man richtig zu tun. Es ist einfach, ein Fenster aus der Taskleiste über eine Eigenschaft in Windows Forms und WPF zu verstecken, aber soweit ich das beurteilen kann, dies nicht gewährleistet (oder notwendigerweise selbst beeinflussen) aus dem versteckt Alt + ↹Tab Dialog. Ich habe gesehen unsichtbar Fenster zeigen sich in Alt + ↹Tab , und ich frage mich nur, was der beste Weg ist, um ein Fenster zu garantieren wird nie angezeigt (sichtbar oder nicht) in die Alt + ↹Tab Dialog.
Update: Bitte sehen unten meine gepostete Lösung. Ich durfte nicht auf meine eigene Frage-Antwort als die Lösung markieren, aber bisher ist es das einzige, das funktioniert.
Update 2: Es gibt jetzt eine richtige Lösung von Franci Penov, die ziemlich gut aussieht, haben aber es selbst nicht ausprobiert. Bezieht einige Win32, vermeidet aber die Lahmen Schaffung von Off-Screen-Fenster.
Lösung
Update:
Nach @donovan, unterstützt moderne Tage WPF diese nativ durch Einstellung
ShowInTaskbar="False"
und Visibility="Hidden"
in der XAML. (Ich habe dies noch nicht getestet, aber wir entschieden uns dennoch den Kommentar Sichtbarkeit zu stoßen)
Original Antwort:
Es gibt zwei Möglichkeiten, ein Fenster aus der Task Switcher in Win32 API versteckt:
- die
WS_EX_TOOLWINDOW
erweiterten Fensterstil hinzufügen -. Das ist der richtige Ansatz - , um es ein untergeordnetes Fenster von einem anderen Fenster.
Leider WPF nicht als flexible Kontrolle über den Fensterstil als Win32 unterstützt, damit ein Fenster mit WindowStyle=ToolWindow
endet mit dem Standard WS_CAPTION
und WS_SYSMENU
Arten auf, die es eine Beschriftung und eine Schließen-Schaltfläche haben verursacht. Auf der anderen Seite, können Sie diese beiden Arten von WindowStyle=None
Einstellung jedoch entfernen, die nicht den WS_EX_TOOLWINDOW
erweiterten Stil und das Fenster ausgeblendet wird, nicht von der Task Switcher eingestellt werden.
Um ein WPF-Fenster mit WindowStyle=None
zu haben, die auch von der Task Switcher verborgen ist, kann man auf zwei Arten:
- mit dem Beispielcode oben gehen und das Fenster ein Kind Fenster eines kleinen versteckten Tool-Fenster machen
- Ändern Sie den Fensterstil auch die
WS_EX_TOOLWINDOW
erweitert Stil gehören.
Ich persönlich bevorzuge den zweiten Ansatz. Dann wieder, ich einige erweiterte Sachen wie Verlängerung des Glas im Client-Bereich und ermöglicht WPF in der Beschriftung Zeichnung sowieso, also ein wenig Interop kein großes Problem ist.
Hier ist der Beispielcode für den Win32-Interop-Lösungsansatz. Zunächst wird der XAML Teil:
<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" >
Nichts Besonderes hier, erklären wir nur ein Fenster mit WindowStyle=None
und ShowInTaskbar=False
. Wir fügen auch einen Handler an das Loaded-Ereignis, wo wir den erweiterten Fensterstil ändern wird. Wir können, dass die Arbeit im Konstruktor nicht tun, da es noch an diesem Punkt keinen Fenstergriff ist. Der Event-Handler selbst ist sehr einfach:
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);
}
Und die Win32 Interop Erklärungen. Ich habe alle nicht benötigte Stile aus den Aufzählungen entfernt, nur den Beispielcode zu halten hier klein. Leider auch die SetWindowLongPtr
Einstiegspunkt nicht in user32.dll unter Windows XP gefunden, daher der Trick mit Weiterleitung des Anrufs durch die SetWindowLong
statt.
#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
Andere Tipps
In Ihrer Formularklasse, fügen Sie diese:
protected override CreateParams CreateParams
{
get
{
var Params = base.CreateParams;
Params.ExStyle |= 0x80;
return Params;
}
}
Es ist so einfach wie das; arbeitet ein Charme!
Ich habe eine Lösung gefunden, aber es ist nicht schön. Bisher ist dies die nur , was ich versucht habe, dass tatsächlich funktioniert:
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
Found it hier .
Ein allgemeineres würde wieder verwendbare Lösung schön. Ich nehme an, Sie könnten ein einzelnes Fenster 'w' erstellen und es für alle Fenster in Ihrer Anwendung wiederverwenden, die von der Alt + ↹Tab .
versteckt werden müssen, Update: Ok, so was ich tat, war den obigen Code bewegen, abzüglich der this.Owner = w
Bit (und w.Hide()
unmittelbar nach w.Show()
bewegen, der gut arbeitet) meine Anwendung Konstruktor in eine öffentliche statische Window
Schaffung genannt OwnerWindow
. Jedes Mal, wenn ich ein Fenster will dieses Verhalten zeigen, habe ich einfach this.Owner = App.OwnerWindow
. Arbeiten groß und beinhaltet nur ein extra (und unsichtbar) Fenster zu schaffen. Sie können sogar einstellen this.Owner = null
, wenn Sie das Fenster wollen in die Alt + wieder zu erscheinen ↹Tab Dialog.
Dank Ivan Onuchin über auf MSDN-Foren für die Lösung.
Aktualisieren. 2: Sie sollten auch ShowInTaskBar=false
auf w
gesetzt, damit er nicht kurz in der Taskleiste zu blinken, wenn gezeigt
Warum so kompliziert? Versuchen Sie folgendes:
me.FormBorderStyle = FormBorderStyle.SizableToolWindow
me.ShowInTaskbar = false
Idee von hier genommen: http://www.csharp411.com/hide -Form-from-AltTab /
Hier ist, was der Trick funktioniert, unabhängig von der Art des Fensters Ihr aus zu verbergen versuchen Alt + ↹Tab .
Setzen Sie den folgenden in den Konstruktor des Formulars:
// Keep this program out of the Alt-Tab menu
ShowInTaskbar = false;
Form form1 = new Form ( );
form1.FormBorderStyle = FormBorderStyle.FixedToolWindow;
form1.ShowInTaskbar = false;
Owner = form1;
Im Wesentlichen Sie Ihr Formular ein Kind von einem unsichtbaren Fenster machen, die den korrekten Stil hat und ShowInTaskbar Einstellung aus der Alt-Tab-Liste zu halten. Sie müssen auch Ihre eigene Form der ShowInTaskbar Eigenschaft auf false gesetzt. Das Beste von allem, es ist einfach keine Rolle, welche Art Ihre Hauptform hat, und alles Tweaking das Versteck zu erreichen, ist nur ein paar Zeilen im Konstruktor Code.
Warum versuchen so viel Codes?
Gerade die FormBorderStyle
Eigenschaft auf FixedToolWindow
.
Hoffe, es hilft.
es: (von 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);
In XAML festlegen 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:. Das zeigt immer noch in Alt + Tab Ich denke, nur nicht in der Taskleiste
Ich habe versucht, das Hauptformular Sichtbarkeit auf false setzen, wenn es automatisch auf true geändert wird:
private void Form1_VisibleChanged(object sender, EventArgs e)
{
if (this.Visible)
{
this.Visible = false;
}
}
Es funktioniert perfekt:)
Sie zeigen kein Formular. Verwenden Sie Unsichtbarkeit.
Mehr hier: http://code.msdn.microsoft.com/TheNotifyIconExample
Form1 Eigenschaften:
Formborderstyle: Sizable
Window: Minimierte
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;
}>
Wenn Sie das Formular sein randlos wollen, dann müssen Sie die Form der Konstruktor die folgenden Anweisungen hinzufügen:
this.FormBorderStyle = FormBorderStyle.None;
this.ShowInTaskbar = false;
und Sie müssen die folgende Methode der abgeleiteten Form-Klasse hinzufügen:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
// turn on WS_EX_TOOLWINDOW style bit
cp.ExStyle |= 0x80;
return cp;
}
}
Persönlich soweit ich weiß, dass dies ohne Einhaken in Fenster in irgendeiner Art und Weise nicht möglich ist, ich bin nicht einmal sicher, wie das geschehen würde, oder wenn es möglich ist.
Je nach Bedarf, die Entwicklung Ihrer Anwendungskontext als NotifyIcon (System Tray) Anwendung ermöglicht es, ohne dafür in ALT + TAB, um zu laufen. wenn Sie ein Formular JEDOCH öffnen, wird diese Form noch die Standardfunktionalität folgen.
Ich kann mein Blog-Artikel über das Erstellen einer Anwendung, graben, dass nur ein NotifyIcon standardmäßig ist, wenn Sie wollen.