Skip to content

Commit

Permalink
Merge pull request #1 from DHancock/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
DHancock authored Oct 11, 2023
2 parents 279745f + b352f3f commit 8e24b46
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 58 deletions.
107 changes: 53 additions & 54 deletions TestSolution/Test_WinAppSdk/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,76 +18,75 @@
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace Test_WinAppSdk
namespace Test_WinAppSdk;

/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainWindow : Window
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainWindow : Window
{
private readonly SUBCLASSPROC subClassDelegate;
private readonly HWND hWnd;
private readonly SUBCLASSPROC subClassDelegate;
private readonly HWND hWnd;

public MainWindow()
{
this.InitializeComponent();
public MainWindow()
{
this.InitializeComponent();

hWnd = (HWND)WindowNative.GetWindowHandle(this);
subClassDelegate = new SUBCLASSPROC(NewSubWindowProc);
hWnd = (HWND)WindowNative.GetWindowHandle(this);
subClassDelegate = new SUBCLASSPROC(NewSubWindowProc);

if (!PInvoke.SetWindowSubclass(hWnd, subClassDelegate, 0, 0))
throw new Win32Exception(Marshal.GetLastPInvokeError());
if (!PInvoke.SetWindowSubclass(hWnd, subClassDelegate, 0, 0))
throw new Win32Exception(Marshal.GetLastPInvokeError());

LayoutRoot.Loaded += (s, e) => RegisterConsumer();
}
LayoutRoot.Loaded += (s, e) => RegisterConsumer();
}

private void RegisterConsumer()
private void RegisterConsumer()
{
foreach (TraceListener listener in Trace.Listeners)
{
foreach (TraceListener listener in Trace.Listeners)
if (listener is ViewTraceListener viewTraceListener)
{
if (listener is ViewTraceListener viewTraceListener)
{
viewTraceListener.RegisterConsumer(TraceCounsumer);
return;
}
viewTraceListener.RegisterConsumer(TraceCounsumer);
return;
}

TraceCounsumer.Document.SetText(TextSetOptions.None, "failed to find trace listener");
}

private void Button_Click(object sender, RoutedEventArgs e)
{
TraceCounsumer.Document.SetText(TextSetOptions.None, string.Empty);
}
TraceCounsumer.Document.SetText(TextSetOptions.None, "failed to find trace listener");
}

private LRESULT NewSubWindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
{
Trace.WriteLine(WinMsg.Format(uMsg, wParam, lParam));

if (uMsg == PInvoke.WM_GETMINMAXINFO)
{
const double MinWidth = 660;
const double MinHeight = 500;

MINMAXINFO minMaxInfo = Marshal.PtrToStructure<MINMAXINFO>(lParam);
double scaleFactor = GetScaleFactor();
minMaxInfo.ptMinTrackSize.X = Math.Max(ConvertToDeviceSize(MinWidth, scaleFactor), minMaxInfo.ptMinTrackSize.X);
minMaxInfo.ptMinTrackSize.Y = Math.Max(ConvertToDeviceSize(MinHeight, scaleFactor), minMaxInfo.ptMinTrackSize.Y);
Marshal.StructureToPtr(minMaxInfo, lParam, true);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
TraceCounsumer.Document.SetText(TextSetOptions.None, string.Empty);
}

return PInvoke.DefSubclassProc(hWnd, uMsg, wParam, lParam);
private LRESULT NewSubWindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam, nuint uIdSubclass, nuint dwRefData)
{
Trace.WriteLine(WinMsg.Format(uMsg, wParam, lParam));

if (uMsg == PInvoke.WM_GETMINMAXINFO)
{
const double MinWidth = 660;
const double MinHeight = 500;

MINMAXINFO minMaxInfo = Marshal.PtrToStructure<MINMAXINFO>(lParam);
double scaleFactor = GetScaleFactor();
minMaxInfo.ptMinTrackSize.X = Math.Max(ConvertToDeviceSize(MinWidth, scaleFactor), minMaxInfo.ptMinTrackSize.X);
minMaxInfo.ptMinTrackSize.Y = Math.Max(ConvertToDeviceSize(MinHeight, scaleFactor), minMaxInfo.ptMinTrackSize.Y);
Marshal.StructureToPtr(minMaxInfo, lParam, true);
}

private static int ConvertToDeviceSize(double value, double scalefactor) => Convert.ToInt32(Math.Clamp(value * scalefactor, 0, short.MaxValue));
return PInvoke.DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

private double GetScaleFactor()
{
if ((Content is not null) && (Content.XamlRoot is not null))
return Content.XamlRoot.RasterizationScale;
private static int ConvertToDeviceSize(double value, double scalefactor) => Convert.ToInt32(Math.Clamp(value * scalefactor, 0, short.MaxValue));

double dpi = PInvoke.GetDpiForWindow(hWnd);
return dpi / 96.0;
}
private double GetScaleFactor()
{
if ((Content is not null) && (Content.XamlRoot is not null))
return Content.XamlRoot.RasterizationScale;

double dpi = PInvoke.GetDpiForWindow(hWnd);
return dpi / 96.0;
}
}
10 changes: 6 additions & 4 deletions WinMessageConverter/WinMsg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@ namespace AssyntSoftware.WinMessageConverter;

public static class WinMsg
{
public static bool TryGetMessage(uint msg, out string? output)
public static bool TryGetMessage(uint msg, out string? text)
{
return LazyProvider.MessageDictionary.TryGetValue(msg, out output);
return LazyProvider.MessageDictionary.TryGetValue(msg, out text);
}

public static string Format(uint msg)
{
if (TryGetMessage(msg, out string? output))
return output!;
if (TryGetMessage(msg, out string? text))
return text!;

return $"0x{msg:X4}";
}

// parameter types suitable for CsWin32 window subclass functions (WinAppSdk)
public static string Format(uint msg, nuint wParam, nint lParam)
{
return $"{Format(msg)} wParam: 0x{wParam:X4} lParam: 0x{lParam:X4}";
}

// parameter types suitable for WPF and WinForms applications
public static string Format(int msg, IntPtr wParam, IntPtr lParam)
{
return Format((uint)msg, (nuint)(nint)wParam, lParam);
Expand Down

0 comments on commit 8e24b46

Please sign in to comment.