Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Taskbar icon disappears when WindowChrome is used on Windows 8.1

I have some problems with an own styled WPF Window on Windows 8.1. I wrote a simple transparent WPF Window with a WindowChrome for default windows drag behaviors:

<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" Background="Transparent"
        AllowsTransparency="True" WindowStyle="None">
    <WindowChrome.WindowChrome>
        <WindowChrome />
    </WindowChrome.WindowChrome>
    <Border Background="Gray" CornerRadius="20">
        <Grid>
        </Grid>
    </Border>
</Window>

Windows 8.1 Settings:

  • 2 monitors with extended desktop
  • Taskbar only visible on primary desktop

Repro:

  1. Start the WPF application
  2. Move the window on the secondary screen
  3. Maximize the window on the secondary screen (for example by docking the window on the top)
  4. Restore and drag the window from the secondary screen to the primary screen

--> The taskbar icon will disappear exactly when the mouse enters on the primary screen!

If you do the same repro again the icon reappears.

I also tried to use .NET 4.5 or .NET 4.5.1!

Can anyone explain this problem?

Thank you!

like image 511
Thomas H. Avatar asked Jan 22 '14 18:01

Thomas H.


2 Answers

after some trial and error debugging i figured out, that the window visibility is setting to false, then update the system menu and after that setting to true.

i think this is not necessary and produces this nasty issue

here is the method at WindowChromeWorker

private void _UpdateSystemMenu(WindowState? assumeState)
{
    const MF mfEnabled = MF.ENABLED | MF.BYCOMMAND;
    const MF mfDisabled = MF.GRAYED | MF.DISABLED | MF.BYCOMMAND;

    WindowState state = assumeState ?? _GetHwndState();

    if (null != assumeState || _lastMenuState != state)
    {
        _lastMenuState = state;

        bool modified = _ModifyStyle(WS.VISIBLE, 0);

        IntPtr hmenu = NativeMethods.GetSystemMenu(_hwnd, false);
        if (IntPtr.Zero != hmenu)
        {
            // change menu items
            ...
        }

        if (modified)
        {
            _ModifyStyle(0, WS.VISIBLE);
        }
    }
}

so you can try take a look into my branch of

WPF Shell Integration Library (Ex)tended Edition

original source can be found here

also here is a little test application

hope that helps

like image 186
punker76 Avatar answered Nov 13 '22 01:11

punker76


It seems that this bug only appears when you set WindowStyle="None" on your WPF window. Moreover, this option also breaks Modern apps which are snapped to the side when maximizing you application. It may seem weird, but setting WindowStyle is not required when using WindowChrome to remove window borders, so you can safely skip it.

The only caveat is that you cannot use AllowTransparency (but it's allright, as you should not use it in the first place due to extensive performance problems with this option).

like image 33
ghord Avatar answered Nov 13 '22 02:11

ghord