forms實現快讀閱讀器

forms實現快讀閱讀器

主要功能包括:
??1.文本自動分塊顯示??:按設定的速度逐詞顯示文本內容。
??2.閱讀控制??:開始/停止按鈕以及回車鍵控制。
??3.界面自定義??:包括字體、顏色(前景色和背景色)的設置。
??4.暗黑模式??:支持暗黑主題,并有相應的渲染器。
??5.全屏模式??:通過F11或按鈕切換全屏。
??6.速度調節??:通過WPM(每分鐘字數)數值調節器控制顯示速度。
??7.循環閱讀??:復選框控制是否循環閱讀。
??8.設置持久化??:保存用戶的設置(如字體、顏色、速度等)到配置文件。
??9.文件自動加載??:從固定路徑加載文本文件。
??10.錯誤處理??:文件不存在或內容為空時的提示。
說明:
C:\Users\wangrusheng\AppData\Roaming\WinFormsApp38\settings.json
這個目錄下,有一個json配置文件 主要配置字體,字體顏色,背景顏色,閱讀速度等,第一次運行會自動生成
效果圖:
在這里插入圖片描述

step1:
C:\Users\wangrusheng\RiderProjects\WinFormsApp38\WinFormsApp38\Form1.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Newtonsoft.Json;namespace WinFormsApp38
{public partial class Form1 : Form{private const string FixedFilePath = @"C:\Users\wangrusheng\Downloads\ages.txt";private Settings settings;private System.Windows.Forms.Timer timer;private List<string> tokens;private int currentIndex;private FormWindowState lastWindowState;private Color currentForeground;private Color currentBackground;// 控件聲明private Label lblText;private ToolStrip toolStrip;private ToolStripButton btnFullScreen;private ToolStripButton btnColors;private ToolStripButton btnFont;private ToolStripButton btnStart;private NumericUpDown numWPM;private CheckBox chkRepeat;public Form1(){InitializeComponent();InitializeDynamicComponents();settings = Settings.Load();LoadSettings();SetupEventHandlers();ApplyDarkTheme();}private void InitializeDynamicComponents(){// 主標簽初始化lblText = new Label{Dock = DockStyle.Fill,TextAlign = ContentAlignment.MiddleCenter,Font = new Font("微軟雅黑", 24)};// 工具欄初始化toolStrip = new ToolStrip{Renderer = new DarkToolStripRenderer(),GripStyle = ToolStripGripStyle.Hidden};// 工具欄按鈕btnFullScreen = new ToolStripButton("全屏 (F11)");btnColors = new ToolStripButton("顏色");btnFont = new ToolStripButton("字體");btnStart = new ToolStripButton("開始 (Enter)");// 速度控件numWPM = new NumericUpDown{Minimum = 50,Maximum = 1000,Value = 150,Width = 80,DecimalPlaces = 0,ForeColor = Color.White,BackColor = Color.FromArgb(45, 45, 45)};// 循環復選框chkRepeat = new CheckBox{Text = "循環閱讀",AutoSize = true,ForeColor = Color.White,BackColor = Color.FromArgb(45, 45, 45),FlatStyle = FlatStyle.Flat};// 添加工具欄項toolStrip.Items.AddRange(new ToolStripItem[]{btnFullScreen,btnColors,btnFont,new ToolStripSeparator(),new ToolStripLabel("速度:") { ForeColor = Color.White },new ToolStripControlHost(numWPM),new ToolStripControlHost(chkRepeat),new ToolStripSeparator(),btnStart});// 窗體設置Controls.Add(lblText);Controls.Add(toolStrip);Text = "快速閱讀器";Size = new Size(1200, 600);KeyPreview = true;// WindowState = FormWindowState.Maximized; 自動全屏功能FormBorderStyle = FormWindowState.Maximized == WindowState ? FormBorderStyle.None : FormBorderStyle.Sizable;DoubleBuffered = true;// 定時器timer = new System.Windows.Forms.Timer { Interval = 60000 / 150 };}private void LoadSettings(){currentForeground = settings.ForegroundColor;currentBackground = settings.BackgroundColor;lblText.Font = settings.TextFont;numWPM.Value = settings.WPM;chkRepeat.Checked = settings.Repeat;UpdateLabelAppearance();}private void ApplyDarkTheme(){// 強制使用暗黑主題色currentForeground = Color.White;currentBackground = Color.FromArgb(30, 30, 30);// 主窗體顏色BackColor = currentBackground;ForeColor = currentForeground;// 工具欄樣式toolStrip.BackColor = Color.FromArgb(45, 45, 45);toolStrip.ForeColor = Color.White;// 工具欄按鈕樣式foreach (ToolStripItem item in toolStrip.Items){if (item is ToolStripButton btn){btn.BackColor = Color.FromArgb(45, 45, 45);btn.ForeColor = Color.White;}}// 數值控件numWPM.BackColor = Color.FromArgb(60, 60, 60);numWPM.ForeColor = Color.White;numWPM.BorderStyle = BorderStyle.FixedSingle;// 復選框chkRepeat.BackColor = Color.FromArgb(60, 60, 60);chkRepeat.ForeColor = Color.White;chkRepeat.FlatAppearance.CheckedBackColor = Color.FromArgb(30, 30, 30);UpdateLabelAppearance(); // 強制更新標簽顏色}private void SetupEventHandlers(){btnStart.Click += BtnStart_Click;btnFont.Click += BtnFont_Click;btnColors.Click += BtnColors_Click;btnFullScreen.Click += BtnFullScreen_Click;numWPM.ValueChanged += NumWPM_ValueChanged;timer.Tick += Timer_Tick;KeyDown += Form1_KeyDown;// 自定義繪制事件numWPM.Paint += (s, e) => ControlPaint.DrawBorder(e.Graphics, numWPM.ClientRectangle, Color.Gray, ButtonBorderStyle.Solid);chkRepeat.Paint += (s, e) => {e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(60, 60, 60)), e.ClipRectangle);TextRenderer.DrawText(e.Graphics, chkRepeat.Text, chkRepeat.Font, new Point(20, 0), chkRepeat.Checked ? Color.Lime : Color.White);};}private void UpdateLabelAppearance(){lblText.BackColor = currentBackground;lblText.ForeColor = currentForeground;}// [事件處理方法保持不變,與原始代碼相同]// ... 包括 BtnStart_Click, BtnFont_Click 等其他事件處理方法 ...private void BtnStart_Click(object sender, EventArgs e){if (timer.Enabled){timer.Stop();btnStart.Text = "開始 (Enter)";}else{try{string text = File.ReadAllText(FixedFilePath);tokens = new List<string>(text.Split(new[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries));currentIndex = 0;timer.Interval = 60000 / (int)numWPM.Value;timer.Start();btnStart.Text = "停止 (Enter)";}catch (Exception ex){MessageBox.Show($"讀取文件失敗: {ex.Message}");}}}private void BtnFont_Click(object sender, EventArgs e){using (FontDialog fontDialog = new FontDialog()){fontDialog.Font = lblText.Font;if (fontDialog.ShowDialog() == DialogResult.OK){lblText.Font = fontDialog.Font;settings.TextFont = fontDialog.Font;}}}private void BtnColors_Click(object sender, EventArgs e){// 前景色using (ColorDialog colorDialog = new ColorDialog()){colorDialog.Color = currentForeground;if (colorDialog.ShowDialog() == DialogResult.OK){currentForeground = colorDialog.Color;lblText.ForeColor = currentForeground;settings.ForegroundColor = currentForeground;}}// 背景色using (ColorDialog colorDialog = new ColorDialog()){colorDialog.Color = currentBackground;if (colorDialog.ShowDialog() == DialogResult.OK){currentBackground = colorDialog.Color;lblText.BackColor = currentBackground;settings.BackgroundColor = currentBackground;}}}private void NumWPM_ValueChanged(object sender, EventArgs e){settings.WPM = (int)numWPM.Value;timer.Interval = 60000 / (int)numWPM.Value;}private void Timer_Tick(object sender, EventArgs e){if (currentIndex < tokens.Count){lblText.Text = tokens[currentIndex];currentIndex++;}else if (chkRepeat.Checked){currentIndex = 0;}else{timer.Stop();btnStart.Text = "開始";}}private void ToggleFullscreen(){if (WindowState == FormWindowState.Maximized){WindowState = lastWindowState;FormBorderStyle = FormBorderStyle.Sizable;}else{lastWindowState = WindowState;WindowState = FormWindowState.Maximized;FormBorderStyle = FormBorderStyle.None;}}private void BtnFullScreen_Click(object sender, EventArgs e){ToggleFullscreen();}private void Form1_KeyDown(object sender, KeyEventArgs e){if (e.KeyCode == Keys.F11){ToggleFullscreen();}else if (e.KeyCode == Keys.Enter){BtnStart_Click(sender, e);}}// 修改保存觸發點protected override void OnFormClosing(FormClosingEventArgs e){settings.ForegroundColor = currentForeground;settings.BackgroundColor = currentBackground;settings.Save();base.OnFormClosing(e);}// 暗黑主題渲染器private class DarkToolStripRenderer : ToolStripProfessionalRenderer{public DarkToolStripRenderer() : base(new DarkColorTable()) {RoundedEdges = false;}protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e){if (e.Item.Selected){e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(60, 60, 60)), e.Item.ContentRectangle);}else{base.OnRenderButtonBackground(e);}}}private class DarkColorTable : ProfessionalColorTable{public override Color ToolStripDropDownBackground => Color.FromArgb(45, 45, 45);public override Color MenuItemSelected => Color.FromArgb(60, 60, 60);public override Color MenuItemBorder => Color.FromArgb(30, 30, 30);public override Color MenuBorder => Color.FromArgb(45, 45, 45);public override Color ToolStripBorder => Color.FromArgb(45, 45, 45);public override Color ImageMarginGradientBegin => Color.FromArgb(45, 45, 45);public override Color ImageMarginGradientMiddle => Color.FromArgb(45, 45, 45);public override Color ImageMarginGradientEnd => Color.FromArgb(45, 45, 45);public override Color MenuItemPressedGradientBegin => Color.FromArgb(45, 45, 45);public override Color MenuItemPressedGradientMiddle => Color.FromArgb(45, 45, 45);public override Color MenuItemPressedGradientEnd => Color.FromArgb(45, 45, 45);public override Color ButtonSelectedBorder => Color.FromArgb(60, 60, 60);public override Color ButtonSelectedGradientBegin => Color.FromArgb(60, 60, 60);public override Color ButtonSelectedGradientMiddle => Color.FromArgb(60, 60, 60);public override Color ButtonSelectedGradientEnd => Color.FromArgb(60, 60, 60);public override Color CheckBackground => Color.FromArgb(30, 30, 30);public override Color CheckPressedBackground => Color.FromArgb(60, 60, 60);public override Color CheckSelectedBackground => Color.FromArgb(60, 60, 60);}}// [保留Settings類代碼,與原始代碼相同]public class Settings{// 序列化用的中間結構public class SerializableFont{public string FontFamily { get; set; }public float FontSize { get; set; }public FontStyle FontStyle { get; set; }}// 將Color轉換為字符串表示public string ForegroundColorHex { get; set; }public string BackgroundColorHex { get; set; }// 字體使用可序列化的中間類型public SerializableFont TextFontData { get; set; }public int WPM { get; set; } = 66;public bool Repeat { get; set; }[JsonIgnore] // 忽略實際使用的Font類型public Font TextFont{get => new Font(TextFontData.FontFamily,TextFontData.FontSize,TextFontData.FontStyle);set => TextFontData = new SerializableFont{FontFamily = value.FontFamily.Name,FontSize = value.Size,FontStyle = value.Style};}[JsonIgnore]public Color ForegroundColor{get => ColorTranslator.FromHtml(ForegroundColorHex);set => ForegroundColorHex = ColorTranslator.ToHtml(value);}[JsonIgnore]public Color BackgroundColor{get => ColorTranslator.FromHtml(BackgroundColorHex);set => BackgroundColorHex = ColorTranslator.ToHtml(value);}private static string ConfigPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"WinFormsApp38","settings.json");public void Save(){try{var dir = Path.GetDirectoryName(ConfigPath);if (!Directory.Exists(dir))Directory.CreateDirectory(dir);File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(this));}catch (Exception ex){MessageBox.Show($"保存設置失敗: {ex.Message}");}}public static Settings Load(){try{if (File.Exists(ConfigPath)){var content = File.ReadAllText(ConfigPath);return JsonConvert.DeserializeObject<Settings>(content);}}catch (Exception ex){MessageBox.Show($"加載設置失敗: {ex.Message}");}// 返回默認設置var defaults = new Settings{ForegroundColor = Color.White,BackgroundColor = Color.FromArgb(30, 30, 30), // 改為暗黑背景色TextFont = new Font("微軟雅黑", 24)};defaults.Save(); // 創建默認配置文件return defaults;}}}

end

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75805.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75805.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75805.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PowerBI 條形圖顯示數值和百分比

數據表: 三個度量值 銷售額 VAR Sales SUM(銷量表[銷售量]) RETURNIF(ISBLANK(sales), 0, sales) //希望Y軸顯示所有產品(沒有記錄顯示0)就加這個代碼&#xff0c;不希望顯示就不加//注意, 因為Y軸顯示的產品&#xff0c;會被篩選&#xff0c;所以用ALLSELECTED來獲取當前篩…

python: audioFlux XXCC 提取梅爾頻率倒譜系數 MFCC

承上一篇&#xff1a;python&#xff1a;audioFlux 使用教程 XXCC: 倒譜系數&#xff0c;支持所有頻譜類型. 可以提取梅爾頻率倒譜系數&#xff08;MFCC&#xff09; Cepstrum coefficients, supports all spectrum types. 以下是使用 audioflux 庫中 XXCC 類計算倒譜系數…

為 docker 拉取鏡像配置代理

為 Docker 配置代理&#xff0c;有 兩個層面 的操作&#xff1a;(1) Docker 守護進程&#xff08;用于拉取鏡像等操作&#xff09;&#xff0c;(2) Docker 容器內部&#xff08;容器內應用的網絡流量&#xff09;。 我們這篇文章著重于前者&#xff0c;以下是詳細步驟&#xff…

最新的es版本忘記密碼,重置密碼

剛剛安裝了最新的es版本,就忘了密碼,怎么重置密碼呢? 一、進入es的斌目錄 #進入es文件/bin 目錄 ./elasticsearch-reset-password -u elastic 二 、輸入對應的密碼 然后再次訪問 我的是去掉了ssl的訪問 三、如果報錯:解決 [main] WARN

cursor如何集成MCP服務

本文主要介紹 Cursor IDE 是如何通過 Model Context Protocol (MCP) 服務來增強其功能的。本文將重點介紹兩個核心 MCP 服務的集成&#xff1a;GitHub MCP 服務和 Filesystem MCP 服務。 MCP 服務簡介 MCP&#xff08;Model Context Protocol&#xff09;是一個允許 IDE 與各…

Linux LED驅動(gpio子系統)

0. gpio子系統 gpio子系統是linux內核當中用于管理GPIO資源的一套系統&#xff0c;它提供了很多GPIO相關的API接口&#xff0c;驅動程序中使用GPIO之前需要向gpio子系統申請。 gpio子系統的主要目的就是方便驅動開發者使用gpio&#xff0c;驅動開發者在設備樹中添加gpio相關信息…

go中new和make有什么異同?

相同點&#xff1a;都是給變量分配內存 不同點&#xff1a; 作用類型不同。new通常給int、string、數組類型的變量分配內存&#xff0c;而make通常給slice、map、channel分配內存。返回值類型不同。new返回指向變量的指針&#xff0c;make返回的是變量本身new分配內存空間后&…

C/C++基礎知識點

隨著工作中瑣事越來越多&#xff0c;靜下來好好敲代碼的時間越來越少&#xff0c;基礎知識雖然簡單&#xff0c;但常看常新&#xff0c;并記錄下來共勉。 一、基礎知識點 1. 內存區域中數據管理 在C和C中&#xff0c;內存分為多個區域&#xff0c;每個區域負責存儲不同類型的…

消息中間件kafka,rabbitMQ

在分布式系統中,消息中間件是實現不同組件之間異步通信的關鍵技術。Kafka 和 RabbitMQ 是兩個非常流行的消息中間件系統,它們各自有著不同的特點和應用場景。下面將分別介紹 Kafka 和 RabbitMQ,并討論它們在消息隊列中的使用。 一、Kafka (Apache Kafka) 主要特點: 高吞吐…

2k1000LA , 調試串口改成通信串口, uart.

客戶的問題解決了&#xff0c;但是 調試串口 改成通信串口的問題&#xff0c;并沒有解決&#xff0c;我走的其他的路徑。 先準備一些資料。 以備以后使用。 網上的資料。 總結&#xff1a; 實際上 有幾種思路了。 1 就是更改 設備樹的 chosen 節點&#xff0c; 瑞芯微又單獨…

springboot集成spring-cloud-context手動刷新并讀取更新后的配置文件

背景 springboot單體項目在運行過程需要刷新springboot配置文件值&#xff0c;比如某個接口限流閾值&#xff0c;新增某個賬戶等場景。分布式設計的可以直接引入一些持久化中間件比如redis等&#xff0c;也可以用相關配置中心中間件如nacos等。處于成本等場景單體項目可以考慮①…

proteus8.17 環境配置

Proteus介紹 Proteus 8.17 是一款功能強大的電子設計自動化&#xff08;EDA&#xff09;軟件&#xff0c;廣泛應用于電子電路設計、仿真和分析。以下是其主要特點和新功能&#xff1a; ### 主要功能 - **電路仿真**&#xff1a;支持數字和模擬電路的仿真&#xff0c;包括靜態…

手機端可部署的開源大模型; 通義千問2.5訓練和推理需要的內存和外存

手機端可部署的開源大模型 目錄 手機端可部署的開源大模型Qwen2.5 0.5B 7b 推理采用手機內存需要多少Qwen2.5 0.5B不同量化精度下的內存需求Qwen2.5 7B不同量化精度下的內存需求通義千問2.5訓練和推理需要的內存和外存推理階段1. Qwen2.5 - 7B2. Qwen2.5 - 14B3. Qwen2.5 - 72B…

【uniapp-兼容性處理】swiper在iOS上偶發出現后幾張圖片白屏情況

【日期】2025-04-14 【問題】 swiper在iOS上偶發出現后幾張圖片白屏情況 swiper內部的幾個swiper-item垂直排列&#xff0c;各自進行滾動&#xff0c;樣式方面兼容性出現問題 【原因】&#xff1a; 原代碼&#xff1a;&#xff08;不應在swiper-item添加style屬性&#xf…

SpringBoot連接MQTT客戶端

引入依賴 <dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId><version>1.2.2</version> </dependency> 啟動類 SpringBootApplication public class AxiosDemoApplic…

HTML:網頁的骨架 — 入門詳解教程

HTML&#xff1a;網頁的骨架 — 入門詳解教程 HTML&#xff08;HyperText Markup Language&#xff0c;超文本標記語言&#xff09;是構建網頁的基礎語言&#xff0c;負責定義網頁的結構和內容。無論是簡單的個人博客&#xff0c;還是復雜的企業網站&#xff0c;HTML都是不可或…

212、【圖論】字符串接龍(Python)

題目描述 題目鏈接&#xff1a;110. 字符串接龍 代碼實現 import collectionsn int(input()) beginStr, endStr input().split() strList [input() for _ in range(n)]deque collections.deque() # 使用隊列遍歷結點 deque.append([beginStr, 1]) # 存儲當前字符串和遍…

操作系統導論——第19章 分頁:快速地址轉換(TLB)

使用分頁作為核心機制來實現虛擬內存&#xff0c;可能會帶來較高的性能開銷。使用分頁&#xff0c;就要將內存地址空間切分成大量固定大小的單元&#xff08;頁&#xff09;&#xff0c;并且需要記錄這些單元的地址映射信息。因為這些映射信息一般存儲在物理內存中&#xff0c;…

使用Apache POI(Java)創建docx文檔和表格

1、引入poi 依賴組件 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>4.0.0</version> </dependency> <dependency><groupId>org.apache.poi</groupId>&…

python cv2 安裝

在Python中安裝opencv-python&#xff08;即OpenCV庫&#xff09;&#xff0c;通常有兩種方法&#xff1a;使用pip命令或通過conda&#xff08;如果你使用的是Anaconda或Miniconda&#xff09;。以下是詳細的步驟&#xff1a; 方法1&#xff1a;使用pip 打開你的命令行界面&am…