Калужский Александр: В этой задаче другой вопрос)..
20-04-2024
Читать статью
эл: здравствуйте. Задание из демоверсии 2024..
Калужский Александр: Кодовое слово 100 уже занято буквой В..
07-04-2024
Привет! Сегодня сделаем аналоговые часы на языке программировании C#.
Запускаем Visual Studio. Выбираем Создание проекта->Приложение Windows Forms (.NET Framework)->Создать.
Для самого окна сделаем размер: 350px на 350px в окне свойств.
Свойство FormBorderStyle для окна формы поставим в значение None, чтобы убрать границу у окна нашей программы.
Добавим на форму из Панели элементов PictureBox. Поставим так же размеры для PictureBox 350 и 350.
Свойство SizeMode для PictureBox установим в Zoom. Это растянет нашу картинку на всё окно формы. Свойство Dock установим в Fill. Это означает, что наша картинка будет размещена по центру окна формы.
Уже можно загрузить саму картинку циферблата. Будем использовать вот это изображение формата gif:
Загружаем данное изображение в свойство Image для PictureBox. Выбираем Локальный ресурс->Импорт.
Теперь, если мы запустим наш проект, то мы увидим, что мы не можем переносить мышкой наше окно. Чтобы исправить ситуацию, заходим в код нашей программы, нажав клавишу F7.
C помощью команды using подключим пространство имён System.Runtime.InteropServices
... using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; // Подключаем новое пространство имён ...
Подключаем функции из библиотеки user32.dll, которые помогут нам переносить окно с помощью мышки, кликая в любой точки этого окна.
... public partial class Form1 : Form { [DllImport("user32", CharSet = CharSet.Auto)] internal extern static bool PostMessage(IntPtr hWnd, uint Msg, uint WParam, uint LParam); [DllImport("user32", CharSet = CharSet.Auto)] internal extern static bool ReleaseCapture(); ...
А так же подключим обработчик события MouseDown (нажатия клавиши мыши) для нашей PictureBox. Кликаем на вкладку конструктор, выбираем в свойствах именно форму и нажимаем кнопку со значком молния. Там ищем событие MouseDown и кликаем два раза на поле, которое напротив слова MouseDown.
В появившийся функции обработчика события пропишем следующий код:
private void PictureBox1_MouseDown(object sender, MouseEventArgs e) { const uint WM_SYSCOMMAND = 0x0112; const uint DOMOVE = 0xF012; ReleaseCapture(); PostMessage(this.Handle, WM_SYSCOMMAND, DOMOVE, 0); }
Запустим программу и увидим, что теперь можно перемещать окно, кликая по любой точке картинки.
Чтобы у нас была только картинка циферблата, и не было видно самого окна, настроим прозрачность окна.
Пропишем код:
... public Form1() { InitializeComponent(); this.BackColor = Color.AliceBlue; this.TransparencyKey = this.BackColor; ...
Заведём необходимые переменные:
... public partial class Form1 : Form { int cx = 175, cy = 175; // Центр картинки. int secHAND = 100, minHAND = 90, hrHAND = 75; Timer t = new Timer(); ...
secHAND, minHAND, hrHAND - это длина в пикселях секундной стрелки, минутной и часовой соответственно.
Так же завели таймер t.
Перейдём в обработчик события Load (загрузка) для самой формы (по аналогии, как мы делали обработчик события MouseDown).
Настроим таймер:
private void Form1_Load(object sender, EventArgs e) { t.Interval = 1000; //В миллисекундах t.Tick += new EventHandler(this.t_Tick); t.Start(); }
Теперь каждую секунду будет запускаться функция t_Tick(), которую мы пропишем ниже.
Стрелки будут идти от центра картинки. Центр имеет координаты x=175 (350/2), y=175 (350/2). Начало координат находится в верхнем левом углу.
Напишем функцию msCoord, которая будет получать количество секунд (или минут) и длину стрелки, а возвращать координаты конца секундной(минутной) стрелки.
private int[] msCoord(int val, int hlen) { int[] coord = new int[2]; val *= 6; if (val >= 0 && val <= 180) { coord[0] = cx + (int)(hlen * Math.Sin(Math.PI * val / 180)); coord[1] = cy - (int)(hlen * Math.Cos(Math.PI * val / 180)); } else { coord[0] = cx - (int)(hlen * -Math.Sin(Math.PI * val / 180)); coord[1] = cy - (int)(hlen * Math.Cos(Math.PI * val / 180)); } return coord; }
При отклонении на 1 секунду (или минуту), стрелка отклоняется на 6 градусов (360/60). В начале, функция узнаёт на сколько градусов отклоняется стрелка от начального положения (цифры 12).
Если прошло 5 секунд, стрелка отклонилась на 30 градусов. Тогда координата x=cx+l*sin(30), a y=cy-l*cos(30), где l-длина стрелки, cx и cy - центр картинки. Градусы нужно указывать в радианах (умножаем на пи и делим на 180 градусов угол отклонения).
В функции так же учтены знаки для синуса и косинуса для разных четвертей окружности. Так же учтено, когда нужно вычитать от сx и cy, а когда прибавлять.
Напишем функцию для получения координат конца часовой стрелки.
private int[] hrCoord(int hval, int mval, int hlen) { int[] coord = new int[2]; int val = (int)((hval * 30) + (mval * 0.5)); if (val >= 0 && val <= 180) { coord[0] = cx + (int)(hlen * Math.Sin(Math.PI * val / 180)); coord[1] = cy - (int)(hlen * Math.Cos(Math.PI * val / 180)); } else { coord[0] = cx - (int)(hlen * -Math.Sin(Math.PI * val / 180)); coord[1] = cy - (int)(hlen * Math.Cos(Math.PI * val / 180)); } return coord; }
Эта функция принимает и часы и минуты. Для часовой стрелки: 1 час - это 30 градусов (360/12), а одна минута - это 0.5 градусов.
В остальном работает так же, как предыдущая функция.
Напишем главную функцию t_Tick.
private void t_Tick(object sender, EventArgs e) { //Берём время. int s = DateTime.Now.Second; int m = DateTime.Now.Minute; int h = DateTime.Now.Hour; int[] handCoord = new int[2]; Graphics g = pictureBox1.CreateGraphics(); // Стираем предыдущее положения секундной стрелки handCoord = msCoord(s, secHAND + 4); g.DrawLine(new Pen(Color.White, 45f), new Point(cx, cy), new Point(handCoord[0], handCoord[1])); // Стираем предыдущее положение минутной стрелки handCoord = msCoord(m, minHAND + 4); g.DrawLine(new Pen(Color.White, 40f), new Point(cx, cy), new Point(handCoord[0], handCoord[1])); // Стираем предыдущее положение часовой стрелки handCoord = hrCoord(h % 12, m, hrHAND + 4); g.DrawLine(new Pen(Color.White, 20f), new Point(cx, cy), new Point(handCoord[0], handCoord[1])); //Отрисовка стрелки часов. handCoord = hrCoord(h % 12, m, hrHAND); g.DrawLine(new Pen(Color.Gray, 4f), new Point(cx, cy), new Point(handCoord[0], handCoord[1])); //Отрисовка минутной стрелки handCoord = msCoord(m, minHAND); g.DrawLine(new Pen(Color.Black, 2f), new Point(cx, cy), new Point(handCoord[0], handCoord[1])); // Отрисовка секундной стрелки. handCoord = msCoord(s, secHAND); g.DrawLine(new Pen(Color.DarkOrange, 2f), new Point(cx, cy), new Point(handCoord[0], handCoord[1])); }
В начале функции берём системное время (часы, минуты, секунды). Создаём объект g типа Graphics, который позволит рисовать на нашей картинке (циферблате).
Узнаём координаты для секундной, минутной и часовой стрелки, и в начале проводим "толстые линии" белого цвета, которые должны стереть предыдущее изображение стрелок. Т.к для линий подобрана нужная толщина, то получается полностью закрасить предыдущее положение стрелок.
Затем уже, рисуем линии стрелок часов с нормальной толщиной и нужными нами цветами.
Каждую секунду стрелки прорисовываются заново. Для часов подставляем остаток от деления на 12 (h % 12), чтобы учесть, что 22-это 10 часов.
На этом всё! Будьте здоровы!
Если вам лень перепечатывать данный проект вручную, можете купить мой за 600 499 рублей.