Skip to content

Commit

Permalink
现在在 Win32 窗口上也可以点击 HyperlinkButton 了
Browse files Browse the repository at this point in the history
IntPtr 改为 nint
  • Loading branch information
wherewhere committed Nov 9, 2023
1 parent babcffa commit 861ed52
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 39 deletions.
38 changes: 27 additions & 11 deletions CoreAppUWP/Helpers/DispatcherQueueHelper.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
using System;
using System.Runtime.InteropServices; // For DllImport
using System.Runtime.InteropServices; // For DllImport
using Windows.System;

namespace CoreAppUWP.Helpers
{
public partial class WindowsSystemDispatcherQueueHelper
{
/// <summary>
/// Specifies the threading and apartment type for a new DispatcherQueueController.
/// </summary>
/// <remarks>Introduced in Windows 10, version 1709.</remarks>
[StructLayout(LayoutKind.Sequential)]
private struct DispatcherQueueOptions
{
internal int DWSize;
internal int ThreadType;
internal int ApartmentType;
/// <summary>
/// Size of this <see cref="DispatcherQueueOptions"/> structure.
/// </summary>
public int DWSize;

/// <summary>
/// Thread affinity for the created <a href="https://docs.microsoft.com/uwp/api/windows.system.dispatcherqueuecontroller">DispatcherQueueController</a>.
/// </summary>
public int ThreadType;

/// <summary>
/// Specifies whether to initialize COM apartment on the new thread as an application single-threaded apartment (ASTA)
/// or single-threaded apartment (STA). This field is only relevant if <b>threadType</b> is <b>DQTYPE_THREAD_DEDICATED</b>.
/// Use <b>DQTAT_COM_NONE</b> when <b>DispatcherQueueOptions.threadType</b> is <b>DQTYPE_THREAD_CURRENT</b>.
/// </summary>
public int ApartmentType;
}

[LibraryImport("CoreMessaging.dll")]
private static unsafe partial int CreateDispatcherQueueController(DispatcherQueueOptions options, IntPtr* instance);
private static unsafe partial int CreateDispatcherQueueController(DispatcherQueueOptions options, nint* instance);

private IntPtr m_dispatcherQueueController = IntPtr.Zero;
private nint m_dispatcherQueueController = nint.Zero;
public void EnsureWindowsSystemDispatcherQueueController()
{
if (DispatcherQueue.GetForCurrentThread() != null)
Expand All @@ -26,16 +42,16 @@ public void EnsureWindowsSystemDispatcherQueueController()
return;
}

if (m_dispatcherQueueController == IntPtr.Zero)
if (m_dispatcherQueueController == nint.Zero)
{
DispatcherQueueOptions options;
options.DWSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));
options.ThreadType = 2; // DQTYPE_THREAD_CURRENT
options.ApartmentType = 2; // DQTAT_COM_STA
options.ThreadType = 2; // DQTYPE_THREAD_CURRENT
options.ApartmentType = 2; // DQTAT_COM_STA

unsafe
{
IntPtr dispatcherQueueController;
nint dispatcherQueueController;
_ = CreateDispatcherQueueController(options, &dispatcherQueueController);
m_dispatcherQueueController = dispatcherQueueController;
}
Expand Down
9 changes: 5 additions & 4 deletions CoreAppUWP/Helpers/ThemeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public static bool IsDarkTheme()
? Application.Current.RequestedTheme == ApplicationTheme.Dark
: ActualTheme == ElementTheme.Dark
: ActualTheme == ElementTheme.Default
? UISettings?.GetColorValue(UIColorType.Background) == Colors.Black
? UISettings?.GetColorValue(UIColorType.Foreground).IsColorLight() == true
: ActualTheme == ElementTheme.Dark;
}

Expand All @@ -238,7 +238,7 @@ public static async ValueTask<bool> IsDarkThemeAsync()
? Application.Current.RequestedTheme == ApplicationTheme.Dark
: ActualTheme == ElementTheme.Dark
: ActualTheme == ElementTheme.Default
? UISettings?.GetColorValue(UIColorType.Background) == Colors.Black
? UISettings?.GetColorValue(UIColorType.Foreground).IsColorLight() == true
: ActualTheme == ElementTheme.Dark;
}

Expand All @@ -249,10 +249,12 @@ public static bool IsDarkTheme(this ElementTheme ActualTheme)
? Application.Current.RequestedTheme == ApplicationTheme.Dark
: ActualTheme == ElementTheme.Dark
: ActualTheme == ElementTheme.Default
? UISettings?.GetColorValue(UIColorType.Background) == Colors.Black
? UISettings?.GetColorValue(UIColorType.Foreground).IsColorLight() == true
: ActualTheme == ElementTheme.Dark;
}

public static bool IsColorLight(this Color color) => ((5 * color.G) + (2 * color.R) + color.B) > (8 * 128);

public static void UpdateExtendViewIntoTitleBar(bool IsExtendsTitleBar)
{
WindowHelper.ActiveWindows.Values.ForEach(async window =>
Expand Down Expand Up @@ -335,7 +337,6 @@ public static async void UpdateSystemCaptionButtonColors(Window window)
TitleBar.ButtonBackgroundColor = TitleBar.ButtonInactiveBackgroundColor = ExtendViewIntoTitleBar ? Colors.Transparent : BackgroundColor;
}


public static async void UpdateSystemCaptionButtonColors(DesktopWindow window)
{
if (!AppWindowTitleBar.IsCustomizationSupported()) { return; }
Expand Down
4 changes: 2 additions & 2 deletions CoreAppUWP/Helpers/UIHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ public static int GetActualPixel(this double pixel)
return Convert.ToInt32(pixel * currentDpi);
}

public static int GetActualPixel(this double pixel, IntPtr window)
public static int GetActualPixel(this double pixel, nint window)
{
uint currentDpi = PInvoke.GetDpiForWindow(new HWND(window));
return Convert.ToInt32(pixel * (currentDpi / 96.0));
}

public static double GetDisplayPixel(this int pixel, IntPtr window)
public static double GetDisplayPixel(this int pixel, nint window)
{
uint currentDpi = PInvoke.GetDpiForWindow(new HWND(window));
return pixel / (currentDpi / 96.0);
Expand Down
6 changes: 3 additions & 3 deletions CoreAppUWP/Helpers/WindowHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace CoreAppUWP.Helpers
/// </summary>
public static class WindowHelper
{
public static async ValueTask<bool> CreateWindowAsync(Action<Window> launched)
public static async Task<bool> CreateWindowAsync(Action<Window> launched)
{
CoreApplicationView newView = CoreApplication.CreateNewView();
int newViewId = await newView.Dispatcher.AwaitableRunAsync(() =>
Expand All @@ -40,14 +40,14 @@ public static async ValueTask<bool> CreateWindowAsync(Action<Window> launched)
return await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
}

public static async ValueTask<DesktopWindow> CreateDesktopWindowAsync(Action<DesktopWindowXamlSource> launched)
public static async Task<DesktopWindow> CreateDesktopWindowAsync(Action<DesktopWindowXamlSource> launched)
{
DesktopWindow newWindow = await DesktopWindow.CreateAsync(launched).ConfigureAwait(false);
TrackWindow(newWindow);
return newWindow;
}

public static async ValueTask<DesktopWindow> CreateDesktopWindowAsync(this DispatcherQueue dispatcherQueue, Action<DesktopWindowXamlSource> launched)
public static async Task<DesktopWindow> CreateDesktopWindowAsync(this DispatcherQueue dispatcherQueue, Action<DesktopWindowXamlSource> launched)
{
DesktopWindow newWindow = await DesktopWindow.CreateAsync(dispatcherQueue, launched).ConfigureAwait(false);
TrackWindow(newWindow);
Expand Down
4 changes: 2 additions & 2 deletions CoreAppUWP/Pages/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ private void UpdateAppTitle(CoreApplicationViewTitleBar coreTitleBar)

private void UpdateAppTitle(AppWindow appWindow)
{
IntPtr hwnd = (IntPtr)appWindow.Id.Value;
nint hwnd = (nint)appWindow.Id.Value;
RightPaddingColumn.Width = new GridLength(Math.Max(0, appWindow.TitleBar.RightInset.GetDisplayPixel(hwnd)));
}

Expand All @@ -249,7 +249,7 @@ private void CustomTitleBar_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.GetWindowForElement() is DesktopWindow window)
{
IntPtr hwnd = (IntPtr)window.AppWindow.Id.Value;
nint hwnd = (nint)window.AppWindow.Id.Value;
RectInt32 Rect = new((AppTitleBar.ActualWidth - DragRegion.ActualWidth).GetActualPixel(hwnd), 0, DragRegion.ActualWidth.GetActualPixel(hwnd), DragRegion.ActualHeight.GetActualPixel(hwnd));
window.AppWindow?.TitleBar.SetDragRectangles([Rect]);
}
Expand Down
13 changes: 8 additions & 5 deletions CoreAppUWP/Pages/SettingsPages/SettingsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
<HyperlinkButton
Click="HyperlinkButton_Click"
Content="Windows Color Settings"
Tag="WindowsColor" />
Tag="ms-settings:colors"
ToolTipService.ToolTip="{Binding Tag, RelativeSource={RelativeSource Mode=Self}}" />
</controls:Setting.Description>
<ComboBox SelectedIndex="{x:Bind Provider.SelectedTheme, Mode=TwoWay}">
<ComboBoxItem Content="Dark" />
Expand Down Expand Up @@ -353,17 +354,19 @@
VerticalScrollMode="Disabled">
<StackPanel Orientation="Horizontal" Spacing="4">
<HyperlinkButton
Click="HyperlinkButton_Click"
Content="Feedback"
NavigateUri="https://github.com/wherewhere/CoreAppUWP/issues"
ToolTipService.ToolTip="{Binding NavigateUri, RelativeSource={RelativeSource Mode=Self}}" />
Tag="https://github.com/wherewhere/CoreAppUWP/issues"
ToolTipService.ToolTip="{Binding Tag, RelativeSource={RelativeSource Mode=Self}}" />
<HyperlinkButton
Click="HyperlinkButton_Click"
Content="Log Folder"
Tag="LogFolder" />
<HyperlinkButton
Click="HyperlinkButton_Click"
Content="Release Notes"
NavigateUri="https://github.com/wherewhere/CoreAppUWP/releases/latest"
ToolTipService.ToolTip="{Binding NavigateUri, RelativeSource={RelativeSource Mode=Self}}" />
Tag="https://github.com/wherewhere/CoreAppUWP/releases/latest"
ToolTipService.ToolTip="{Binding Tag, RelativeSource={RelativeSource Mode=Self}}" />
</StackPanel>
</ScrollViewer>
</controls:SettingExpander.Description>
Expand Down
25 changes: 14 additions & 11 deletions CoreAppUWP/Pages/SettingsPages/SettingsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Core;
Expand All @@ -18,6 +19,7 @@
using Windows.System;
using Windows.UI.ApplicationSettings;
using Windows.UI.ViewManagement;
using DispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
Expand Down Expand Up @@ -65,7 +67,7 @@ protected override void OnNavigatedTo(NavigationEventArgs e)

private async void Button_Click(object sender, RoutedEventArgs e)
{
switch ((sender as FrameworkElement).Tag as string)
switch ((sender as FrameworkElement).Tag?.ToString())
{
case "Reset":
SettingsHelper.LocalObject.Clear();
Expand Down Expand Up @@ -158,20 +160,21 @@ void OnLaunched(DesktopWindowXamlSource source)

private async void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
switch ((sender as FrameworkElement).Tag.ToString())
string tag = (sender as FrameworkElement).Tag?.ToString();
if (!IsCoreWindow
&& WindowHelper.ActiveWindows.Values.FirstOrDefault()?.DispatcherQueue is DispatcherQueue dispatcherQueue
&& dispatcherQueue?.HasThreadAccess == false)
{
case "LogFolder":
_ = Launcher.LaunchFolderAsync(await ApplicationData.Current.LocalFolder.CreateFolderAsync("MetroLogs", CreationCollisionOption.OpenIfExists));
break;
case "WindowsColor":
_ = Launcher.LaunchUriAsync(new Uri("ms-settings:colors"));
break;
default:
break;
await dispatcherQueue.ResumeForegroundAsync();
}
_ = tag switch
{
"LogFolder" => Launcher.LaunchFolderAsync(await ApplicationData.Current.LocalFolder.CreateFolderAsync("MetroLogs", CreationCollisionOption.OpenIfExists)),
_ => Launcher.LaunchUriAsync(new Uri(tag)),
};
}

public ValueTask Refresh(bool reset = false) => Provider.Refresh(reset);
public Task Refresh(bool reset = false) => Provider.Refresh(reset);

private void MarkdownText_LinkClicked(object sender, LinkClickedEventArgs e) => _ = Launcher.LaunchUriAsync(new Uri(e.Link));
}
Expand Down
2 changes: 1 addition & 1 deletion CoreAppUWP/ViewModels/SettingsPages/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public void KeepProcess()
}
}

public async ValueTask Refresh(bool reset)
public async Task Refresh(bool reset)
{
if (reset)
{
Expand Down

0 comments on commit 861ed52

Please sign in to comment.