MainWindow.xaml.cs11.4 KB
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Threading.Tasks;
using System.Windows.Threading;
using System.Diagnostics;
using System.Threading;
namespace MyCoolApp
{
public partial class MainWindow : Window
{
// --- 变量定义 ---
private string filePath, configPath, lastClipText = "", searchEngineUrl = "https://www.bing.com/search?q=";
private int skinIndex = 0, timeLeftSeconds = 0;
private bool preferEdge = true;
private uint currentVK = 0x51; // 默认 Q
private DispatcherTimer countdownTimer, memTimer;
private const int HOTKEY_ID = 9001;
// --- Win32 API 导入 ---
[DllImport("user32.dll")] private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")] private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[DllImport("user32.dll")] private static extern bool AddClipboardFormatListener(IntPtr hwnd);
[DllImport("psapi.dll")] private static extern bool EmptyWorkingSet(IntPtr hProcess);
// 定义一个全局唯一的 Mutex 变量
private static Mutex mutex = null;
public MainWindow()
{
// 检查是否已有实例在运行
bool isNewInstance;
mutex = new Mutex(true, "Global\\AuroraNote_Unique_Mutex_ID", out isNewInstance);
if (!isNewInstance)
{
// 如果不是新实例,直接关闭当前进程
MessageBox.Show("极光便签 已经在运行中。");
Application.Current.Shutdown();
return;
}
InitializeComponent();
// --- 固定文件名,不再使用随机 ID ---
// 这样重启后永远能读到上一次的笔记
filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Notes.txt");
configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Settings.ini");
LoadConfig();
LoadNote();
// 内存优化定时器
memTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(30) };
memTimer.Tick += (s, e) => ReduceMemory();
memTimer.Start();
}
// --- 核心优化:内存压缩 ---
private void ReduceMemory()
{
try
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
EmptyWorkingSet(Process.GetCurrentProcess().Handle);
}
catch { }
}
// --- 智能搜索逻辑 (F1) ---
private void SmartSearch(string query)
{
if (string.IsNullOrWhiteSpace(query)) return;
string url = query.StartsWith("http") ? query : searchEngineUrl + Uri.EscapeDataString(query);
try
{
string browser = preferEdge ? "msedge.exe" : "chrome.exe";
try { Process.Start(new ProcessStartInfo(browser, url) { UseShellExecute = true }); }
catch { Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); }
}
catch { }
}
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.F1) { SmartSearch(txtNote.SelectedText); e.Handled = true; }
}
// --- 系统热键与剪贴板处理 ---
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
IntPtr handle = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(handle).AddHook(HwndHook);
AddClipboardFormatListener(handle);
RegisterHotKey(handle, HOTKEY_ID, 0x0002 | 0x0004, currentVK); // Ctrl+Shift+Key
}
private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == 0x0312 && wParam.ToInt32() == HOTKEY_ID)
{
if (this.Visibility == Visibility.Visible) { this.Hide(); ReduceMemory(); }
else { this.Show(); this.Activate(); }
}
if (msg == 0x031D) OnClipboardChanged();
return IntPtr.Zero;
}
private async void OnClipboardChanged()
{
try
{
await Task.Delay(300); // 避开系统占用
if (Clipboard.ContainsText())
{
string txt = Clipboard.GetText();
// --- 新增逻辑:防止自循环 ---
// 如果剪贴板的内容 等于 文本框当前选中的文字,说明是你自己在便签里点的复制
// 我们需要检查 txtNote 是否被初始化,并且判断内容是否重复
bool isInternalCopy = false;
Application.Current.Dispatcher.Invoke(() => {
if (txtNote.SelectedText == txt)
{
isInternalCopy = true;
}
});
if (isInternalCopy) return; // 如果是内部复制,直接退出,不记录
// -----------------------
if (!string.IsNullOrWhiteSpace(txt) && txt != lastClipText)
{
lastClipText = txt;
txtNote.AppendText($"\n--- 采集 {DateTime.Now:HH:mm} ---\n{txt}\n");
txtNote.ScrollToEnd();
}
}
}
catch { }
}
// --- 在 MainWindow 类中添加此方法 ---
private void About_Click(object sender, RoutedEventArgs e)
{
string version = "v1.0.0";
string author = "小野"; // 这里换成你的名字或代号
string info = $"【极光便签】\n\n" +
$"版本:{version}\n" +
$"作者:{author}\n\n" +
$"LB5.NET\n\n" +
$"功能特性:\n" +
$"• 内存极致压缩技术\n" +
$"• 自定义老板键与搜索平台\n" +
$"• 智能剪贴板自动化采集\n\n" +
$"感谢使用!";
MessageBox.Show(info, "关于", MessageBoxButton.OK, MessageBoxImage.Information);
}
// --- 番茄钟逻辑 ---
private void BtnStartTimer_Click(object sender, RoutedEventArgs e)
{
if (int.TryParse(txtTimerMin.Text, out int mins))
{
if (countdownTimer != null) countdownTimer.Stop();
timeLeftSeconds = mins * 60;
lblTimer.Text = $"{mins:D2}:00";
lblTimer.Visibility = Visibility.Visible;
mainBorder.BorderBrush = Brushes.Crimson;
countdownTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
countdownTimer.Tick += (s, ev) => {
if (timeLeftSeconds > 0)
{
timeLeftSeconds--;
lblTimer.Text = $"{timeLeftSeconds / 60:D2}:{timeLeftSeconds % 60:D2}";
}
else
{
((DispatcherTimer)s).Stop();
mainBorder.BorderBrush = Brushes.Gold;
lblTimer.Visibility = Visibility.Collapsed;
this.Show(); this.Activate();
MessageBox.Show("专注时间到!");
}
};
countdownTimer.Start();
}
}
// --- 设置保存与读取 ---
private void SetSearchEngine_Click(object sender, RoutedEventArgs e)
{
searchEngineUrl = (sender as MenuItem).Tag.ToString();
UpdateMenuCheck(); SaveConfig();
}
private void SetBrowser_Click(object sender, RoutedEventArgs e)
{
preferEdge = (sender == menuEdge);
UpdateMenuCheck(); SaveConfig();
}
private void SetHotkey_Click(object sender, RoutedEventArgs e)
{
currentVK = (uint)KeyInterop.VirtualKeyFromKey((Key)Enum.Parse(typeof(Key), (sender as MenuItem).Tag.ToString()));
SaveConfig(); MessageBox.Show("老板键已更改,重启后生效。");
}
private void UpdateMenuCheck()
{
menuBing.IsChecked = searchEngineUrl.Contains("bing");
menuBaidu.IsChecked = searchEngineUrl.Contains("baidu");
menuGoogle.IsChecked = searchEngineUrl.Contains("google");
menuSogou.IsChecked = searchEngineUrl.Contains("sogou");
menuEdge.IsChecked = preferEdge; menuChrome.IsChecked = !preferEdge;
}
private void SaveConfig() => File.WriteAllText(configPath, $"{currentVK}|{preferEdge}|{searchEngineUrl}");
private void LoadConfig()
{
if (File.Exists(configPath))
{
try
{
var p = File.ReadAllText(configPath).Split('|');
if (p.Length >= 3) { currentVK = uint.Parse(p[0]); preferEdge = bool.Parse(p[1]); searchEngineUrl = p[2]; }
}
catch { }
}
UpdateMenuCheck();
}
// --- 基础交互逻辑 ---
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control)
{
this.Opacity = e.Delta > 0 ? Math.Min(1.0, this.Opacity + 0.1) : Math.Max(0.2, this.Opacity - 0.1);
e.Handled = true;
}
}
private void BtnSkin_Click(object sender, RoutedEventArgs e)
{
string[] c = { "#DD222222", "#DD1E3A5F", "#DD2D5A27", "#DD4B0082" };
skinIndex = (skinIndex + 1) % c.Length;
mainBorder.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(c[skinIndex]));
}
private void BtnPin_Click(object sender, RoutedEventArgs e) { this.Topmost = !this.Topmost; btnPin.Foreground = this.Topmost ? Brushes.Cyan : Brushes.Gray; }
private void BtnClose_Click(object sender, RoutedEventArgs e) => this.Close();
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) this.DragMove(); }
private void ClearAll_Click(object sender, RoutedEventArgs e) => txtNote.Clear();
private void BtnSearch_Click(object sender, RoutedEventArgs e) => SmartSearch(txtNote.SelectedText);
private void LoadNote() { if (File.Exists(filePath)) txtNote.Text = File.ReadAllText(filePath); }
private void txtNote_TextChanged(object sender, TextChangedEventArgs e) { try { File.WriteAllText(filePath, txtNote.Text); } catch { } }
}
}