mirror of
https://github.com/peter-tanner/Vivado-Dark-Mode-Windows-demo.git
synced 2024-11-30 09:00:31 +08:00
203 lines
6.4 KiB
C#
203 lines
6.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Karna.Magnification
|
|
{
|
|
public class Magnifier : IDisposable
|
|
{
|
|
private Form form;
|
|
private IntPtr hwndMag;
|
|
private float magnification;
|
|
private bool initialized;
|
|
private RECT magWindowRect = new RECT();
|
|
private System.Windows.Forms.Timer timer;
|
|
public nint afterHwnd;
|
|
|
|
public Magnifier(Form form)
|
|
{
|
|
if (form == null)
|
|
throw new ArgumentNullException("form");
|
|
|
|
magnification = 1.0f;
|
|
this.form = form;
|
|
this.form.Resize += new EventHandler(form_Resize);
|
|
this.form.FormClosing += new FormClosingEventHandler(form_FormClosing);
|
|
|
|
timer = new System.Windows.Forms.Timer();
|
|
timer.Tick += new EventHandler(timer_Tick);
|
|
|
|
initialized = NativeMethods.MagInitialize();
|
|
if (initialized)
|
|
{
|
|
SetupMagnifier();
|
|
timer.Interval = NativeMethods.USER_TIMER_MINIMUM;
|
|
timer.Enabled = true;
|
|
}
|
|
}
|
|
|
|
void form_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
timer.Enabled = false;
|
|
}
|
|
|
|
void timer_Tick(object sender, EventArgs e)
|
|
{
|
|
UpdateMaginifier();
|
|
}
|
|
|
|
void form_Resize(object sender, EventArgs e)
|
|
{
|
|
ResizeMagnifier();
|
|
}
|
|
|
|
~Magnifier()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
public virtual void ResizeMagnifier()
|
|
{
|
|
if ( initialized && (hwndMag != IntPtr.Zero))
|
|
{
|
|
NativeMethods.GetClientRect(form.Handle, ref magWindowRect);
|
|
// Resize the control to fill the window.
|
|
NativeMethods.SetWindowPos(hwndMag, IntPtr.Zero,
|
|
magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, 0);
|
|
}
|
|
}
|
|
|
|
public virtual void UpdateMaginifier()
|
|
{
|
|
if ((!initialized) || (hwndMag == IntPtr.Zero))
|
|
return;
|
|
|
|
RECT sourceRect = new RECT();
|
|
|
|
sourceRect.left = form.Left;
|
|
sourceRect.right = form.Right;
|
|
sourceRect.top = form.Top;
|
|
sourceRect.bottom = form.Bottom;
|
|
|
|
if (this.form == null || this.form.IsDisposed)
|
|
{
|
|
timer.Enabled = false;
|
|
return;
|
|
}
|
|
|
|
// Set the source rectangle for the magnifier control.
|
|
NativeMethods.MagSetWindowSource(hwndMag, sourceRect);
|
|
// Reclaim topmost status, to prevent unmagnified menus from remaining in view.
|
|
//NativeMethods.SetWindowPos(hwndMag, form.Handle, 0, 0, 0, 0,
|
|
// (int)SetWindowPosFlags.SWP_NOACTIVATE | (int)SetWindowPosFlags.SWP_NOMOVE | (int)SetWindowPosFlags.SWP_NOSIZE);
|
|
|
|
// Force redraw.
|
|
redraw();
|
|
}
|
|
|
|
public virtual void redraw()
|
|
{
|
|
NativeMethods.InvalidateRect(hwndMag, IntPtr.Zero, true);
|
|
}
|
|
|
|
public float Magnification
|
|
{
|
|
get { return magnification; }
|
|
set
|
|
{
|
|
if (magnification != value)
|
|
{
|
|
magnification = value;
|
|
// Set the magnification factor.
|
|
Transformation matrix = new Transformation(magnification);
|
|
NativeMethods.MagSetWindowTransform(hwndMag, ref matrix);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void SetupMagnifier()
|
|
{
|
|
if (!initialized)
|
|
return;
|
|
|
|
IntPtr hInst;
|
|
|
|
hInst = NativeMethods.GetModuleHandle(null);
|
|
|
|
// Make the window opaque.
|
|
form.AllowTransparency = true;
|
|
form.TransparencyKey = Color.Empty;
|
|
form.Opacity = 255;
|
|
|
|
// Create a magnifier control that fills the client area.
|
|
NativeMethods.GetClientRect(form.Handle, ref magWindowRect);
|
|
hwndMag = NativeMethods.CreateWindow(
|
|
(int)ExtendedWindowStyles.WS_EX_TRANSPARENT | (int)ExtendedWindowStyles.WS_EX_NOACTIVATE,
|
|
NativeMethods.WC_MAGNIFIER,
|
|
"MagnifierWindow",
|
|
(int)WindowStyles.WS_CHILD | (int)MagnifierStyle.MS_INVERTCOLORS |
|
|
(int)WindowStyles.WS_VISIBLE,
|
|
magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom,
|
|
form.Handle, IntPtr.Zero, hInst, IntPtr.Zero
|
|
);
|
|
|
|
if (hwndMag == IntPtr.Zero)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Set the magnification factor.
|
|
Transformation matrix = new Transformation(magnification);
|
|
NativeMethods.MagSetWindowTransform(hwndMag, ref matrix);
|
|
}
|
|
|
|
public bool SetFilter(nint hwnd)
|
|
{
|
|
bool res = true;
|
|
//IntPtr filterHandle = Marshal.AllocHGlobal(sizeof(int));
|
|
|
|
//try
|
|
//{
|
|
// Marshal.WriteInt64(filterHandle, (nint)hwnd); // Store the integer value
|
|
// res &= NativeMethods.MagSetWindowFilterList(hwndMag, (int)FilterMode.MW_FILTERMODE_INCLUDE, 1, filterHandle);
|
|
// res &= NativeMethods.MagGetWindowFilterList(hwndMag, filterHandle, 0, filterHandle) == 1;
|
|
//}
|
|
//finally
|
|
//{
|
|
// // Free the allocated unmanaged memory to prevent memory leaks
|
|
// Marshal.FreeHGlobal(filterHandle);
|
|
//}
|
|
return res;
|
|
}
|
|
|
|
protected void RemoveMagnifier()
|
|
{
|
|
if (initialized)
|
|
NativeMethods.MagUninitialize();
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
timer.Enabled = false;
|
|
if (disposing)
|
|
timer.Dispose();
|
|
timer = null;
|
|
form.Resize -= form_Resize;
|
|
RemoveMagnifier();
|
|
}
|
|
|
|
#region IDisposable Members
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|