forms数字聚光灯实现了专注于当前活动窗口的屏幕遮罩工具
说明:
1.在非活动窗口区域创建半透明黑色遮罩
2.突出显示当前获得焦点的窗口
3.通过降低周围区域的亮度帮助用户集中注意力
效果图:
step1:
C:\Users\wangrusheng\RiderProjects\WinFormsApp32\WinFormsApp32\Form1.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;namespace WinFormsApp32
{public partial class Form1 : Form{#region Win32 API[DllImport("user32.dll")]private static extern IntPtr GetForegroundWindow();[DllImport("user32.dll")]private static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);[DllImport("user32.dll")]private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);private const int LWA_ALPHA = 0x2;[StructLayout(LayoutKind.Sequential)]public struct RECT{public int Left;public int Top;public int Right;public int Bottom;}#endregionprivate readonly List<DimLayerForm> dimLayers = new List<DimLayerForm>();private bool isActive = true;private int opacity = 80;private System.Windows.Forms.Timer refreshTimer;private RECT lastActiveRect;public Form1(){InitializeComponent();InitializeTrayIcon();InitializeTimer();this.ShowInTaskbar = false;this.WindowState = FormWindowState.Minimized;}private class DimLayerForm : Form{public DimLayerForm(){FormBorderStyle = FormBorderStyle.None;ShowInTaskbar = false;TopMost = true;BackColor = Color.Black;StartPosition = FormStartPosition.Manual;}protected override CreateParams CreateParams{get{CreateParams cp = base.CreateParams;cp.ExStyle |= 0x80000; // WS_EX_LAYEREDcp.ExStyle |= 0x20; // WS_EX_TRANSPARENTreturn cp;}}}private void InitializeTrayIcon(){var trayIcon = new NotifyIcon{Icon = SystemIcons.Application,Text = "Focus Dimmer",Visible = true};var contextMenu = new ContextMenuStrip();var toggleItem = new ToolStripMenuItem("Toggle Dimming");toggleItem.Click += (s, e) => ToggleDimming();contextMenu.Items.Add(toggleItem);var trackBar = new TrackBar{Minimum = 20,Maximum = 200,Value = opacity,Width = 150,TickStyle = TickStyle.None};trackBar.ValueChanged += (s, e) => {opacity = trackBar.Value;UpdateDimming();};contextMenu.Items.Add(new ToolStripControlHost(trackBar));contextMenu.Items.Add(new ToolStripSeparator());var exitItem = new ToolStripMenuItem("Exit");exitItem.Click += (s, e) => Application.Exit();contextMenu.Items.Add(exitItem);trayIcon.ContextMenuStrip = contextMenu;}private void InitializeTimer(){refreshTimer = new System.Windows.Forms.Timer { Interval = 100 };refreshTimer.Tick += (s, e) => UpdateDimming();refreshTimer.Start();}private void UpdateDimming(){if (!isActive) return;var foregroundHandle = GetForegroundWindow();GetWindowRect(foregroundHandle, out RECT currentActiveRect);if (currentActiveRect.Left == lastActiveRect.Left &¤tActiveRect.Top == lastActiveRect.Top &¤tActiveRect.Right == lastActiveRect.Right &¤tActiveRect.Bottom == lastActiveRect.Bottom){return;}lastActiveRect = currentActiveRect;ClearDimLayers();CreateDimLayers();}private void CreateDimLayers(){foreach (var screen in Screen.AllScreens){var screenRect = screen.Bounds;var screenRECT = new RECT{Left = screenRect.Left,Top = screenRect.Top,Right = screenRect.Right,Bottom = screenRect.Bottom};if (!IsRectIntersecting(screenRECT, lastActiveRect)){AddDimLayer(screenRect);continue;}// 上方区域if (lastActiveRect.Top > screenRect.Top){AddDimLayer(new Rectangle(screenRect.Left,screenRect.Top,screenRect.Width,lastActiveRect.Top - screenRect.Top));}// 下方区域if (lastActiveRect.Bottom < screenRect.Bottom){AddDimLayer(new Rectangle(screenRect.Left,lastActiveRect.Bottom,screenRect.Width,screenRect.Bottom - lastActiveRect.Bottom));}// 左侧区域if (lastActiveRect.Left > screenRect.Left){AddDimLayer(new Rectangle(screenRect.Left,screenRect.Top,lastActiveRect.Left - screenRect.Left,screenRect.Height));}// 右侧区域if (lastActiveRect.Right < screenRect.Right){AddDimLayer(new Rectangle(lastActiveRect.Right,screenRect.Top,screenRect.Right - lastActiveRect.Right,screenRect.Height));}}}private bool IsRectIntersecting(RECT a, RECT b){return !(a.Right <= b.Left || a.Left >= b.Right || a.Bottom <= b.Top || a.Top >= b.Bottom);}private void AddDimLayer(Rectangle bounds){if (bounds.Width <= 0 || bounds.Height <= 0) return;var layer = new DimLayerForm { Bounds = bounds };SetLayeredWindowAttributes(layer.Handle, 0, (byte)opacity, LWA_ALPHA);layer.Show();dimLayers.Add(layer);}private void ClearDimLayers(){foreach (var layer in dimLayers){layer.Close();layer.Dispose();}dimLayers.Clear();}private void ToggleDimming(){isActive = !isActive;if (isActive) UpdateDimming();else ClearDimLayers();}}
}
end