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