pandaligx 发表于 2024-9-23 20:04

快捷设置分辨率刷新率与缩放比为100%

介绍
做这个软件是为了方便快捷的设置屏幕:分辨率-刷新率-屏幕缩放比为100%

原因
有部分人因修改了系统缩放比导致屏幕很大,无法还原,甚至需要重装系统,所以才做这个东西


下载地址
快捷设置分辨率刷新率与缩放比.exe

提示
无界面,只有设置完成以后会弹出GUI提示窗口

源码
#!

use fltk::{app, dialog};
use std::ffi::CString;
use std::fs;
use std::process::Command;
use std::ptr::null_mut;

extern crate winapi;
use winapi::um::fileapi::GetTempPathA;
use winapi::um::wingdi::{DEVMODEA, DISPLAY_DEVICEA, DISPLAY_DEVICE_ACTIVE};
use winapi::um::wininet::{InternetCloseHandle, InternetOpenA, InternetOpenUrlA, InternetReadFile};
use winapi::um::winuser::{ChangeDisplaySettingsExA, EnumDisplayDevicesA, EnumDisplaySettingsA, CDS_UPDATEREGISTRY};
use winapi::um::wincon::SetConsoleOutputCP;
use winapi::shared::minwindef::DWORD;
use std::io::Write;

fn set_best_display_settings_for_monitor(device_name: &str) -> String {
    let mut result_message = String::new();
    unsafe {
      let mut dm: DEVMODEA = std::mem::zeroed();
      let mut best_mode: DEVMODEA = std::mem::zeroed();
      dm.dmSize = std::mem::size_of::<DEVMODEA>() as u16;
      best_mode.dmSize = std::mem::size_of::<DEVMODEA>() as u16;

      let device_name_c = CString::new(device_name).unwrap();
      let device_name_ptr = device_name_c.as_ptr();
      
      let mut i_mode_num: DWORD = 0;
      let mut best_width: DWORD = 0;
      let mut best_height: DWORD = 0;
      let mut best_refresh_rate: DWORD = 0;

      // 枚举所有的显示模式来找到最大的分辨率和刷新率
      while EnumDisplaySettingsA(device_name_ptr, i_mode_num, &mut dm) != 0 {
            if dm.dmPelsWidth >= best_width && dm.dmPelsHeight >= best_height &&
                dm.dmDisplayFrequency >= best_refresh_rate {
                best_width = dm.dmPelsWidth;
                best_height = dm.dmPelsHeight;
                best_refresh_rate = dm.dmDisplayFrequency;
                best_mode = dm;
            }
            i_mode_num += 1;
      }

      if best_width != 0 && best_height != 0 {
            // 设置找到的分辨率和刷新率,并更新注册表
            let result = ChangeDisplaySettingsExA(device_name_ptr, &mut best_mode, null_mut(), CDS_UPDATEREGISTRY, null_mut());
            if result == 0 {
                result_message.push_str(&format!(
                  "显示设备 {} 的显示设置已成功更改为 {}x{} @ {}Hz。\n",
                  device_name, best_width, best_height, best_refresh_rate
                ));
            } else {
                result_message.push_str(&format!(
                  "无法更改显示设备 {} 的显示设置。错误代码: {}\n",
                  device_name, result
                ));
            }
      } else {
            result_message.push_str(&format!(
                "未找到适合的模式用于显示设备 {}。\n",
                device_name
            ));
      }
    }
    result_message
}

fn download_file(url: &str, destination: &str) -> bool {
    unsafe {
      let agent = CString::new(
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
      )
      .unwrap();
      let url_c = CString::new(url).unwrap();

      let h_internet = InternetOpenA(agent.as_ptr(), 1, null_mut(), null_mut(), 0);
      if h_internet.is_null() {
            return false;
      }

      let h_url = InternetOpenUrlA(h_internet, url_c.as_ptr(), null_mut(), 0, 0, 0);
      if h_url.is_null() {
            InternetCloseHandle(h_internet);
            return false;
      }

      let mut buffer = vec!;
      let mut bytes_read: DWORD = 0;
      let mut file = match fs::File::create(destination) {
            Ok(f) => f,
            Err(_) => {
                InternetCloseHandle(h_url);
                InternetCloseHandle(h_internet);
                return false;
            }
      };

      loop {
            let result = InternetReadFile(h_url, buffer.as_mut_ptr() as *mut _, buffer.len() as DWORD, &mut bytes_read);
            if result == 0 || bytes_read == 0 {
                break;
            }
            file.write_all(&buffer[..bytes_read as usize]).unwrap();
      }

      InternetCloseHandle(h_url);
      InternetCloseHandle(h_internet);

      true
    }
}

fn download_and_run_set_dpi() -> String {
    let mut result_message = String::new();
    unsafe {
      let mut temp_path: = ;
      GetTempPathA(temp_path.len() as u32, temp_path.as_mut_ptr());

      let temp_path_str = std::ffi::CStr::from_ptr(temp_path.as_ptr()).to_str().unwrap_or("");
      let set_dpi_path = format!("{}SetDpi.exe", temp_path_str);

      if download_file("URL/SetDpi.exe", &set_dpi_path) {
            result_message.push_str(&format!("SetDpi.exe 已成功下载到 {}\n", set_dpi_path));

            let output = Command::new(&set_dpi_path)
                .arg("100")
                .output()
                .expect("failed to execute process");

            if output.status.success() {
                result_message.push_str("SetDpi.exe 执行成功。\n");
            }

            if fs::remove_file(&set_dpi_path).is_ok() {
                result_message.push_str("SetDpi.exe 已删除。\n");
            } else {
                result_message.push_str("无法删除 SetDpi.exe。\n");
            }

      } else {
            result_message.push_str("无法下载 SetDpi.exe。\n");
      }
    }
    result_message
}

fn main() {
    // 设置控制台代码页为 65001 (UTF-8)
    unsafe {
      SetConsoleOutputCP(65001);
    }

    let mut dd: DISPLAY_DEVICEA = unsafe { std::mem::zeroed() };
    dd.cb = std::mem::size_of::<DISPLAY_DEVICEA>() as DWORD;
    let mut device_index = 0;
    let mut result_message = String::new();

    // 枚举所有显示器
    while unsafe { EnumDisplayDevicesA(null_mut(), device_index, &mut dd, 0) } != 0 {
      if dd.StateFlags & DISPLAY_DEVICE_ACTIVE != 0 {
            let device_name = unsafe { std::ffi::CStr::from_ptr(dd.DeviceName.as_ptr()).to_string_lossy().into_owned() };
            result_message.push_str(&format!("显示设备 {}: {}\n", device_index, device_name));
            result_message.push_str(&set_best_display_settings_for_monitor(&device_name));
      }
      device_index += 1;
    }

    // 下载并运行 SetDpi.exe
    result_message.push_str(&download_and_run_set_dpi());

    // 创建FLTK应用程序
    let app = app::App::default();

    // 显示结果提示对话框
    dialog::message(200, 200, &result_message);

    app.run().unwrap();
}

pandaligx 发表于 2024-9-24 23:08

帮忙删帖吧,版主,搞错区了
页: [1]
查看完整版本: 快捷设置分辨率刷新率与缩放比为100%