CS_Prj02 用C#生成一个桌面指针式时钟 带日历 背景透明 程序

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; }
        }
    }

}