cs
复制代码
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsClock3
{
public partial class Form1 : Form
{
private Timer timer;
private Point center;
private int clockRadius;
private ContextMenuStrip contextMenu;
private bool isDragging;
private Point lastMousePos;
// 字体定义
private Font dateFont = new Font("Microsoft YaHei", 14, FontStyle.Bold);
private Font weekFont = new Font("Microsoft YaHei", 12, FontStyle.Regular);
private Font timeFont = new Font("Arial", 24, FontStyle.Bold);
// 颜色定义
private Color dateColor = Color.DarkBlue;
private Color weekColor = Color.Purple;
private Color timeColor = Color.Blue;
public string AppName { get; private set; }
public Form1()
{
InitializeComponent();
InitializeClock();
InitializeContextMenu();
}
private void InitializeClock()
{
this.Text = "指针式时钟";
this.ClientSize = new Size(450, 500); // 增加高度以容纳日期信息
this.DoubleBuffered = true;
this.Paint += ClockForm_Paint;
this.MouseDown += ClockForm_MouseDown;
this.MouseMove += ClockForm_MouseMove;
this.MouseUp += ClockForm_MouseUp;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.LightGray;
this.TransparencyKey = Color.LightGray;
// 设置计时器每秒更新一次
timer = new Timer();
timer.Interval = 1000;
timer.Tick += Timer_Tick;
timer.Start();
}
private void InitializeContextMenu()
{
contextMenu = new ContextMenuStrip();
// 开机启动选项
ToolStripMenuItem autoStartItem = new ToolStripMenuItem("开机自动启动");
autoStartItem.Checked = IsAutoStartEnabled();
autoStartItem.CheckOnClick = true;
autoStartItem.Click += (sender, e) =>
{
SetAutoStart(autoStartItem.Checked);
};
contextMenu.Items.Add(autoStartItem);
// 设置选项
ToolStripMenuItem settingsItem = new ToolStripMenuItem("设置");
settingsItem.Click += (sender, e) => ShowSettings();
contextMenu.Items.Add(settingsItem);
// 退出选项
ToolStripMenuItem exitItem = new ToolStripMenuItem("退出");
exitItem.Click += (sender, e) => Application.Exit();
contextMenu.Items.Add(exitItem);
this.ContextMenuStrip = contextMenu;
}
private void ShowSettings()
{
Form settingsForm = new Form
{
Text = "时钟设置",
Size = new Size(300, 250),
StartPosition = FormStartPosition.CenterScreen,
FormBorderStyle = FormBorderStyle.FixedDialog,
MaximizeBox = false
};
// 开机启动复选框
CheckBox autoStartCheck = new CheckBox
{
Text = "开机自动启动",
Checked = IsAutoStartEnabled(),
Location = new Point(20, 20),
AutoSize = true,
Font = new Font("Microsoft YaHei", 10)
};
// 透明背景复选框
CheckBox transparentCheck = new CheckBox
{
Text = "透明背景",
Checked = this.TransparencyKey == Color.LightGray,
Location = new Point(20, 60),
AutoSize = true,
Font = new Font("Microsoft YaHei", 10)
};
// 日期格式标签
Label formatLabel = new Label
{
Text = "日期格式:",
Location = new Point(20, 100),
AutoSize = true,
Font = new Font("Microsoft YaHei", 10)
};
// 日期格式选择
ComboBox formatCombo = new ComboBox
{
Location = new Point(100, 100),
Size = new Size(160, 25),
DropDownStyle = ComboBoxStyle.DropDownList
};
formatCombo.Items.AddRange(new object[] {
"yyyy年MM月dd日",
"yyyy-MM-dd",
"MM/dd/yyyy",
"dd MMM yyyy"
});
formatCombo.SelectedIndex = 0;
// 确定按钮
Button okButton = new Button
{
Text = "确定",
Size = new Size(80, 30),
Location = new Point(100, 150),
Font = new Font("Microsoft YaHei", 9)
};
okButton.Click += (sender, e) =>
{
SetAutoStart(autoStartCheck.Checked);
if (transparentCheck.Checked)
{
this.BackColor = Color.LightGray;
this.TransparencyKey = Color.LightGray;
}
else
{
this.BackColor = SystemColors.Control;
this.TransparencyKey = Color.Empty;
}
// 更新日期格式
Properties.Settings.Default.DateFormat = formatCombo.SelectedItem.ToString();
Properties.Settings.Default.Save();
settingsForm.Close();
};
settingsForm.Controls.Add(autoStartCheck);
settingsForm.Controls.Add(transparentCheck);
settingsForm.Controls.Add(formatLabel);
settingsForm.Controls.Add(formatCombo);
settingsForm.Controls.Add(okButton);
settingsForm.ShowDialog();
}
private void Timer_Tick(object sender, EventArgs e)
{
this.Invalidate(); // 触发重绘
}
private void ClockForm_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// 计算中心点和半径(增加垂直偏移为日期留空间)
int verticalOffset = 50;
center = new Point(ClientSize.Width / 2, ClientSize.Height / 2 - 25 + verticalOffset);
clockRadius = Math.Min(ClientSize.Width, ClientSize.Height) / 2 - 60;
// 绘制日期和星期
DrawDateAndWeek(g);
// 绘制时钟背景
DrawClockFace(g);
// 获取当前时间
DateTime now = DateTime.Now;
// 绘制指针
DrawHourHand(g, now.Hour, now.Minute);
DrawMinuteHand(g, now.Minute, now.Second);
DrawSecondHand(g, now.Second);
// 绘制中心点
DrawCenterCap(g);
// 绘制数字时间显示
DrawDigitalTime(g, now);
}
private void DrawDateAndWeek(Graphics g)
{
DateTime now = DateTime.Now;
// 获取日期格式
string dateFormat = Properties.Settings.Default.DateFormat;
if (string.IsNullOrEmpty(dateFormat))
dateFormat = "yyyy年MM月dd日";
// 格式化日期
string dateString = now.ToString(dateFormat);
string weekString = GetChineseWeekday(now.DayOfWeek);
// 计算位置
SizeF dateSize = g.MeasureString(dateString, dateFont);
SizeF weekSize = g.MeasureString(weekString, weekFont);
int totalWidth = (int)(dateSize.Width + 20 + weekSize.Width);
int startX = (ClientSize.Width - totalWidth) / 2;
int yPos = 20;
// 绘制日期
g.DrawString(dateString, dateFont, new SolidBrush(dateColor),
startX, yPos);
// 绘制星期
g.DrawString(weekString, weekFont, new SolidBrush(weekColor),
startX + (int)dateSize.Width + 20, yPos + (dateSize.Height - weekSize.Height) / 2);
// 绘制装饰线
Pen decorPen = new Pen(Color.Gray, 1);
g.DrawLine(decorPen, startX - 10, yPos + dateSize.Height + 5,
startX + (int)dateSize.Width + (int)weekSize.Width + 30, yPos + dateSize.Height + 5);
}
private string GetChineseWeekday(DayOfWeek day)
{
switch (day)
{
case DayOfWeek.Sunday: return "星期日";
case DayOfWeek.Monday: return "星期一";
case DayOfWeek.Tuesday: return "星期二";
case DayOfWeek.Wednesday: return "星期三";
case DayOfWeek.Thursday: return "星期四";
case DayOfWeek.Friday: return "星期五";
case DayOfWeek.Saturday: return "星期六";
default: return "";
}
}
private void DrawClockFace(Graphics g)
{
// 绘制外圆
g.FillEllipse(Brushes.White, center.X - clockRadius, center.Y - clockRadius,
clockRadius * 2, clockRadius * 2);
g.DrawEllipse(new Pen(Color.Black, 3), center.X - clockRadius, center.Y - clockRadius,
clockRadius * 2, clockRadius * 2);
// 绘制刻度
for (int i = 0; i < 60; i++)
{
double angle = Math.PI * 2 * i / 60.0;
int innerLength = i % 5 == 0 ? 15 : 5;
int outerLength = i % 5 == 0 ? 25 : 15;
int x1 = center.X + (int)((clockRadius - innerLength) * Math.Sin(angle));
int y1 = center.Y - (int)((clockRadius - innerLength) * Math.Cos(angle));
int x2 = center.X + (int)((clockRadius - outerLength) * Math.Sin(angle));
int y2 = center.Y - (int)((clockRadius - outerLength) * Math.Cos(angle));
g.DrawLine(new Pen(Color.Black, i % 5 == 0 ? 3 : 1), x1, y1, x2, y2);
}
// 绘制数字
Font font = new Font("Arial", 14, FontStyle.Bold);
for (int i = 1; i <= 12; i++)
{
double angle = Math.PI * 2 * (i - 3) / 12.0;
int x = center.X + (int)((clockRadius - 40) * Math.Sin(angle));
int y = center.Y - (int)((clockRadius - 40) * Math.Cos(angle));
g.DrawString(i.ToString(), font, Brushes.Black, x - 10, y - 10);
}
}
private void DrawHourHand(Graphics g, int hours, int minutes)
{
double angle = Math.PI * 2 * (hours % 12 + minutes / 60.0) / 12.0 - Math.PI / 2;
int length = clockRadius * 3 / 5;
DrawHand(g, angle, length, Color.Black, 8);
}
private void DrawMinuteHand(Graphics g, int minutes, int seconds)
{
double angle = Math.PI * 2 * (minutes + seconds / 60.0) / 60.0 - Math.PI / 2;
int length = clockRadius * 4 / 5;
DrawHand(g, angle, length, Color.Black, 5);
}
private void DrawSecondHand(Graphics g, int seconds)
{
double angle = Math.PI * 2 * seconds / 60.0 - Math.PI / 2;
int length = clockRadius * 4 / 5;
DrawHand(g, angle, length, Color.Red, 2);
}
private void DrawHand(Graphics g, double angle, int length, Color color, int width)
{
int x = center.X + (int)(length * Math.Cos(angle));
int y = center.Y + (int)(length * Math.Sin(angle));
Pen pen = new Pen(color, width);
pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
g.DrawLine(pen, center, new Point(x, y));
}
private void DrawCenterCap(Graphics g)
{
int capSize = 10;
g.FillEllipse(Brushes.Red, center.X - capSize, center.Y - capSize, capSize * 2, capSize * 2);
}
private void DrawDigitalTime(Graphics g, DateTime time)
{
string timeString = time.ToString("HH:mm:ss");
SizeF size = g.MeasureString(timeString, timeFont);
int x = center.X - (int)(size.Width / 2);
int y = center.Y + clockRadius + 20;
g.DrawString(timeString, timeFont, new SolidBrush(timeColor), x, y);
}
private void ClockForm_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDragging = true;
lastMousePos = e.Location;
}
}
private void ClockForm_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
this.Location = new Point(
this.Location.X + e.X - lastMousePos.X,
this.Location.Y + e.Y - lastMousePos.Y);
}
}
private void ClockForm_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDragging = false;
}
}
private bool IsAutoStartEnabled()
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Run", false))
{
return key?.GetValue(AppName) != null;
}
}
private void SetAutoStart(bool enable)
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(
"Software\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
if (enable)
{
string appPath = Application.ExecutablePath;
key.SetValue(AppName, $"\"{appPath}\"");
}
else
{
key.DeleteValue(AppName, false);
}
}
}
}
// 添加设置类
public sealed partial class Settings : ApplicationSettingsBase
{
[UserScopedSetting]
[DefaultSettingValue("yyyy年MM月dd日")]
public string DateFormat
{
get { return (string)this["DateFormat"]; }
set { this["DateFormat"] = value; }
}
}
}