折腾笔记[43]-基于csharp的时钟
摘要
基于csharp的时钟.
代码
- 工程定义
clock.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<RootNamespace>exp76_eink_display</RootNamespace>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<!-- 应用程序图标 -->
<ApplicationIcon>clock.ico</ApplicationIcon>
<!-- 版本信息 -->
<Version>2026.02.15.1120</Version>
<FileVersion>2026.02.15.1120</FileVersion>
<AssemblyVersion>2026.02.15.1120</AssemblyVersion>
<!-- 作者信息 -->
<Authors>qsbye</Authors>
<Company>ByeIO</Company>
<!-- 单文件发布配置 -->
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
</Project>
- 主程序
Program.cs
namespace exp76_eink_display;
static class Program
{
/// <summary>
/// 程序主入口
/// </summary>
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new Clock());
}
}
Clock.cs
// 文件: Clock.cs
// 功能: 墨水屏时钟
// 标准库
using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Windows.Forms;
namespace exp76_eink_display
{
public partial class Clock : Form
{
#region 常量定义
// 字体比例系数
private const float HOUR_FONT_RATIO = 0.25f; // 小时字体占屏幕高度比例
private const float MINUTE_FONT_RATIO = 0.25f; // 分钟字体占屏幕高度比例
#endregion 常量定义
#region UI控件
// 顶部导航栏
private Panel topPanel;
private Button btnSettings;
private Panel settingsPanel;
private CheckBox chkAutoStart;
private Button btnCloseSettings;
private bool isSettingsOpen = false;
// 时间显示标签
private Label labelHour; // 小时标签
private Label labelMinute; // 分钟标签
// 右键菜单
private ContextMenuStrip contextMenu;
#endregion UI控件
#region 开机自启相关
private string startupFolderPath;
private string shortcutPath;
private string appPath;
#endregion 开机自启相关
#region 构造方法
public Clock()
{
InitializeComponent();
InitializeCustomComponents();
InitializeAutoStart();
InitializeContextMenu();
// 窗体加载时居中显示时间
this.Load += Clock_Load;
// 窗体大小改变时重新居中
this.Resize += Clock_Resize;
// 定时器触发更新时间
this.timer1.Tick += Timer1_Tick;
// 双击退出全屏
// this.DoubleClick += Clock_DoubleClick;
// 按键退出(ESC键)
this.KeyPreview = true;
this.KeyDown += Clock_KeyDown;
}
#endregion 构造方法
#region 初始化方法
/// <summary>
/// 初始化自定义UI组件
/// </summary>
private void InitializeCustomComponents()
{
// 移除原有labelTime(由设计器添加)
if (this.labelTime != null)
{
this.Controls.Remove(this.labelTime);
this.labelTime.Dispose();
this.labelTime = null;
}
// 创建小时标签(上半部分)
labelHour = new Label
{
Name = "labelHour",
AutoSize = true,
TextAlign = ContentAlignment.MiddleCenter,
ForeColor = Color.Black,
BackColor = Color.Transparent
};
// 创建分钟标签(下半部分,斜体)
labelMinute = new Label
{
Name = "labelMinute",
AutoSize = true,
TextAlign = ContentAlignment.MiddleCenter,
ForeColor = Color.Black,
BackColor = Color.Transparent
};
// 添加标签到窗体
this.Controls.Add(labelHour);
this.Controls.Add(labelMinute);
labelHour.BringToFront();
labelMinute.BringToFront();
// 创建顶部导航栏
topPanel = new Panel
{
Name = "topPanel",
Height = 40,
Dock = DockStyle.Top,
BackColor = Color.FromArgb(240, 240, 240),
Visible = false // 默认隐藏,非全屏时显示
};
// 创建设置按钮
btnSettings = new Button
{
Name = "btnSettings",
Text = "⚙ 设置",
Height = 30,
Top = 5,
Left = 10,
FlatStyle = FlatStyle.Flat,
BackColor = Color.White,
Cursor = Cursors.Hand,
// 启用自动大小
AutoSize = true,
// 或 GrowOnly
AutoSizeMode = AutoSizeMode.GrowAndShrink
};
btnSettings.FlatAppearance.BorderColor = Color.LightGray;
btnSettings.Click += BtnSettings_Click;
topPanel.Controls.Add(btnSettings);
this.Controls.Add(topPanel);
// 创建设置面板(下拉菜单样式)
settingsPanel = new Panel
{
Name = "settingsPanel",
Height = 100,
Top = 45,
Left = 10,
BackColor = Color.White,
BorderStyle = BorderStyle.FixedSingle,
Visible = false,
// 启用自动大小
AutoSize = true,
// 或 GrowOnly
AutoSizeMode = AutoSizeMode.GrowAndShrink
};
// 开机自启勾选框
chkAutoStart = new CheckBox
{
Name = "chkAutoStart",
Text = "开机自启",
AutoSize = true,
Top = 15,
Left = 15,
Checked = false
};
chkAutoStart.CheckedChanged += ChkAutoStart_CheckedChanged;
// 关闭设置按钮
btnCloseSettings = new Button
{
Name = "btnCloseSettings",
Text = "关闭",
Height = 25,
Top = 55,
Left = 120,
FlatStyle = FlatStyle.Flat,
// 启用自动大小
AutoSize = true,
// 或 GrowOnly
AutoSizeMode = AutoSizeMode.GrowAndShrink
};
btnCloseSettings.Click += (s, e) => { settingsPanel.Visible = false; isSettingsOpen = false; };
settingsPanel.Controls.Add(chkAutoStart);
settingsPanel.Controls.Add(btnCloseSettings);
this.Controls.Add(settingsPanel);
settingsPanel.BringToFront();
}
/// <summary>
/// 初始化开机自启功能
/// </summary>
private void InitializeAutoStart()
{
startupFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
// 使用 Process 获取实际的可执行文件路径,而不是 DLL 路径
appPath = Process.GetCurrentProcess().MainModule.FileName;
string appName = Path.GetFileNameWithoutExtension(appPath);
shortcutPath = Path.Combine(startupFolderPath, appName + ".lnk");
chkAutoStart.Checked = File.Exists(shortcutPath);
}
/// <summary>
/// 初始化右键菜单
/// </summary>
private void InitializeContextMenu()
{
// 创建右键菜单
contextMenu = new ContextMenuStrip();
// 添加"退出全屏"菜单项
ToolStripMenuItem menuExitFullScreen = new ToolStripMenuItem
{
Name = "menuExitFullScreen",
Text = "退出全屏",
// 初始状态下非全屏,禁用该选项
Enabled = false
};
menuExitFullScreen.Click += MenuExitFullScreen_Click;
// 添加"进入全屏"菜单项
ToolStripMenuItem menuEnterFullScreen = new ToolStripMenuItem
{
Name = "menuEnterFullScreen",
Text = "进入全屏",
// 初始状态下非全屏,禁用该选项
Enabled = false
};
menuEnterFullScreen.Click += MenuEnterFullScreen_Click;
// 添加分隔线
ToolStripSeparator separator = new ToolStripSeparator();
// 添加"退出程序"菜单项
ToolStripMenuItem menuExit = new ToolStripMenuItem
{
Name = "menuExit",
Text = "退出程序"
};
menuExit.Click += (s, e) => this.Close();
// 将菜单项添加到右键菜单
contextMenu.Items.Add(menuExitFullScreen);
contextMenu.Items.Add(menuEnterFullScreen);
contextMenu.Items.Add(separator);
contextMenu.Items.Add(menuExit);
// 将右键菜单关联到窗体和标签控件
this.ContextMenuStrip = contextMenu;
labelHour.ContextMenuStrip = contextMenu;
labelMinute.ContextMenuStrip = contextMenu;
}
#endregion 初始化方法
#region 事件处理方法
/// <summary>
/// 设置按钮点击事件
/// </summary>
private void BtnSettings_Click(object sender, EventArgs e)
{
isSettingsOpen = !isSettingsOpen;
settingsPanel.Visible = isSettingsOpen;
}
/// <summary>
/// 开机自启选项变更事件
/// </summary>
private void ChkAutoStart_CheckedChanged(object sender, EventArgs e)
{
try
{
if (chkAutoStart.Checked)
{
CreateStartupShortcut();
// MessageBox.Show("已添加到开机自启", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
RemoveStartupShortcut();
// MessageBox.Show("已取消开机自启", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show($"操作失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
chkAutoStart.CheckedChanged -= ChkAutoStart_CheckedChanged;
chkAutoStart.Checked = !chkAutoStart.Checked;
chkAutoStart.CheckedChanged += ChkAutoStart_CheckedChanged;
}
}
/// <summary>
/// 退出全屏菜单点击事件
/// </summary>
private void MenuExitFullScreen_Click(object sender, EventArgs e)
{
ExitFullScreen();
}
/// <summary>
/// 进入全屏菜单点击事件
/// </summary>
private void MenuEnterFullScreen_Click(object sender, EventArgs e)
{
EnterFullScreen();
}
/// <summary>
/// 窗体加载事件
/// </summary>
private void Clock_Load(object sender, EventArgs e)
{
UpdateTime();
AdjustFontSize();
CenterLabels();
UpdateTopPanelVisibility();
UpdateContextMenuState();
}
/// <summary>
/// 窗体大小改变事件
/// </summary>
private void Clock_Resize(object sender, EventArgs e)
{
AdjustFontSize();
CenterLabels();
UpdateTopPanelVisibility();
UpdateContextMenuState();
}
/// <summary>
/// 定时器触发事件
/// </summary>
private void Timer1_Tick(object sender, EventArgs e)
{
UpdateTime();
if (DateTime.Now.Second == 0)
{
AdjustFontSize();
CenterLabels();
}
}
/// <summary>
/// 双击窗体事件(切换全屏)
/// </summary>
private void Clock_DoubleClick(object sender, EventArgs e)
{
ToggleFullScreen();
}
/// <summary>
/// 键盘按下事件
/// </summary>
private void Clock_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
this.Close();
}
}
#endregion 事件处理方法
#region 功能方法
/// <summary>
/// 创建开机自启快捷方式
/// </summary>
private void CreateStartupShortcut()
{
Type shellType = Type.GetTypeFromProgID("WScript.Shell");
dynamic shell = Activator.CreateInstance(shellType);
dynamic shortcut = shell.CreateShortcut(shortcutPath);
shortcut.TargetPath = appPath;
shortcut.WorkingDirectory = Path.GetDirectoryName(appPath);
shortcut.Description = "E-ink Clock 开机自启";
shortcut.Save();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(shortcut);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(shell);
}
/// <summary>
/// 移除开机自启快捷方式
/// </summary>
private void RemoveStartupShortcut()
{
if (File.Exists(shortcutPath))
{
File.Delete(shortcutPath);
}
}
/// <summary>
/// 更新顶部导航栏可见性
/// </summary>
private void UpdateTopPanelVisibility()
{
bool isFullScreen = this.WindowState == FormWindowState.Maximized && this.FormBorderStyle == FormBorderStyle.None;
if (topPanel != null)
{
topPanel.Visible = !isFullScreen;
}
if (isFullScreen && settingsPanel != null)
{
settingsPanel.Visible = false;
isSettingsOpen = false;
}
}
/// <summary>
/// 更新右键菜单状态
/// </summary>
private void UpdateContextMenuState()
{
if (contextMenu == null) return;
bool isFullScreen = this.WindowState == FormWindowState.Maximized && this.FormBorderStyle == FormBorderStyle.None;
// 查找"退出全屏"菜单项并更新状态
ToolStripMenuItem menuExitFullScreen = contextMenu.Items.Find("menuExitFullScreen", false).FirstOrDefault() as ToolStripMenuItem;
if (menuExitFullScreen != null)
{
menuExitFullScreen.Enabled = isFullScreen;
// 非全屏时隐藏该选项
menuExitFullScreen.Visible = isFullScreen;
}
// 查找"进入全屏"菜单项并更新状态
ToolStripMenuItem menuEnterFullScreen = contextMenu.Items.Find("menuEnterFullScreen", false).FirstOrDefault() as ToolStripMenuItem;
if (menuEnterFullScreen != null)
{
menuEnterFullScreen.Enabled = !isFullScreen;
// 全屏时隐藏该选项
menuEnterFullScreen.Visible = !isFullScreen;
}
}
/// <summary>
/// 切换全屏状态
/// </summary>
private void ToggleFullScreen()
{
if (this.WindowState == FormWindowState.Maximized && this.FormBorderStyle == FormBorderStyle.None)
{
ExitFullScreen();
}
else
{
EnterFullScreen();
}
}
/// <summary>
/// 进入全屏模式
/// </summary>
private void EnterFullScreen()
{
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
UpdateTopPanelVisibility();
UpdateContextMenuState();
AdjustFontSize();
CenterLabels();
}
/// <summary>
/// 退出全屏模式
/// </summary>
private void ExitFullScreen()
{
this.WindowState = FormWindowState.Normal;
this.FormBorderStyle = FormBorderStyle.Sizable;
UpdateTopPanelVisibility();
UpdateContextMenuState();
AdjustFontSize();
CenterLabels();
}
/// <summary>
/// 更新时间显示
/// </summary>
private void UpdateTime()
{
DateTime now = DateTime.Now;
// 上半部分显示小时
labelHour.Text = now.ToString("HH");
// 下半部分显示分钟(斜体)
labelMinute.Text = now.ToString("mm");
}
/// <summary>
/// 调整字体大小
/// </summary>
private void AdjustFontSize()
{
int navHeight = (topPanel != null && topPanel.Visible) ? topPanel.Height : 0;
int margin = 20;
int availableWidth = this.ClientSize.Width - margin * 2;
int availableHeight = this.ClientSize.Height - navHeight - margin * 2;
if (availableWidth <= 0 || availableHeight <= 0)
return;
// 屏幕分为上下两半
int halfHeight = availableHeight / 2;
// 计算小时字体大小(占上半部分的70%高度)
float hourFontSize = halfHeight * HOUR_FONT_RATIO * 2;
hourFontSize = Math.Max(Math.Min(hourFontSize, 400f), 40f);
// 计算分钟字体大小(占下半部分的60%高度)
float minuteFontSize = halfHeight * MINUTE_FONT_RATIO * 2;
minuteFontSize = Math.Max(Math.Min(minuteFontSize, 350f), 30f);
// 应用字体:小时粗体,分钟粗体+斜体
labelHour.Font = new Font("Microsoft YaHei", hourFontSize, FontStyle.Bold);
labelMinute.Font = new Font("Microsoft YaHei", minuteFontSize, FontStyle.Bold | FontStyle.Italic);
}
/// <summary>
/// 居中显示标签
/// </summary>
private void CenterLabels()
{
int navHeight = (topPanel != null && topPanel.Visible) ? topPanel.Height : 0;
int clientHeight = this.ClientSize.Height - navHeight;
int halfHeight = clientHeight / 2;
// 水平居中
labelHour.Left = (this.ClientSize.Width - labelHour.Width) / 2;
labelMinute.Left = (this.ClientSize.Width - labelMinute.Width) / 2;
// 垂直分布:小时在上半部分居中,分钟在下半部分居中
labelHour.Top = navHeight + (halfHeight - labelHour.Height) / 2;
labelMinute.Top = navHeight + halfHeight + (halfHeight - labelMinute.Height) / 2;
}
#endregion 功能方法
}
}
Clock.Designer.cs
namespace exp76_eink_display;
partial class Clock
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 请勿使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.labelTime = new System.Windows.Forms.Label();
this.timer1 = new System.Windows.Forms.Timer(this.components);
// 设置窗体
this.AutoScaleMode = AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
this.ClientSize = new Size(800, 450);
this.Text = "电子时钟";
// 设置时间标签
this.labelTime.AutoSize = true;
this.labelTime.Font = new System.Drawing.Font("Microsoft YaHei", 120F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this.labelTime.ForeColor = System.Drawing.Color.Black;
this.labelTime.Location = new System.Drawing.Point(0, 0);
this.labelTime.Name = "labelTime";
this.labelTime.Size = new System.Drawing.Size(0, 265);
this.labelTime.TabIndex = 0;
this.labelTime.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
// 添加控件到窗体
this.Controls.Add(this.labelTime);
// 设置定时器
this.timer1.Interval = 1000;
this.timer1.Enabled = true;
}
#endregion
private System.Windows.Forms.Label labelTime;
private System.Windows.Forms.Timer timer1;
}
效果
| 时钟运行 |
|---|
![]() |


浙公网安备 33010602011771号