8

システムメニューがある場所であるWPFウィンドウの左上隅からアイコンを非表示または削除することについて、多くの質問があることを私は知っています。私はそれらの多くを試しましたが、どれも機能しません。ここに私の要件があります:

  • アイコンが消え、空のスペースを取りません (つまり、透明なアイコンはありません)。
  • ウィンドウのタイトルは、ウィンドウの左端から直接始まります
  • 右上隅の閉じるボタンはまだそこにあり、機能します
  • 有効にすると、最小化/最大化ボタンが表示されます (オプション、これはテストしていません)。
  • 窓枠全体のカスタム描画なし
  • Aero Glass が有効になっている Windows 7 で動作します (Windows 8 のユーザーはいますか?)
  • 32 ビットおよび 64 ビット Windows で動作 (x86 および x64 ビルド)
  • WPF .NET 4.0 で動作
  • Visual Studio のようなデバッガーでなくても機能します (デバッガーでも機能する場合は便利です)。
  • Windows XP でも動作するはずです (オプション)

利用可能な回答は基本的に Windows API 関数GetWindowLongを使用し、SetWindowLong場合SetWindowPosによっては拡張ウィンドウ スタイルを追加しWS_EX_DLGMODALFRAMESWP_FRAMECHANGED. 場合によっては、他のスタイルも設定または設定解除されます。

残念ながら、これはまったく機能しません。閉じるボタンのないアイコンを持たないか、両方がまだそこにある可能性があります。しかし、そのコンテンツがすべて 2010 年以前のものであることも注目に値します。以前の .NET または Windows バージョンをターゲットにしており、それ以来失敗しているようです。

システム ダイアログのウィンドウ スタイル (エクスプローラーから) と WPF ウィンドウを Microsoft Spy++ (Visual Studio に含まれる) と既に比較しました。しかし、すべてのフラグを同じに設定しようとすると、アイコンが消えません。これは、他のすべての API 関数や物理を無効にする黒魔術のようなものです。

現在、指定された環境でまだ機能するソリューションを誰かが持っていますか?

4

3 に答える 3

2

これは、この質問に対するさまざまな解決策を見て、私が思いついたものです。

    internal const int SWP_NOSIZE = 0x0001;
    internal const int SWP_NOMOVE = 0x0002;
    internal const int SWP_NOZORDER = 0x0004;
    internal const int SWP_FRAMECHANGED = 0x0020;
    internal const int GWL_EXSTYLE = -20;
    internal const int WS_EX_DLGMODALFRAME = 0x0001;

    [DllImport("user32.dll", SetLastError = true)]
    internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    [DllImport("user32.dll")]
    internal static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);

    /// <summary>
    /// Hides icon for window.
    /// If this is called before InitializeComponent() then the icon will be completely removed from the title bar
    /// If this is called after InitializeComponent() then an empty image is used but there will be empty space between window border and title
    /// </summary>
    /// <param name="window">Window class</param>
    internal static void HideIcon(this Window window)
    {
        if (window.IsInitialized)
        {
            window.Icon = BitmapSource.Create(1, 1, 96, 96, PixelFormats.Bgra32, null, new byte[] {0, 0, 0, 0}, 4);
        }
        else
        {
            window.SourceInitialized += delegate
            {
                // Get this window's handle
                var hwnd = new WindowInteropHelper(window).Handle;

                // Change the extended window style to not show a window icon
                int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
                SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);

                // Update the window's non-client area to reflect the changes
                SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
            };
        }
    }

例:

public partial class ExampleWindow : Window
{
    public ExampleWindow()
    {
        // Hides icon completely
        this.HideIcon();

        InitializeComponent();
    }
}
于 2015-09-21T01:27:35.983 に答える