أفضل طريقة لإخفاء نافذة من Alt-Tab برنامج الجلاد ؟

StackOverflow https://stackoverflow.com/questions/357076

  •  21-08-2019
  •  | 
  •  

سؤال

لقد كنت .NET developer لعدة سنوات حتى الآن و هذا لا تزال واحدة من تلك الأشياء التي كنت لا تعرف كيفية القيام بذلك بشكل صحيح.فإنه من السهل إخفاء النافذة من شريط المهام عن طريق خاصية في كل من ويندوز أشكال WPF ، ولكن بقدر ما أستطيع أن أقول, هذا لا يضمن (أو بالضرورة تؤثر حتى) لا يخفى عليه من Alt+↹التبويب الحوار.رأيت غير مرئية ويندوز تظهر في Alt+↹التبويب, و أنا أتساءل فقط ما هو أفضل وسيلة لضمان نافذة أبدا تظهر (مرئية أو لا) في Alt+↹التبويب الحوار.

تحديث: يرجى الاطلاع على بلدي نشر الحل أدناه.أنا لا يسمح لي علامة بلدي إجابات الحل ، لكن حتى الآن هو الوحيد الذي يعمل.

تحديث 2: هناك الآن الحل المناسب من قبل Franci Penov التي تبدو جيدة جدا ، ولكن لم اجرب ذلك بنفسي.ينطوي على بعض Win32 ولكن يتجنب عرجاء إنشاء قبالة الشاشة ويندوز.

هل كانت مفيدة؟

المحلول

تحديث:

وفقا @دونوفان الأيام الحديثة WPF يدعم هذا أصلا ، من خلال وضع ShowInTaskbar="False" و Visibility="Hidden" في XAML.(أنا لم تختبر بعد هذا ، ولكن مع ذلك قررت عثرة تعليق الرؤية)

الجواب الأصلية:

هناك طريقتان إخفاء نافذة من مهمة الجلاد في Win32 API:

  1. لإضافة WS_EX_TOOLWINDOW تمديد نافذة style - هذا هو النهج الصحيح.
  2. لجعلها نافذة الطفل من نافذة أخرى.

للأسف, WPF لا يدعم مرنة السيطرة على نافذة نمط Win32 ، وبالتالي نافذة مع WindowStyle=ToolWindow ينتهي مع الافتراضي WS_CAPTION و WS_SYSMENU أنماط, الذي يؤدي إلى شرح و زر إغلاق.من ناحية أخرى, يمكنك إزالة هذه اثنين من الأساليب من خلال وضع WindowStyle=None, ومع ذلك لم تحدد WS_EX_TOOLWINDOW تمديد نمط النافذة لن تكون مخفية من مهمة الجلاد.

أن يكون نافذة مع WPF WindowStyle=None وهذا هو أيضا خفية من مهمة الجلاد ، واحد أما من طريقتين:

  • الذهاب مع نموذج التعليمات البرمجية أعلاه وجعل نافذة نافذة طفل صغير المخفية أداة نافذة
  • تعديل نمط الإطار أن تشمل أيضا 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.نحن أيضا إضافة معالج الى تحميلها الحدث حيث سنقوم بتعديل تمديد نافذة الطراز.لا يمكننا العمل في منشئ, كما لا يوجد مقبض الإطار في هذه النقطة بعد.معالج الحدث في حد ذاته هو بسيط جدا:

    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 الإعلانات.لقد تمت إزالة جميع لا لزوم لها أنماط من enums, فقط للحفاظ على نموذج التعليمات البرمجية هنا صغيرة.أيضا, للأسف SetWindowLongPtr نقطة الدخول لم يتم العثور على في user32.dll على ويندوز 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+↹التبويب الحوار.

شكرا إيفان Onuchin على منتديات MSDN على الحل.

تحديث 2: يجب عليك أيضا تعيين ShowInTaskBar=false على w لمنعها من اللمعان لفترة وجيزة في شريط المهام عندما يظهر.

لماذا هذا التعقيد ؟ جرب هذا:

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 إلى FixedToolWindow.آمل أن يساعد.

انظر في ذلك:(من 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 مجموعة 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 أعتقد, ليس فقط في شريط المهام.

حاولت وضع النموذج الرئيسي هو رؤية كاذبة عندما يتم تغييرها تلقائيا إلى true:

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

وهو يعمل تماما :)

لا تظهر على شكل.استخدام الخفي.

المزيد هنا: http://code.msdn.microsoft.com/TheNotifyIconExample

Form1 خصائص:
FormBorderStyle:لا بأس به
حالة الإطار:تصغير
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;
}>

إذا كنت تريد شكل أن تكون بلا حدود ، ثم تحتاج إلى إضافة البيانات التالية إلى النموذج منشئ:

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 (علبة النظام) التطبيق سوف تسمح لها أن تكون قيد التشغيل دون أن تظهر في ALT + TAB.ومع ذلك, إذا قمت بفتح النموذج هذا النموذج وسوف لا تزال تتبع وظائف القياسية.

أنا يمكن حفر بلدي بلوق المادة حول إنشاء تطبيق فقط NotifyIcon افتراضيا إذا كنت تريد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top