XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

HaloPixelToolBox

【WinUI3】基于USB HID通讯的花再音响工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using CommunityToolkit.Mvvm.Input;
using Microsoft.UI.Dispatching;
using System.Runtime.InteropServices;
using HaloPixelToolBox.Client.Interface.Services;
using HaloPixelToolBox.Client.Utilities.Helpers;
using HaloPixelToolBox.Client.Utilities.Helpers.Win32;
using HaloPixelToolBox.Client.Views;
using XFEExtension.NetCore.WinUIHelper.Implements;
using XFEExtension.NetCore.WinUIHelper.Utilities;

namespace HaloPixelToolBox.Client.ViewModels;

public partial class TrayMenuPageViewModel : ServiceBaseViewModelBase<string>
{
    IntPtr _mouseHook = new();
    LowLevelMouseProc? _proc;
    public Window MenuWindow { get; set; }
    public DispatcherQueue DispatcherQueue => MenuWindow.DispatcherQueue;

    public TrayMenuPageViewModel(Window window)
    {
        MenuWindow = window;
        AutoNavigationParameterService.ParameterChange += AutoNavigationParameterService_ParameterChange;
    }

    private void AutoNavigationParameterService_ParameterChange(object? sender, string? e)
    {
        AutoNavigationParameterService.CurrentPage?.Unloaded += CurrentPage_Unloaded;
        InstallMouseHook();
    }

    private void CurrentPage_Unloaded(object sender, RoutedEventArgs e)
    {
        UnInstallMouseHook();
    }

    void UnInstallMouseHook()
    {
        if (_mouseHook != IntPtr.Zero)
        {
            Win32Helper.UnhookWindowsHookEx(_mouseHook);
            _mouseHook = IntPtr.Zero;
        }
    }

    void InstallMouseHook()
    {
        _proc = HookCallback;
        _mouseHook = Win32Helper.SetWindowsHookEx(Win32Helper.WH_MOUSE_LL, _proc, IntPtr.Zero, 0);
    }

    IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        try
        {
            if (nCode >= 0 && wParam == Win32Helper.WM_LBUTTONDOWN)
            {
                var hook = Marshal.PtrToStructure<MSLLHOOKSTRUCT>(lParam);
                var pt = hook.pt;

                var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(MenuWindow);
                Win32Helper.GetWindowRect(hwnd, out var rect);

                var inside =
                    pt.x >= rect.Left && pt.x <= rect.Right &&
                    pt.y >= rect.Top && pt.y <= rect.Bottom;

                if (!inside)
                {
                    DispatcherQueue.TryEnqueue(() =>
                    {
                        MenuWindow.Close();
                    });
                }
            }
        }
        catch { }

        return Win32Helper.CallNextHookEx(_mouseHook, nCode, wParam, lParam);
    }

    [RelayCommand]
    void Show()
    {
        ServiceManager.GetGlobalService<ITrayIconService>()?.ShowWindow();
        NavigationViewService?.NavigateTo<CloudMusicLyricsToolPage>();
        MenuWindow.Close();
    }

    [RelayCommand]
    void OpenSettings()
    {
        ServiceManager.GetGlobalService<ITrayIconService>()?.ShowWindow();
        NavigationViewService?.NavigateTo<SettingPage>();
        MenuWindow.Close();
    }

    [RelayCommand]
    static void Exit() => ServiceManager.GetGlobalService<ITrayIconService>()?.ExitApp();
}