Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The hidden taskbar icon is invalid after restarting explorer #10026

Open
ChenYiLins opened this issue Sep 27, 2024 · 2 comments
Open

The hidden taskbar icon is invalid after restarting explorer #10026

ChenYiLins opened this issue Sep 27, 2024 · 2 comments
Labels
bug Something isn't working needs-triage Issue needs to be triaged by the area owners

Comments

@ChenYiLins
Copy link

Describe the bug

I hide the taskbar icon, when explorer was be restarted, the hidden taskbar icon will reappear.

Steps to reproduce the bug

1.Use code App.MainWindow.IsShownInSwitchers = false;
2.Restart Explorer using Task Manager.

Expected behavior

At the same time, I tried to get the value of IsShownInSwitchers. Even though the taskbar icon has appeared, the value of IshownInSwitchers is still false.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.6.0: 1.6.240829007

Windows version

Windows 11 (22H2): Build 22621

Additional context

No response

@ChenYiLins ChenYiLins added the bug Something isn't working label Sep 27, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Sep 27, 2024
@castorix
Copy link

You can be notified when the Shell is restarted :
This works on my Windows 10 22H2 OS =>

  hWndMain = WinRT.Interop.WindowNative.GetWindowHandle(this);
  Microsoft.UI.WindowId myWndId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWndMain);
  _apw = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(myWndId);
  _apw.IsShownInSwitchers = false;
  SubClassDelegate = new SUBCLASSPROC(WindowSubClass);
  bool bRet = SetWindowSubclass(hWndMain, SubClassDelegate, 0, 0);
        private int WindowSubClass(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam, IntPtr uIdSubclass, uint dwRefData)
        {
            if (uMsg == m_WM_TASKBARCREATED)
            { 
                Console.Beep(6000, 10);
                _apw.IsShownInSwitchers = true;
                _apw.IsShownInSwitchers = false;
            }
            return DefSubclassProc(hWnd, uMsg, wParam, lParam);
        }

with :

[DllImport("User32.Dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegisterWindowMessage(string lpString);

private static readonly uint m_WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");

public delegate int SUBCLASSPROC(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam, IntPtr uIdSubclass, uint dwRefData);

[DllImport("Comctl32.dll", SetLastError = true)]
public static extern bool SetWindowSubclass(IntPtr hWnd, SUBCLASSPROC pfnSubclass, uint uIdSubclass, uint dwRefData);

[DllImport("Comctl32.dll", SetLastError = true)]
public static extern int DefSubclassProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
private SUBCLASSPROC SubClassDelegate;

private IntPtr hWndMain = IntPtr.Zero;     
private Microsoft.UI.Windowing.AppWindow _apw;

@ChenYiLins
Copy link
Author

I also tried to use hook, which also worked.

public sealed partial class FlyoutPage : Page
{
    private static readonly HOOKPROC _callWndProcHook = CallWndProcCallback;
    private static readonly UnhookWindowsHookExSafeHandle _callWndProcHookId;

    private struct CWPSTRUCT
    {
        public IntPtr lParam;
        public IntPtr wParam;
        public uint message;
        public IntPtr hwnd;
    }

    public FlyoutViewModel ViewModel
    {
        get;
    }

    static FlyoutPage()
    {
        var hModule = PInvoke.GetModuleHandle(Process.GetCurrentProcess().MainModule!.ModuleName);
        _callWndProcHookId = PInvoke.SetWindowsHookEx(WINDOWS_HOOK_ID.WH_CALLWNDPROC, _callWndProcHook, hModule, PInvoke.GetCurrentThreadId());

        AppDomain.CurrentDomain.ProcessExit += (s, e) => { _callWndProcHookId.Close(); };
    }

    public FlyoutPage()
    {
        ViewModel = App.GetService<FlyoutViewModel>();
        InitializeComponent();
    }

    private static LRESULT CallWndProcCallback(int nCode, WPARAM wParam, LPARAM lParam)
    {
        var navigation = App.GetService<INavigationService>();
        if (navigation?.Frame != null)
        {
            if (navigation.Frame.Content is not FlyoutPage)
            {
                navigation.NavigateTo(typeof(FlyoutViewModel).FullName!);
            }

            if (navigation.Frame.Content is FlyoutPage page)
            {
                page.CallWndProcHookCallback(nCode, wParam, lParam);
            }
        }
        return PInvoke.CallNextHookEx(_callWndProcHookId, nCode, wParam, lParam);
    }

    private void CallWndProcHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode >= 0)
        {
            var msg = Marshal.PtrToStructure<CWPSTRUCT>(lParam);
            if (msg.message == PInvoke.RegisterWindowMessage("TaskbarCreated"))
            {
                App.FlyoutWindow.IsShownInSwitchers = true;
                App.FlyoutWindow.IsShownInSwitchers = false;
            }
        }
    }

For more code, you can check out my MoreFlyout project.
But I think this series of phenomena should be the bug of IsShowInSwitchers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs-triage Issue needs to be triaged by the area owners
Projects
None yet
Development

No branches or pull requests

2 participants