experiment

This commit is contained in:
Lightczx
2023-10-08 17:30:35 +08:00
parent 7b17bb5a01
commit 1cd3ec0cdb
6 changed files with 155 additions and 4 deletions

View File

@@ -3,6 +3,9 @@ DefSubclassProc
RemoveWindowSubclass
SetWindowSubclass
// CoreMessaging
CreateDispatcherQueueController
// DWMAPI
DwmSetWindowAttribute
@@ -37,12 +40,14 @@ GetCursorPos
GetDC
GetDpiForWindow
GetForegroundWindow
GetWindowLong
GetWindowPlacement
GetWindowThreadProcessId
ReleaseDC
RegisterHotKey
SendInput
SetForegroundWindow
SetWindowLong
UnregisterHotKey
// COM
@@ -56,6 +61,7 @@ IMemoryBufferByteAccess
// Const value
INFINITE
WM_ERASEBKGND
WM_GETMINMAXINFO
WM_HOTKEY
WM_NCRBUTTONDOWN
@@ -69,6 +75,7 @@ LPTHREAD_START_ROUTINE
// UI.WindowsAndMessaging
MINMAXINFO
WINDOW_EX_STYLE
// System.Com
CWMO_FLAGS

View File

@@ -0,0 +1,72 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Windows.Win32.CsWin32.InteropServices;
internal class WinRTCustomMarshaler : ICustomMarshaler
{
private static readonly string? AssemblyFullName = typeof(Windows.Foundation.IMemoryBuffer).Assembly.FullName;
private readonly string className;
private bool lookedForFromAbi;
private MethodInfo? fromAbiMethod;
private WinRTCustomMarshaler(string className)
{
this.className = className;
}
public static ICustomMarshaler GetInstance(string cookie)
{
return new WinRTCustomMarshaler(cookie);
}
public void CleanUpManagedData(object ManagedObj)
{
}
public void CleanUpNativeData(nint pNativeData)
{
Marshal.Release(pNativeData);
}
public int GetNativeDataSize()
{
throw new NotSupportedException();
}
public nint MarshalManagedToNative(object ManagedObj)
{
throw new NotSupportedException();
}
public object MarshalNativeToManaged(nint thisPtr)
{
return className switch
{
"Windows.System.DispatcherQueueController" => Windows.System.DispatcherQueueController.FromAbi(thisPtr),
_ => MarshalNativeToManagedSlow(thisPtr),
};
}
private object MarshalNativeToManagedSlow(nint pNativeData)
{
if (!lookedForFromAbi)
{
Type? type = Type.GetType($"{className}, {AssemblyFullName}");
fromAbiMethod = type?.GetMethod("FromAbi");
lookedForFromAbi = true;
}
if (fromAbiMethod is not null)
{
return fromAbiMethod.Invoke(default, new object[] { pNativeData })!;
}
else
{
return Marshal.GetObjectForIUnknown(pNativeData);
}
}
}

View File

@@ -9,23 +9,28 @@ namespace Snap.Hutao.Core.Windowing;
[HighQuality]
internal enum BackdropType
{
/// <summary>
/// 透明
/// </summary>
Transparent = -1,
/// <summary>
/// 无
/// </summary>
None,
None = 0,
/// <summary>
/// 亚克力
/// </summary>
Acrylic,
Acrylic = 1,
/// <summary>
/// 云母
/// </summary>
Mica,
Mica = 2,
/// <summary>
/// 变种云母
/// </summary>
MicaAlt,
MicaAlt = 3,
}

View File

@@ -0,0 +1,52 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml.Media;
using Windows.Win32.System.WinRT;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing;
internal class TransparentBackdrop : SystemBackdrop
{
private static readonly Lazy<Windows.UI.Composition.Compositor> LazyCompositor = new(() =>
{
EnsureWindowsSystemDispatcherQueueController();
return new();
});
private static Windows.System.DispatcherQueueController? dispatcherQueueController;
private static Windows.UI.Composition.Compositor Compositor => LazyCompositor.Value;
protected override void OnTargetConnected(ICompositionSupportsSystemBackdrop connectedTarget, Microsoft.UI.Xaml.XamlRoot xamlRoot)
{
connectedTarget.SystemBackdrop = Compositor.CreateColorBrush(Windows.UI.Color.FromArgb(0, 255, 255, 255));
}
protected override void OnTargetDisconnected(ICompositionSupportsSystemBackdrop disconnectedTarget)
{
disconnectedTarget.SystemBackdrop = null;
}
private static unsafe void EnsureWindowsSystemDispatcherQueueController()
{
if (Windows.System.DispatcherQueue.GetForCurrentThread() is not null)
{
return;
}
if (dispatcherQueueController is null)
{
DispatcherQueueOptions options = new()
{
dwSize = (uint)sizeof(DispatcherQueueOptions),
threadType = DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT,
apartmentType = DISPATCHERQUEUE_THREAD_APARTMENTTYPE.DQTAT_COM_STA,
};
CreateDispatcherQueueController(options, out dispatcherQueueController);
}
}
}

View File

@@ -56,6 +56,7 @@ internal sealed class WindowController
RecoverOrInitWindowSize();
UpdateImmersiveDarkMode(options.TitleBar, default!);
//SetWindowTransparent();
// appWindow.Show(true);
// appWindow.Show can't bring window to top.
@@ -149,6 +150,7 @@ internal sealed class WindowController
{
window.SystemBackdrop = backdropType switch
{
//BackdropType.Transparent => new TransparentBackdrop(),
BackdropType.MicaAlt => new MicaBackdrop() { Kind = MicaKind.BaseAlt },
BackdropType.Mica => new MicaBackdrop() { Kind = MicaKind.Base },
BackdropType.Acrylic => new DesktopAcrylicBackdrop(),
@@ -188,6 +190,14 @@ internal sealed class WindowController
DwmSetWindowAttribute(options.Hwnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, &isDarkMode, unchecked((uint)sizeof(BOOL)));
}
private unsafe void SetWindowTransparent()
{
int result = GetWindowLong(options.Hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE);
WINDOW_EX_STYLE style = *(WINDOW_EX_STYLE*)&result;
style |= WINDOW_EX_STYLE.WS_EX_LAYERED;
SetWindowLong(options.Hwnd, WINDOW_LONG_PTR_INDEX.GWL_EXSTYLE, *(int*)&style);
}
private void UpdateDragRectangles()
{
AppWindowTitleBar appTitleBar = window.AppWindow.TitleBar;

View File

@@ -89,6 +89,11 @@ internal sealed class WindowSubclass : IDisposable
{
switch (uMsg)
{
case WM_ERASEBKGND:
{
return (LRESULT)(nint)1;
}
case WM_GETMINMAXINFO:
{
uint dpi = GetDpiForWindow(hwnd);