SORU
10 Aralık 2008, ÇARŞAMBA


En iyi Alt-Tab program değiştiriciden bir pencere gizlemek için bir yol?

Bir oldum .Birkaç yıl için NET geliştirici ve şimdi bu hala düzgün bir şekilde yapmak için nasıl bilmiyorum, bu şeylerden biridir. Kolay saklanacak bir pencereden görev çubuğu üzerinden bir özelliği Windows Forms ve WPF, ama bildiğim kadarıyla söyleyebilirim, bu yok garanti (veya ille de bile etkiler) olmak gizli Alt-Tab iletişim. Gördümgörünmezwindows Alt-Tab görünür, ve sadece bir pencere olacak garanti etmek için en iyi yolu nedir merak ediyorumasla(görünür veya değil) Alt-Tab iletişim kutusunda görünür.

Güncelleme:Yayınlanan benim çözüm lütfen aşağıya bakınız. Çözüm olarak benim kendi cevaplar işaretlemek için izin yok, ama şimdiye kadar işe yarayan tek şey.

Güncelleme 2:Şimdi oldukça iyi görünüyor Franci Penov tarafından uygun bir çözüm var, ama kendim hiç denemedim. Bazı Win32, ama ekran kapalı windows topal oluşturma önler içerir.

CEVAP
15 ŞUBAT 2009, Pazar


Güncelleme:

@Donovan göre, modern gün WPF bu doğal olarak ayarlanması ile destekler ShowInTaskbar="False" ve XAML Visibility="Hidden". (Henüz test etmedim, ama yine de yorum görünürlüğünü yükseltmek için karar verdi)

Orijinal cevabı:

Win32 API olarak görev değiştiriciden bir pencere gizleme iki yolu vardır:

  1. WS_EX_TOOLWINDOW genişletilmiş pencere stili eklemek için - bu doğru yaklaşım değil.
  2. bunu başka bir pencere bir alt pencere olun.

Ne yazık ki, WPF desteklemiyor gibi esnek kontrol penceresi tarzı olarak, Win32, böylece bir pencere ile WindowStyle=ToolWindow biter varsayılan WS_CAPTION WS_SYSMENU stilleri, hangi neden için bir başlık ve Kapatma düğmesi. Diğer taraftan, WS_EX_TOOLWINDOW genişletilmiş stilini ayarlamak değil, ancak o WindowStyle=None, ayarlayarak bu iki stilleri kaldırabilirsiniz ve pencere görev değiştiriciyi gizli olmayacak.

Ayrıca görev değiştiriciden gizli WindowStyle=None ile bir WPF penceresi var, bir iki şekilde olabilir:

  • örnek kod ile yukarıdaki gidip pencereyi küçük gizli aracı bir pencere bir alt pencere olun
  • pencere stili de WS_EX_TOOLWINDOW genişletilmiş stil içerecek şekilde değiştirin.

Ben şahsen ikinci bir yaklaşım tercih. Sonra tekrar, istemci alanında cam uzanan ve başlık WPF çizim zaten etkinleştirme gibi gelişmiş bazı şeyler, birlikte çalışabilirlik biraz büyük bir sorun değildir.

İşte Win32 birlikte çalışma çözüm yaklaşımı için örnek kod. İlk olarak, XAML kısmı:

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

Çok fazla bir şey değil burada, biz sadece WindowStyle=None ShowInTaskbar=False ile bir pencere bildirin. Ayrıca genişletilmiş pencere stili değiştirmek nerede Yüklü olay için bir işleyici ekleyin. Bu noktada yine başa pencere yok gibi yapıcı bu işi yapamayız. Olay çok basit kendisi işleyicisi:

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

Ve win 32 bildirimleri birlikte çalışabilirlik. Çeteleler tüm gereksiz stiller, sadece örnek kodu burada küçük tutmak için çıkardım. Ayrıca, SetWindowLongPtr giriş ne yazık ki bu noktada Windows XP, dolayısıyla SetWindowLong ile arama yerine yönlendirme numarası user32.dll bulunamadı.

    #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

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • bobinire

    bobinire

    24 EYLÜL 2006
  • Dylan Brenan

    Dylan Brenan

    22 Aralık 2009
  • RiceBunny

    RiceBunny

    16 ŞUBAT 2006