mirror of https://github.com/dahall/Vanara.git
Added nullability to Magnification and tests
parent
163affe6ba
commit
3aa52d622f
|
@ -394,6 +394,38 @@ public static partial class Magnification
|
|||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool MagSetColorEffect(HWND hwnd, in MAGCOLOREFFECT pEffect);
|
||||
|
||||
/// <summary>Sets the color transformation matrix for a magnifier control.</summary>
|
||||
/// <param name="hwnd">
|
||||
/// <para>Type: <c>HWND</c></para>
|
||||
/// <para>The magnification window.</para>
|
||||
/// </param>
|
||||
/// <param name="pEffect">
|
||||
/// <para>Type: <c>PMAGCOLOREFFECT</c></para>
|
||||
/// <para>The color transformation matrix, or <c>NULL</c> to remove the current color effect, if any.</para>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <para>Type: <c>BOOL</c></para>
|
||||
/// <para>Returns <c>TRUE</c> if successful, or <c>FALSE</c> otherwise.</para>
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The magnifier control uses the color transformation matrix to apply a color effect to the entire magnifier window. If the
|
||||
/// function is called multiple times, the most recent color transform is used.
|
||||
/// </para>
|
||||
/// <para>This function requires Windows Display Driver Model (WDDM)-capable video cards.</para>
|
||||
/// <para>Examples</para>
|
||||
/// <para>The following example sets a color transformation matrix that converts the colors displayed in the magnifier to grayscale.</para>
|
||||
/// <para>
|
||||
/// <code>// Description: // Converts the colors displayed in the magnifier window to grayscale, or // returns the colors to normal. // Parameters: // hwndMag - Handle of the magnifier control. // fInvert - TRUE to convert to grayscale, or FALSE for normal colors. // BOOL ConvertToGrayscale(HWND hwndMag, BOOL fConvert) { // Convert the screen colors in the magnifier window. if (fConvert) { MAGCOLOREFFECT magEffectGrayscale = {{ // MagEffectGrayscale { 0.3f, 0.3f, 0.3f, 0.0f, 0.0f }, { 0.6f, 0.6f, 0.6f, 0.0f, 0.0f }, { 0.1f, 0.1f, 0.1f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } }}; return MagSetColorEffect(hwndMag, &magEffectGrayscale); } // Return the colors to normal. else { return MagSetColorEffect(hwndMag, NULL); } }</code>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/magnification/nf-magnification-magsetcoloreffect BOOL MagSetColorEffect( HWND
|
||||
// hwnd, PMAGCOLOREFFECT pEffect );
|
||||
[DllImport(Lib_Magnification, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("magnification.h", MSDNShortId = "NF:magnification.MagSetColorEffect")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool MagSetColorEffect(HWND hwnd, [In, Optional] IntPtr pEffect);
|
||||
|
||||
/// <summary>Changes the color transformation matrix associated with the full-screen magnifier.</summary>
|
||||
/// <param name="pEffect">
|
||||
/// <para>Type: <c>PMAGCOLOREFFECT</c></para>
|
||||
|
@ -529,7 +561,7 @@ public static partial class Magnification
|
|||
[DllImport(Lib_Magnification, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("magnification.h", MSDNShortId = "NF:magnification.MagSetImageScalingCallback")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool MagSetImageScalingCallback(HWND hwnd, MagImageScalingCallback callback);
|
||||
public static extern bool MagSetImageScalingCallback(HWND hwnd, MagImageScalingCallback? callback);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current active input transformation for pen and touch input, represented as a source rectangle and a destination rectangle.
|
||||
|
@ -579,7 +611,7 @@ public static partial class Magnification
|
|||
[DllImport(Lib_Magnification, SetLastError = true, ExactSpelling = true)]
|
||||
[PInvokeData("magnification.h", MSDNShortId = "NF:magnification.MagSetInputTransform")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool MagSetInputTransform([MarshalAs(UnmanagedType.Bool)] bool fEnabled, [Optional] in RECT pRectSource, [Optional] in RECT pRectDest);
|
||||
public static extern bool MagSetInputTransform([MarshalAs(UnmanagedType.Bool)] bool fEnabled, [In, Optional] PRECT? pRectSource, [In, Optional] PRECT? pRectDest);
|
||||
|
||||
/// <summary>Sets the list of windows to be magnified or the list of windows to be excluded from magnification.</summary>
|
||||
/// <param name="hwnd">
|
||||
|
@ -737,7 +769,7 @@ public static partial class Magnification
|
|||
// { float transform[5][5]; } MAGCOLOREFFECT, *PMAGCOLOREFFECT;
|
||||
[PInvokeData("magnification.h", MSDNShortId = "NS:magnification.tagMAGCOLOREFFECT")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MAGCOLOREFFECT
|
||||
public struct MAGCOLOREFFECT : IEquatable<MAGCOLOREFFECT>
|
||||
{
|
||||
private const int dimLen = 5;
|
||||
|
||||
|
@ -916,41 +948,6 @@ public static partial class Magnification
|
|||
public static bool operator !=(MAGCOLOREFFECT lhs, MAGCOLOREFFECT rhs) => !(lhs == rhs);
|
||||
|
||||
/// <summary>An Identity Matrix for MAGCOLOREFFECT.</summary>
|
||||
|
||||
/* Unmerged change from project 'Vanara.PInvoke.Magnification (net48)'
|
||||
Before:
|
||||
public static readonly MAGCOLOREFFECT Identity = new MAGCOLOREFFECT { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
After:
|
||||
public static readonly MAGCOLOREFFECT Identity = new() { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
*/
|
||||
|
||||
/* Unmerged change from project 'Vanara.PInvoke.Magnification (net7.0)'
|
||||
Before:
|
||||
public static readonly MAGCOLOREFFECT Identity = new MAGCOLOREFFECT { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
After:
|
||||
public static readonly MAGCOLOREFFECT Identity = new() { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
*/
|
||||
|
||||
/* Unmerged change from project 'Vanara.PInvoke.Magnification (netcoreapp3.1)'
|
||||
Before:
|
||||
public static readonly MAGCOLOREFFECT Identity = new MAGCOLOREFFECT { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
After:
|
||||
public static readonly MAGCOLOREFFECT Identity = new() { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
*/
|
||||
|
||||
/* Unmerged change from project 'Vanara.PInvoke.Magnification (netstandard2.0)'
|
||||
Before:
|
||||
public static readonly MAGCOLOREFFECT Identity = new MAGCOLOREFFECT { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
After:
|
||||
public static readonly MAGCOLOREFFECT Identity = new() { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
*/
|
||||
|
||||
/* Unmerged change from project 'Vanara.PInvoke.Magnification (net45)'
|
||||
Before:
|
||||
public static readonly MAGCOLOREFFECT Identity = new MAGCOLOREFFECT { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
After:
|
||||
public static readonly MAGCOLOREFFECT Identity = new() { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
*/
|
||||
public static readonly MAGCOLOREFFECT Identity = new() { transform00 = 1, transform11 = 1, transform22 = 1, transform33 = 1, transform44 = 1 };
|
||||
}
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ public class WindowBase : MarshalByRefObject, IDisposable, IWindowInstance, IWin
|
|||
/// <summary>Performs an implicit conversion from <see cref="WindowBase"/> to <see cref="HWND"/>.</summary>
|
||||
/// <param name="w">The <see cref="WindowBase"/> instance.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator HWND(WindowBase w) => w.Handle;
|
||||
public static implicit operator HWND(WindowBase? w) => w?.Handle ?? HWND.NULL;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
private void CheckDetached()
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using NUnit.Framework;
|
||||
using NUnit.Framework.Internal;
|
||||
using System.Diagnostics;
|
||||
using static Vanara.PInvoke.Magnification;
|
||||
using static Vanara.PInvoke.User32;
|
||||
|
||||
namespace Vanara.PInvoke.Tests;
|
||||
|
||||
|
@ -14,6 +16,13 @@ public class MagnificationTests
|
|||
{ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }});
|
||||
|
||||
//static readonly MAGCOLOREFFECT invert = new(new[,] {
|
||||
// { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
// { 0.0f, -1.0f, 0.0f, 0.0f, 0.0f },
|
||||
// { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f },
|
||||
// { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
// { 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }});
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void _Setup()
|
||||
{
|
||||
|
@ -26,6 +35,58 @@ public class MagnificationTests
|
|||
Assert.IsTrue(MagUninitialize());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSetMagEffect()
|
||||
{
|
||||
VisibleWindow? hwndHost = null;
|
||||
HWND hwndMag = default;
|
||||
new System.Threading.Thread(() =>
|
||||
{
|
||||
const string WindowClassName = "Magnification Test";
|
||||
|
||||
HINSTANCE hInst = Kernel32.GetModuleHandle().ReleaseOwnership();
|
||||
hwndHost = new VisibleWindow(WindowClassName, hInst, WindowClassName, new SIZE(300, 200), exStyle: WindowStylesEx.WS_EX_TOPMOST | WindowStylesEx.WS_EX_LAYERED | WindowStylesEx.WS_EX_TRANSPARENT);
|
||||
Assert.False(hwndHost.Handle.IsNull);
|
||||
|
||||
// Make the window opaque.
|
||||
SetLayeredWindowAttributes(hwndHost, 0, 255, LayeredWindowAttributes.LWA_ALPHA);
|
||||
|
||||
// Create a magnifier control that fills the client area.
|
||||
var r = hwndHost.ClientRect;
|
||||
var tmp = CreateWindow(WC_MAGNIFIER, "MagnifierWindow", WindowStyles.WS_CHILD | (WindowStyles)MagnifierStyles.MS_SHOWMAGNIFIEDCURSOR | WindowStyles.WS_VISIBLE,
|
||||
0, 0, r.Width, r.Height, hwndHost, default, hInst);
|
||||
if ((hwndMag = tmp.ReleaseOwnership()) != HWND.NULL)
|
||||
{
|
||||
hwndHost.Show();
|
||||
new MessagePump().Run(hwndHost);
|
||||
}
|
||||
}).Start();
|
||||
System.Threading.Thread.Yield();
|
||||
System.Threading.Thread.Sleep(500);
|
||||
|
||||
try
|
||||
{
|
||||
Assert.That(hwndMag, ResultIs.ValidHandle);
|
||||
|
||||
Assert.That(MagGetColorEffect(GetDesktopWindow(), out var eff), ResultIs.FailureCode(Win32Error.ERROR_NOT_SUPPORTED));
|
||||
Assert.That(MagSetColorEffect(GetDesktopWindow(), eff), ResultIs.FailureCode(Win32Error.ERROR_NOT_SUPPORTED));
|
||||
|
||||
MAGTRANSFORM matrix = new(2f);
|
||||
Assert.That(MagSetWindowTransform(hwndMag, matrix), ResultIs.Successful);
|
||||
Assert.That(MagGetWindowTransform(hwndMag, out var m2), ResultIs.Successful);
|
||||
Assert.AreEqual(matrix, m2);
|
||||
|
||||
Assert.That(MagGetColorEffect(hwndMag, out eff), ResultIs.Successful);
|
||||
Assert.True(eff.IsIdentity);
|
||||
Assert.That(MagSetColorEffect(hwndMag, grayeff), ResultIs.Successful);
|
||||
Assert.That(MagSetColorEffect(hwndMag), ResultIs.Successful);
|
||||
}
|
||||
finally
|
||||
{
|
||||
hwndHost?.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MagGetSetFullscreenTransformTest()
|
||||
{
|
||||
|
@ -47,7 +108,7 @@ public class MagnificationTests
|
|||
{
|
||||
Assert.That(MagSetFullscreenColorEffect(grayeff), ResultIs.Successful);
|
||||
Assert.That(MagGetFullscreenColorEffect(out var grayeff_get), ResultIs.Successful);
|
||||
Assert.That(grayeff.transform, Is.EquivalentTo(grayeff_get.transform));
|
||||
Assert.AreEqual(grayeff, grayeff_get);
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
Assert.That(MagSetFullscreenColorEffect(MAGCOLOREFFECT.Identity), ResultIs.Successful);
|
||||
}
|
||||
|
@ -110,42 +171,4 @@ public class MagnificationTests
|
|||
Assert.AreEqual(11.2f, tfx[1, 2]);
|
||||
Assert.AreEqual(12.2f, tfx[2, 2]);
|
||||
}
|
||||
|
||||
/*
|
||||
private static bool CreateMagnifier(HINSTANCE hInstance)
|
||||
{
|
||||
const string WindowClassName = "Magnification Test";
|
||||
|
||||
// Register the host window class.
|
||||
var wcex = new WNDCLASSEX
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf<WNDCLASSEX>(),
|
||||
style = 0,
|
||||
lpfnWndProc = HostWndProc,
|
||||
hInstance = hInstance,
|
||||
hCursor = LoadCursor(default, IDC_ARROW),
|
||||
hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE),
|
||||
lpszClassName = WindowClassName
|
||||
};
|
||||
|
||||
if (RegisterClassEx(wcex) == 0)
|
||||
return false;
|
||||
|
||||
// Create the host window.
|
||||
hwndHost = CreateWindowEx(WindowStylesEx.WS_EX_TOPMOST | WindowStylesEx.WS_EX_LAYERED | WindowStylesEx.WS_EX_TRANSPARENT,
|
||||
WindowClassName, WindowClassName, WindowStyles.WS_CLIPCHILDREN, 0, 0, 0, 0, default, default, hInstance, default);
|
||||
if (hwndHost.IsInvalid)
|
||||
return false;
|
||||
|
||||
// Make the window opaque.
|
||||
SetLayeredWindowAttributes(hwndHost, 0, 255, LayeredWindowAttributes.LWA_ALPHA);
|
||||
|
||||
// Create a magnifier control that fills the client area.
|
||||
hwndMag = CreateWindow(WC_MAGNIFIER, "MagnifierWindow", WindowStyles.WS_CHILD | WindowStyles.MS_SHOWMAGNIFIEDCURSOR | WindowStyles.WS_VISIBLE,
|
||||
0, 0, LENS_WIDTH, LENS_HEIGHT, hwndHost, NULL, hInstance, NULL);
|
||||
return !hwndMag.IsInvalid;
|
||||
}
|
||||
|
||||
private static IntPtr HostWndProc(HWND hwnd, uint uMsg, IntPtr wParam, IntPtr lParam) => throw new NotImplementedException();
|
||||
*/
|
||||
}
|
Loading…
Reference in New Issue