在日常生活中,常用的一些应用、文件、文件夹经常会放在桌面比较显眼的位置。但是有时候因为其他应用的使用,导致图标被覆盖,只能切换到桌面才能打开。
本程序模仿Win11自带的快捷启动应用,实现常用应用、文件、文件夹的分类和快速启动等。
效果图:
实现内容:
通过拖拽将程序、文件和文件夹等放入应用中,自动分类布局,并允许排序、启动、设置我开机启动等。
程序思路:
1.点击程序弹出窗口,窗口位置固定屏幕中间底部,点击程序外围隐藏窗口(通过钩子监听鼠标点击事件实现)。
2.拖拽文件到窗口内自动分类显示(通过系统Api读取图标),
3.右键调整顺序,设置/取消应用开机启动(创建/删除应用快捷方式到启动文件夹实现)
4.点击应用、文件、文件夹打开(Process启动)
5.调整屏幕亮度(系统Api读取,通过命令行指令修改亮度)
读取应用图标:
[DllImport("Shell32.dll")]
private static extern IntPtr SHGetFileInfo
(
string pszPath,
uint dwFileAttributes,
out SHFILEINFO psfi,
uint cbfileInfo,
SHGFI uFlags
);
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero; iIcon = 0; dwAttributes = 0; szDisplayName = ""; szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
public string szTypeName;
};
private enum SHGFI
{
SmallIcon = 0x00000001,
LargeIcon = 0x00000000,
Icon = 0x00000100,
DisplayName = 0x00000200,
Typename = 0x00000400,
SysIconIndex = 0x00004000,
UseFileAttributes = 0x00000010
}
/// <summary>
/// 获取文件夹图标
/// </summary>
/// <returns>图标</returns>
public Icon GetDirectoryIcon(string dir, bool largeIcon = true)
{
SHFILEINFO _SHFILEINFO = new SHFILEINFO();
int cbFileInfo = Marshal.SizeOf(_SHFILEINFO);
SHGFI flags;
if (largeIcon)
flags = SHGFI.Icon | SHGFI.LargeIcon;
else
flags = SHGFI.Icon | SHGFI.SmallIcon;
IntPtr IconIntPtr = SHGetFileInfo(@"", 0, out _SHFILEINFO, (uint)cbFileInfo, flags);
if (IconIntPtr.Equals(IntPtr.Zero))
return null;
Icon _Icon = System.Drawing.Icon.FromHandle(_SHFILEINFO.hIcon);
return _Icon;
}
/// <summary>
/// 获取文件图标
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
Icon GetFileIcon(string filePath)
{
if (File.Exists(filePath))
return System.Drawing.Icon.ExtractAssociatedIcon(filePath);
return null;
}
通过钩子监听鼠标点击事件,判断点击位置,点击引用外围则最小化应用(系统显示器放大125%):
//监听鼠标点击,点击窗口外围则最小化窗口
private void Instance_OnMouseDown(object? sender, System.Windows.Forms.MouseEventArgs e)
{
if(e.Button == System.Windows.Forms.MouseButtons.Left)
{
var pos = e.Location;
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
if (this.WindowState == WindowState.Minimized)
return;
double left = this.Left;
double top = this.Top;
double wid = this.ActualWidth;
double height = this.ActualHeight;
if (pos.X < left * 1.25)
this.WindowState = WindowState.Minimized;
else if (pos.X > (left + wid) * 1.25)
this.WindowState = WindowState.Minimized;
else if (pos.Y < top * 1.25)
this.WindowState = WindowState.Minimized;
else if (pos.Y > (top + height) * 1.25)
this.WindowState = WindowState.Minimized;
}));
}
}
读取/设置屏幕亮度:
RegistryKey registryBrighnessKey = null;
/// <summary>
/// 获取当前屏幕亮度
/// </summary>
/// <param name="isAC">是否使用电源:true为使用电源,正常情况下两个值都一样</param>
/// <returns></returns>
public int GetBrightness(bool isAC = true)
{
try
{
if(registryBrighnessKey != null)
{
var valueAC = registryBrighnessKey.GetValue("ACSettingIndex");//接通电源
var valueDC = registryBrighnessKey.GetValue("DCSettingIndex");//使用电池
if (isAC)
return Convert.ToInt32(valueAC);
else
return Convert.ToInt32(valueDC);
}
else
{
//读取电源方案GUID
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.StandardInput.WriteLine("powercfg /L");
process.StandardInput.Close();
string res = process.StandardOutput.ReadToEnd();
if (string.IsNullOrEmpty(res))
return -1;
string guid = string.Empty;
foreach (string item in res.Split(new char[] { '\r', }))
{
//带*的电源方案为当前使用的方案
if (item.Contains("*"))
{
int index = item.IndexOf(':');
if (index < 0)
continue;
int index2 = item.IndexOf("(");
if (index2 < 0)
continue;
guid = item.Substring(index + 1, index2 - index - 1).Trim();
break;
}
}
if (string.IsNullOrEmpty(guid))
return -1;
string path = $"SYSTEM\\CurrentControlSet\\Control\\Power\\User\\PowerSchemes\\{guid}\\7516b95f-f776-4464-8c53-06167f40cc99\\aded5e82-b909-4619-9949-f5d71dac0bcb";
RegistryKey root = Registry.LocalMachine;
registryBrighnessKey = root.OpenSubKey(path);
if (registryBrighnessKey != null)
{
var valueAC = registryBrighnessKey.GetValue("ACSettingIndex");//接通电源
var valueDC = registryBrighnessKey.GetValue("DCSettingIndex");//使用电池
if (isAC)
return Convert.ToInt32(valueAC);
else
return Convert.ToInt32(valueDC);
}
else
return -1;
}
}
catch
{
return -1;
}
}
private bool IsSettingBrightness = false;
/// <summary>
/// 设置屏幕亮度
/// </summary>
/// <param name="brightness"></param>
public void SetBrightness(int brightness)
{
if (!hasLoaded)
return;
if (brightness == BrightnessValueNow)
return;
IsSettingBrightness = true;
Task.Run(() =>
{
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.StandardInput.WriteLine($"PowerShell (Get-WmiObject -Namespace root/WMI -Class WmiMonitorBrightnessMethods).WmiSetBrightness(1, {brightness})");
process.StandardInput.Close();
IsSettingBrightness = false;
Thread.Sleep(200);
BrightnessValueNow = brightness;
});
}
应用设置为开机启动:
/// <summary>
/// 设置为开机启动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SetPowerOnStart(object sender, RoutedEventArgs e)
{
MenuItem menuItem = sender as MenuItem;
StartItem item = menuItem.DataContext as StartItem;
if (item.IsApp)
{
string startpPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
string fileName = item.name.Split('.')[0] + ".lnk";
string fPath = Path.Combine(startpPath, fileName);
if (!item.IsPowerOnStart)
{
if (!File.Exists(fPath))
{
try
{
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(fPath);
//目标文件(指向目标程序)
shortcut.TargetPath = item.filePath;
//快捷方式存放目录,如果创建时指定全路径,此步骤可以忽略,设置了也无效
//shortcut.WorkingDirectory = System.Environment.CurrentDirectory;
//快捷方式指定窗口,1正常,3最大化,7最小化
shortcut.WindowStyle = 1;
//快捷方式附加说明
shortcut.Description = "附加说明";
//系统快捷方式图标所在位置,第165个图标
shortcut.IconLocation = System.Environment.SystemDirectory + "\\" + "shell32.dll, 165";
//生成快捷方式
shortcut.Save();
item.IsPowerOnStart = true;
icAppList.ItemsSource = null;
icAppList.ItemsSource = AppList;
}
catch (Exception ex)
{
}
}
}
else
{
try
{
File.Delete(fPath);
item.IsPowerOnStart = false;
icAppList.ItemsSource = null;
icAppList.ItemsSource = AppList;
}
catch (Exception ex)
{
}
}
}
}
到这里工作基本完成啦,窗口根据内容数量调整高度等细节就不一一展示了,个人感觉挺有用的。比Win11自带的多了分类,Win10上使用非常方便。