添加防止锁屏工具 - Python和Rust版本
This commit is contained in:
305
anti_lockscreen_rust/src/main.rs
Normal file
305
anti_lockscreen_rust/src/main.rs
Normal file
@@ -0,0 +1,305 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use eframe::{egui, App, Frame, NativeOptions};
|
||||
use egui::{FontFamily, FontId, RichText, Vec2, Color32, Rounding, Stroke};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
use winapi::um::winuser::{GetCursorPos, SetCursorPos, INPUT, INPUT_MOUSE, MOUSEINPUT, SendInput};
|
||||
use winapi::shared::windef::POINT;
|
||||
use rand::Rng;
|
||||
use chrono::Local;
|
||||
|
||||
// 应用程序状态
|
||||
#[derive(Clone)]
|
||||
struct AppState {
|
||||
running: Arc<Mutex<bool>>,
|
||||
interval: Arc<Mutex<u64>>, // 间隔秒数
|
||||
log_message: Arc<Mutex<String>>,
|
||||
last_action: Arc<Mutex<Instant>>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
fn new() -> Self {
|
||||
AppState {
|
||||
running: Arc::new(Mutex::new(false)),
|
||||
interval: Arc::new(Mutex::new(30)),
|
||||
log_message: Arc::new(Mutex::new(String::from("准备就绪"))),
|
||||
last_action: Arc::new(Mutex::new(Instant::now())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟鼠标微动
|
||||
fn simulate_mouse_move() -> Result<(i32, i32), String> {
|
||||
unsafe {
|
||||
let mut point = POINT { x: 0, y: 0 };
|
||||
if GetCursorPos(&mut point) == 0 {
|
||||
return Err("无法获取鼠标位置".to_string());
|
||||
}
|
||||
|
||||
let current_x = point.x;
|
||||
let current_y = point.y;
|
||||
|
||||
// 随机微动 1-3 像素
|
||||
let mut rng = rand::thread_rng();
|
||||
let offset_x: i32 = if rng.gen_bool(0.5) { 1 } else { -1 } * rng.gen_range(1..=3);
|
||||
let offset_y: i32 = if rng.gen_bool(0.5) { 1 } else { -1 } * rng.gen_range(1..=3);
|
||||
|
||||
let new_x = current_x + offset_x;
|
||||
let new_y = current_y + offset_y;
|
||||
|
||||
// 移动鼠标到新位置
|
||||
if SetCursorPos(new_x, new_y) == 0 {
|
||||
return Err("无法移动鼠标".to_string());
|
||||
}
|
||||
|
||||
// 短暂延迟后移回原位
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
|
||||
if SetCursorPos(current_x, current_y) == 0 {
|
||||
return Err("无法恢复鼠标位置".to_string());
|
||||
}
|
||||
|
||||
Ok((offset_x, offset_y))
|
||||
}
|
||||
}
|
||||
|
||||
// 后台工作线程
|
||||
fn worker_thread(state: AppState) {
|
||||
let mut last_move = Instant::now();
|
||||
|
||||
loop {
|
||||
let running = *state.running.lock().unwrap();
|
||||
if !running {
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
let interval = *state.interval.lock().unwrap();
|
||||
let elapsed = last_move.elapsed().as_secs();
|
||||
|
||||
if elapsed >= interval {
|
||||
match simulate_mouse_move() {
|
||||
Ok((offset_x, offset_y)) => {
|
||||
let time_str = Local::now().format("%H:%M:%S").to_string();
|
||||
let msg = format!("{} - 鼠标微动: ({}, {})", time_str, offset_x, offset_y);
|
||||
*state.log_message.lock().unwrap() = msg;
|
||||
}
|
||||
Err(e) => {
|
||||
let time_str = Local::now().format("%H:%M:%S").to_string();
|
||||
let msg = format!("{} - 错误: {}", time_str, e);
|
||||
*state.log_message.lock().unwrap() = msg;
|
||||
}
|
||||
}
|
||||
last_move = Instant::now();
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
// 主应用程序结构
|
||||
struct AntiLockScreenApp {
|
||||
state: AppState,
|
||||
interval_input: String,
|
||||
}
|
||||
|
||||
impl AntiLockScreenApp {
|
||||
fn new() -> Self {
|
||||
AntiLockScreenApp {
|
||||
state: AppState::new(),
|
||||
interval_input: "30".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App for AntiLockScreenApp {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut Frame) {
|
||||
// 中文字体在第一次更新时加载
|
||||
static FONT_LOADED: std::sync::Once = std::sync::Once::new();
|
||||
FONT_LOADED.call_once(|| {
|
||||
let mut fonts = egui::FontDefinitions::default();
|
||||
|
||||
// 尝试从系统加载中文字体
|
||||
let font_paths = [
|
||||
"C:/Windows/Fonts/msyh.ttc", // 微软雅黑
|
||||
"C:/Windows/Fonts/simhei.ttf", // 黑体
|
||||
"C:/Windows/Fonts/simsun.ttc", // 宋体
|
||||
"C:/Windows/Fonts/msgothic.ttc", // 日文哥特体(备用)
|
||||
];
|
||||
|
||||
for font_path in &font_paths {
|
||||
if let Ok(font_data) = std::fs::read(font_path) {
|
||||
fonts.font_data.insert(
|
||||
"chinese_font".to_owned(),
|
||||
egui::FontData::from_owned(font_data),
|
||||
);
|
||||
|
||||
// 更新字体族
|
||||
fonts.families.get_mut(&egui::FontFamily::Proportional)
|
||||
.unwrap()
|
||||
.insert(0, "chinese_font".to_owned());
|
||||
|
||||
fonts.families.get_mut(&egui::FontFamily::Monospace)
|
||||
.unwrap()
|
||||
.push("chinese_font".to_owned());
|
||||
|
||||
ctx.set_fonts(fonts);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 主窗口
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.add_space(20.0);
|
||||
|
||||
// 标题
|
||||
ui.label(
|
||||
RichText::new("防止锁屏工具")
|
||||
.font(FontId::new(24.0, FontFamily::Proportional))
|
||||
.strong()
|
||||
.color(Color32::from_rgb(51, 51, 51))
|
||||
);
|
||||
|
||||
ui.add_space(15.0);
|
||||
|
||||
// 说明文字
|
||||
ui.label(
|
||||
RichText::new("点击开始后,程序会定期模拟鼠标微动")
|
||||
.font(FontId::new(12.0, FontFamily::Proportional))
|
||||
.color(Color32::from_rgb(102, 102, 102))
|
||||
);
|
||||
|
||||
ui.label(
|
||||
RichText::new("防止系统自动锁屏")
|
||||
.font(FontId::new(12.0, FontFamily::Proportional))
|
||||
.color(Color32::from_rgb(102, 102, 102))
|
||||
);
|
||||
|
||||
ui.add_space(20.0);
|
||||
|
||||
// 间隔设置
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(
|
||||
RichText::new("微动间隔(秒):")
|
||||
.font(FontId::new(12.0, FontFamily::Proportional))
|
||||
);
|
||||
|
||||
let running = *self.state.running.lock().unwrap();
|
||||
ui.add_enabled_ui(!running, |ui| {
|
||||
ui.text_edit_singleline(&mut self.interval_input);
|
||||
});
|
||||
});
|
||||
|
||||
ui.add_space(15.0);
|
||||
|
||||
// 状态显示
|
||||
let running = *self.state.running.lock().unwrap();
|
||||
let status_text = if running { "状态: 运行中" } else { "状态: 已停止" };
|
||||
let status_color = if running {
|
||||
Color32::from_rgb(76, 175, 80)
|
||||
} else {
|
||||
Color32::from_rgb(244, 67, 54)
|
||||
};
|
||||
|
||||
ui.label(
|
||||
RichText::new(status_text)
|
||||
.font(FontId::new(14.0, FontFamily::Proportional))
|
||||
.color(status_color)
|
||||
);
|
||||
|
||||
ui.add_space(10.0);
|
||||
|
||||
// 日志消息
|
||||
let log_msg = self.state.log_message.lock().unwrap().clone();
|
||||
ui.label(
|
||||
RichText::new(&log_msg)
|
||||
.font(FontId::new(10.0, FontFamily::Proportional))
|
||||
.color(Color32::from_rgb(128, 128, 128))
|
||||
);
|
||||
|
||||
ui.add_space(20.0);
|
||||
|
||||
// 按钮区域
|
||||
ui.horizontal(|ui| {
|
||||
// 开始按钮
|
||||
let start_btn = ui.add_sized(
|
||||
[100.0, 40.0],
|
||||
egui::Button::new(
|
||||
RichText::new("开始")
|
||||
.font(FontId::new(14.0, FontFamily::Proportional))
|
||||
.color(Color32::WHITE)
|
||||
)
|
||||
.fill(Color32::from_rgb(76, 175, 80))
|
||||
.rounding(Rounding::same(5.0))
|
||||
);
|
||||
|
||||
if start_btn.clicked() && !running {
|
||||
// 解析间隔时间
|
||||
if let Ok(interval) = self.interval_input.parse::<u64>() {
|
||||
if interval >= 10 && interval <= 300 {
|
||||
*self.state.interval.lock().unwrap() = interval;
|
||||
*self.state.running.lock().unwrap() = true;
|
||||
*self.state.log_message.lock().unwrap() = "防止锁屏已启动".to_string();
|
||||
} else {
|
||||
*self.state.log_message.lock().unwrap() = "间隔必须在10-300秒之间".to_string();
|
||||
}
|
||||
} else {
|
||||
*self.state.log_message.lock().unwrap() = "请输入有效的数字".to_string();
|
||||
}
|
||||
}
|
||||
|
||||
ui.add_space(20.0);
|
||||
|
||||
// 停止按钮
|
||||
let stop_btn = ui.add_sized(
|
||||
[100.0, 40.0],
|
||||
egui::Button::new(
|
||||
RichText::new("停止")
|
||||
.font(FontId::new(14.0, FontFamily::Proportional))
|
||||
.color(Color32::WHITE)
|
||||
)
|
||||
.fill(Color32::from_rgb(244, 67, 54))
|
||||
.rounding(Rounding::same(5.0))
|
||||
);
|
||||
|
||||
if stop_btn.clicked() && running {
|
||||
*self.state.running.lock().unwrap() = false;
|
||||
*self.state.log_message.lock().unwrap() = "防止锁屏已停止".to_string();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 请求连续更新以刷新UI
|
||||
ctx.request_repaint_after(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), eframe::Error> {
|
||||
// 启动后台工作线程
|
||||
let state = AppState::new();
|
||||
let worker_state = state.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
worker_thread(worker_state);
|
||||
});
|
||||
|
||||
// 应用程序选项
|
||||
let options = NativeOptions {
|
||||
viewport: egui::ViewportBuilder::default()
|
||||
.with_inner_size([400.0, 280.0])
|
||||
.with_resizable(false),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// 运行应用程序
|
||||
eframe::run_native(
|
||||
"防止锁屏工具",
|
||||
options,
|
||||
Box::new(|_cc| Box::new(AntiLockScreenApp::new())),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user