Alt-Tab प्रोग्राम स्विचर से विंडो छिपाने का सबसे अच्छा तरीका है?


101

मैं कई वर्षों से .NET डेवलपर हूं और यह अभी भी उन चीजों में से एक है, जिन्हें मैं ठीक से नहीं जानता। विंडोज फॉर्म और डब्ल्यूपीएफ दोनों में एक संपत्ति के माध्यम से टास्कबार से एक खिड़की को छिपाना आसान है, लेकिन जहां तक ​​मैं बता सकता हूं, यह Alt+ ↹Tabसंवाद से छिपाए जाने की गारंटी नहीं देता (या आवश्यक रूप से प्रभावित भी करता है) । मैंने अदृश्य विंडो को Alt+ में दिखाया है ↹Tab, और मैं बस सोच रहा हूं कि एक विंडो की गारंटी देने का सबसे अच्छा तरीका क्या है + डायलॉग में कभी दिखाई नहीं देगा (दिखाई नहीं देगा) ।Alt↹Tab

अपडेट: कृपया मेरे पोस्ट किए गए समाधान को नीचे देखें। मुझे समाधान के रूप में अपने स्वयं के उत्तरों को चिह्नित करने की अनुमति नहीं है, लेकिन अभी तक यह केवल एक ही है जो काम करता है।

अपडेट 2: फ्रैंकी पेनोव द्वारा अब एक उचित समाधान है जो बहुत अच्छा लग रहा है, लेकिन इसे खुद से बाहर करने की कोशिश नहीं की है। कुछ Win32 को शामिल करता है, लेकिन ऑफ-स्क्रीन विंडोज़ के लंगड़ा निर्माण से बचा जाता है।


13
सिस्टम ट्रे ऐप एक बेहतरीन उदाहरण हैं
ट्रैविसो

3
मैं इसे एक कारण से करना चाहता हूं क्योंकि मैं एक "डिमिंग" प्रभाव प्रदान करने के लिए फुल-स्क्रीन सेमीट्रांसपेरेंट ब्लैक विंडो का उपयोग करता हूं, जब मेरा ऐप एक मॉडल इंटरफ़ेस, यूएसी डायलॉग की तरह प्रदर्शित कर रहा है। चूंकि यह एक इंटरेक्टिव विंडो नहीं है, इसलिए Alt-Tab संवाद में इसे दिखाने का कोई मतलब नहीं है।
devios1 19

8
जब आपका ऐप अपना स्वयं का संवाद दिखाता है, तो मैं पूरे डेस्कटॉप को डिम करने के खिलाफ सुझाव दूंगा। डेस्कटॉप को छोटा करना एक ओएस स्तर के संचालन का सुझाव देता है। अधिकांश लोगों को यह समझने में पर्याप्त ज्ञान नहीं होगा कि वह सुरक्षित डेस्कटॉप नहीं है।
फ्रैंकी पेनोव

3
"एक संपत्ति के माध्यम से टास्कबार से एक खिड़की को छिपाना आसान है"। यह संपत्ति ShowInTaskbar (सिर्फ रिकॉर्ड के लिए) है।
ग्रीनल्डमैन

सवाल Alt-Tab से विंडो को छिपाने के बारे में है, टास्कबार से नहीं।
अलेक्जेंड्रू डिकु

जवाबों:


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विस्तारित शैली सेट नहीं करेगा और विंडो को कार्य स्विचर से छिपाया नहीं जाएगा।

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 में नहीं मिला है, इसलिए 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
अच्छी तरह से काम! धन्यवाद!
एंथनी ब्रायन

मेरे लिए अच्छा काम करता है। लेकिन मुझे इस तरह dll आयात करने से नफरत है: P
J4N

8
@ J4N - पी / बिट के साथ कुछ भी गलत नहीं है हर बार और फिर आह्वान करें :-)
फ्रैंकी पेनो

1
यह मेरे लिए WPF में काम नहीं किया। लेकिन चारों ओर खेलने के बाद मुझे एक बहुत आसान समाधान मिला शोएटस्कैबर = "गलत" और दृश्यता = एक्सएएमएल में "हिडन" सेट करना। कोई विशेष पिनवोक की आवश्यकता नहीं है।
डोनोवन

40

अपनी फॉर्म क्लास के अंदर, इसे जोड़ें:

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

        return Params;
    }
}

यह उतना ही आसान है; एक आकर्षण काम करता है!


3
इसके अलावा काम करने के लिए ShowInTaskbar को गलत पर सेट करने की आवश्यकता है।
निक स्पेरित्जर

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

यहां मिला ।

एक अधिक सामान्य, पुन: प्रयोज्य समाधान अच्छा होगा। मुझे लगता है कि आप एक एकल विंडो 'डब्ल्यू' बना सकते हैं और इसे अपने ऐप की सभी खिड़कियों के लिए पुन: उपयोग कर सकते हैं जिन्हें Alt+ से छिपाए जाने की आवश्यकता है ↹Tab

अद्यतन: ठीक है तो क्या मैंने किया था इसके बाद के संस्करण कोड को स्थानांतरित किया गया था, शून्य से this.Owner = wबिट (और चलती w.Hide()के तुरंत बाद w.Show(), जो ठीक काम करता है) अपने आवेदन के निर्माता में, एक सार्वजनिक स्थिर बनाने Windowबुलाया OwnerWindow। जब भी मुझे इस व्यवहार को प्रदर्शित करने के लिए एक विंडो चाहिए, मैं बस सेट करता हूं this.Owner = App.OwnerWindow। महान काम करता है, और केवल एक अतिरिक्त (और अदृश्य) विंडो बनाना शामिल है। आप यह भी सेट कर सकते हैं this.Owner = nullयदि आप चाहते हैं कि विंडो Alt+ ↹Tabडायलॉग में फिर से दिखाई दे ।

समाधान के लिए MSDN मंचों पर इवान ओचुचिन के लिए धन्यवाद।

अद्यतन 2: आप यह भी तय करना चाहिए ShowInTaskBar=falseपर wयह जब से पता चला टास्कबार में संक्षेप में चमकती से रोकने के लिए।


वहाँ भी है कि समस्या के लिए Win32 इंटरॉप समाधान।
फ्रैंकी पेनोव

दिलचस्प है, मैं यह दृष्टिकोण कर रहा हूं लेकिन छिपी हुई खिड़की (मालिक के रूप में मुख्य ऐप विंडो का उपयोग करके) से परहेज कर रहा हूं, और यह Alt-Tab में दिखाई नहीं दे रहा है ...
डेव

1
मुझे लगता है कि दोहरे मॉनिटर कॉन्फ़िगरेशन पर, दूसरी स्क्रीन में भी नकारात्मक निर्देशांक हो सकते हैं।
थॉमस वेलर

@ThomasW। शायद तुम सही हो। जैसे ऑफसेट का उपयोग -100000करना शायद बेहतर होगा।
devios1

यह वास्तव में इस समस्या के लिए एक बुरा हैक है।
अलेक्जेंड्रू डिकु

10

इतना जटिल क्यों? इसे इस्तेमाल करे:

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

यहाँ से लिया गया आइडिया: http://www.csharp411.com/hide-form-from-alttab/


मेरे लिये कार्य करता है। योगदान के लिए धन्यवाद!
MiBol

लेकिन टूलविंडो को अधिकतम या न्यूनतम नहीं किया जा सकता है। टूलविंडो हमेशा एक बेहतर विकल्प नहीं होता है।
अलेक्जेंड्रू डिकु

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;

अनिवार्य रूप से, आप अपने फॉर्म को एक अदृश्य खिड़की का एक बच्चा बनाते हैं जिसमें सही शैली है और Alt-Tab सूची से बाहर रखने के लिए ShowInTaskbar सेटिंग है। आपको अपने स्वयं के फॉर्म को ShowInTaskbar संपत्ति को असत्य पर सेट करना होगा। सबसे अच्छी बात यह है कि बस इस बात से कोई फर्क नहीं पड़ता कि आपके मुख्य रूप में क्या शैली है, और छुपाने के लिए सभी को पूरा करना कंस्ट्रक्टर कोड में कुछ पंक्तियाँ हैं।


रुको ... यह एक सी # या सी या सी ++ है ??? मैं वास्तव में C परिवार में n00b हूं या जो भी हो ...
श्रीनिकेतन 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);

मैं यहाँ जोड़ना चाहूँगा कि 'हैंडल' को var हैंडल = new WindowInteropHelper (यह) .Handle द्वारा एक्वायर्ड किया जा सकता है;
अलेक्जेंड्रू डिकू

1

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 में मुझे दिखाता है कि मेरा अनुमान है, बस टास्कबार में नहीं।


हाँ यह समस्या है: ShowInTaskbar Alt + Tab संवाद को प्रभावित नहीं करता है, जैसे आप उम्मीद कर सकते हैं।
devios1

1

जब भी यह स्वचालित रूप से सच में बदल जाता है, मैंने मुख्य रूप की दृश्यता को झूठा करने की कोशिश की:

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

यह पूरी तरह से काम करता है :)


2
न केवल अब तक का सबसे आसान उपाय है, बल्कि इसने मेरे लिए बहुत अच्छा काम किया है।
डैनियल मैकक्विस्टन

1

यदि आप चाहते हैं कि प्रपत्र सीमाहीन हो, तो आपको निम्नलिखित कथनों को फार्म के निर्माता के साथ जोड़ना होगा:

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

अधिक जानकारी



0

Form1 गुण:
FormBorderStyle: बड़े
आकार का WindowState: कम से कम
ShowInTaskbar: गलत

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 +AB में दिखाए बिना चलने की अनुमति देगा। फिर भी, यदि आप एक फॉर्म खोलते हैं, तो वह फॉर्म अभी भी मानक कार्यक्षमता का पालन करेगा।

यदि आप चाहते हैं तो मैं केवल एक NotifyIcon डिफ़ॉल्ट रूप से एक अनुप्रयोग बनाने के बारे में अपने ब्लॉग लेख को खोद सकता हूं।



मैं पहले से ही NotifyIcons में अच्छी तरह से वाकिफ हूं, धन्यवाद। समस्या यह है कि मैं Alt (टैब) से खुली (गैर-इंटरैक्टिव, या सबसे ऊपरी) खिड़कियां छिपाना चाहता हूं। दिलचस्प बात यह है कि, मैंने अभी देखा कि Vista साइडबार Alt + Tab में दिखाई नहीं देता है, इसलिए ऐसा करने के लिए कुछ तरीका होना चाहिए।
devios1

विभिन्न प्रकारों और टुकड़ों को देखते हुए, खिड़की के प्रकार को बदले बिना (जैसा कि पोस्टबर्ड पोस्ट किया गया है), मुझे ऐसा करने का तरीका नहीं पता है।
मचेल सेलर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.