NotifyIcon context menu - initial prototype

saving this here so i can see if there's a better way to do stuff first before adding functionality
This commit is contained in:
pizzaboxer 2023-07-19 19:07:40 +01:00
parent ee9f339914
commit 4705bec8d6
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
5 changed files with 121 additions and 2 deletions

View File

@ -293,6 +293,9 @@ namespace Bloxstrap
{
Logger.WriteLine("[App::OnStartup] Bootstrapper task has finished");
// notifyicon is blocking main thread, must be disposed here
NotifyIcon?.Dispose();
if (t.IsFaulted)
Logger.WriteLine("[App::OnStartup] An exception occurred when running the bootstrapper");

View File

@ -0,0 +1,35 @@
<ui:UiWindow x:Class="Bloxstrap.UI.Elements.NotifyIconMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:Bloxstrap.UI.Elements"
mc:Ignorable="d"
Title="NotifyIconMenu"
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
MinWidth="0"
MinHeight="0"
Width="0"
Height="0"
ShowInTaskbar="False"
WindowStyle="None"
Loaded="Window_Loaded">
<ui:UiWindow.ContextMenu>
<ContextMenu>
<MenuItem Header="_Bold"
IsCheckable="True"/>
<MenuItem Header="_Italic"
IsCheckable="True" />
<Separator />
<MenuItem Header="I_ncrease Font Size" />
<MenuItem Header="_Decrease Font Size" />
<MenuItem x:Name="TestMenuItem" Header="test" IsCheckable="True" Click="TestMenuItem_Click" />
</ContextMenu>
</ui:UiWindow.ContextMenu>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<!--<ProgressBar IsIndeterminate="True" />-->
<TextBlock Margin="16" Text="if this stops spinning ur SCREWED!!!!!!!!!" />
<ui:ProgressRing Margin="16" IsIndeterminate="True" />
</StackPanel>
</ui:UiWindow>

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Bloxstrap.UI.ViewModels;
namespace Bloxstrap.UI.Elements
{
/// <summary>
/// Interaction logic for NotifyIconMenu.xaml
/// </summary>
public partial class NotifyIconMenu
{
public NotifyIconMenu()
{
InitializeComponent();
}
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
// this is an awful hack lmao im so sorry to anyone who reads this
// https://stackoverflow.com/questions/357076/best-way-to-hide-a-window-from-the-alt-tab-program-switcher#:~:text=ShowInTaskbar%20%3D%20false%3B%20Owner%20%3D%20form1,form%27s%20ShowInTaskbar%20property%20to%20false.
var wndHelper = new WindowInteropHelper(this);
long exStyle = NativeMethods.GetWindowLongPtr(wndHelper.Handle, NativeMethods.GWL_EXSTYLE).ToInt64();
exStyle |= NativeMethods.WS_EX_TOOLWINDOW;
NativeMethods.SetWindowLongPtr(wndHelper.Handle, NativeMethods.GWL_EXSTYLE, (IntPtr)exStyle);
}
// i tried to use a viewmodel but uhhhhhhh it just didnt work idk
private void TestMenuItem_Click(object sender, RoutedEventArgs e)
{
Controls.ShowMessageBox($"hi how u doing i am {TestMenuItem.IsChecked}", MessageBoxImage.Warning);
}
}
}

View File

@ -1,5 +1,7 @@
using System.Windows.Forms;
using Bloxstrap.UI.Elements;
namespace Bloxstrap.UI
{
public class NotifyIconWrapper : IDisposable
@ -7,9 +9,12 @@ namespace Bloxstrap.UI
bool _disposed = false;
private readonly NotifyIcon _notifyIcon;
private readonly NotifyIconMenu _contextMenuWrapper = new();
EventHandler? _alertClickHandler;
public NotifyIconWrapper()
public NotifyIconWrapper()
{
App.Logger.WriteLine("[NotifyIconWrapper::NotifyIconWrapper] Initializing notification area icon");
@ -19,6 +24,21 @@ namespace Bloxstrap.UI
Text = App.ProjectName,
Visible = true
};
_notifyIcon.MouseClick += MouseClickEventHandler;
_contextMenuWrapper.Dispatcher.BeginInvoke(_contextMenuWrapper.ShowDialog);
_contextMenuWrapper.Closing += (_, _) => App.Logger.WriteLine("[NotifyIconWrapper::NotifyIconWrapper] Context menu wrapper closing");
}
public void MouseClickEventHandler(object? sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Right)
return;
_contextMenuWrapper.Activate();
_contextMenuWrapper.ContextMenu.IsOpen = true;
}
public void ShowAlert(string caption, string message, int duration, EventHandler? clickHandler)
@ -62,8 +82,11 @@ namespace Bloxstrap.UI
if (_disposed)
return;
App.Logger.WriteLine($"[NotifyIconWrapper::Dispose] Disposing NotifyIcon");
_contextMenuWrapper.Dispatcher.Invoke(_contextMenuWrapper.Close);
_notifyIcon.Dispose();
_disposed = true;
GC.SuppressFinalize(this);

View File

@ -9,5 +9,17 @@ namespace Bloxstrap.Utility
[DllImport("user32.dll")]
public static extern bool FlashWindow(IntPtr hWnd, bool bInvert);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
// i only bothered to add the constants that im using lol
public const int GWL_EXSTYLE = -20;
public const int WS_EX_TOOLWINDOW = 0x00000080;
}
}