Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > как перерисовать стрелки часов ежесекундно?


Автор: beyond11 3.1.2008, 20:18
Тема курсового - сделать программу "Часы", которая показывала бы часы со стрелками (движущимися ежесекундно, ессесно).
Разобрался с рисованием более-менее... Сделал, чтобы при старте программы в форме рисовались надписи и т.д.
Установил компонент таймер, теперь надо сделать, чтобы каждые 1000 миллисекунд перерисовывалась форма, а именно стрелки на ней. Никак не допру как это сделать.
Вот функция проорисовки формы сразу после старта программы:


private: System::Void Form1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) 
{
e->Graphics->DrawString("12",gcnew System::Drawing::Font(FontFamily::GenericMonospace, 30) ,Brushes::Blue,170,10);
e->Graphics->DrawEllipse(gcnew Pen(Brushes::Red, 2), 50, 50, 300, 300);        
e->Graphics->DrawEllipse(gcnew Pen(Brushes::Red, 1), 198, 198, 4, 4);
//стрелка
e->Graphics->DrawLine(gcnew Pen(Brushes::DarkMagenta, 2), 200, 200, 200, 54);
}



Вот, сделал функцию, которая будет происходить каждую секунду (в свойствах таймера поставил интервал равным 1000).



private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e) 
     {

     }



Так вот, что вписать в функцию System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) , чтобы стрелка перерисовывалась каждую секунду в новом месте?
Я знаю как определить координаты куда именно рисовать стрелку, проблема в том, что я не могу ВООБЩЕ вызвать перерисовку формы в этой функции, помогите пожалуйста. 

Автор: Experimenter 3.1.2008, 21:51
Рисованием занимается функция Paint. http://forum.vingrad.ru/forum/topic-126426.html загляни.

Автор: mr.DUDA 4.1.2008, 14:08
Для перерисовки нужно вызвать Refresh() из обработчика таймера. Координаты и т.п. вычислять с помощью синусов/косинусов, исходя из периода (60 секунд) и текущего кол-ва секунд в DateTime.Now.

Автор: beyond11 4.1.2008, 16:39
> Рисованием занимается функция Paint. Сюда загляни. 

Там все материалы по С#, а мне нужны по С++. И я уже сколько раз пытался с этим паинтом разобраться, ошибки лезут везде и всегда.

>Для перерисовки нужно вызвать Refresh() из обработчика таймера. Координаты и т.п. вычислять с помощью синусов/косинусов, исходя из периода (60 секунд) и текущего кол-ва секунд в DateTime.Now. 

Меня интересует не это. Как вычислить координаты стрелок я знаю, текущее количество секунд - потом разберусь.
Мне нужно вообще хоть как-то вызвать эту долбаную перерисовку, я что не пишу - всегда и везде куча ошибок (я вообще зелёный ещё в WinForms).
зы: Пишу в С++ а не в С#

Если не сложно, впишите пожалуйста в функцию Void timer1_Tick то, что нужно. Мне главное сам принцип понять! А с координатами стрелок проблем не будет.
Заранее спасибо.

Автор: beyond11 4.1.2008, 17:01
оффтоп, решил проблему, здесь было неправильно smile

Автор: mr.DUDA 4.1.2008, 17:04
Цитата(beyond11 @  4.1.2008,  15:39 Найти цитируемый пост)
зы: Пишу в С++ а не в С#

Так проще ?

Автор: beyond11 4.1.2008, 17:22
Цитата(mr.DUDA @ 4.1.2008,  17:04)
Цитата(beyond11 @  4.1.2008,  15:39 Найти цитируемый пост)
зы: Пишу в С++ а не в С#

Так проще ?

Не знаю проще или нет. Не я выбираю, это задание по учёбе. И выбора у меня нет.

Добавлено через 12 минут и 56 секунд
допёр, сделал, спасибо, наконец-то )))
всем спасибо)))

Автор: AET 11.1.2008, 06:55
где можно наити пример или скинте в личко блогодарен

Автор: mr.DUDA 11.1.2008, 11:29
Рецепт создания часов на дотнете (с) mr.DUDA:

- создайте пустое приложение типа Windows Application;
- в свойствах формы укажите DoubleBuffered = true, чтобы не мерцало при перерисовке;
- с тулбокса вытянуть на форму компонент Timer, в свойствах поставить Enabled = true, Interval = 250, так мы не пропустим ни секунды;
- добавить обработчик события таймера Tick и события формы Paint;
- пишем код:

Код
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace ClockApplication
{
    public partial class Form1 : Form
    {
        Pen _penHour, _penMinute, _penSecond;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            if (_penHour == null)
            {
                // один раз создаём карандаши для рисования стрелок
                // самый толстый карандаш - часовая стрелка, самый тонкий - секундная
                // линии начинаются кружком и заканчиваются треугольником
                _penHour = new Pen(Color.Red, 8f);
                _penHour.StartCap = LineCap.RoundAnchor;
                _penHour.EndCap = LineCap.Triangle;
                _penMinute = new Pen(Color.Blue, 6f);
                _penMinute.StartCap = LineCap.RoundAnchor;
                _penMinute.EndCap = LineCap.Triangle;
                _penSecond = new Pen(Color.Black, 4f);
                _penSecond.StartCap = LineCap.RoundAnchor;
                _penSecond.EndCap = LineCap.Triangle;
            }

            int W = Width, H = Height;
            int x0 = W / 2, y0 = H / 2;
            
            // длина стрелок - самая длинная секундная, самая короткая часовая
            double lenHour = x0 / 2;
            double lenMinute = (x0 * 3) / 4;
            double lenSecond = (x0 * 5) / 6;

            // определяем угол поворота каждой стрелки в радианах
            // учитываем что углы отсчитываются по часовой стрелке, от верхнего положения
            double TwoPi = 2 * Math.PI;
            DateTime now = DateTime.Now;
            double angleHour = (now.Hour - 3) * TwoPi / 12;
            double angleMinute = (now.Minute - 15) * TwoPi / 60;
            double angleSecond = (now.Second - 15) * TwoPi / 60;

            // рисуем стрелки
            e.Graphics.DrawLine(_penHour, x0, y0,
                (float)(x0 + lenHour * Math.Cos(angleHour)),
                (float)(y0 + lenHour * Math.Sin(angleHour)));
            e.Graphics.DrawLine(_penMinute, x0, y0,
                (float)(x0 + lenMinute * Math.Cos(angleMinute)),
                (float)(y0 + lenMinute * Math.Sin(angleMinute)));
            e.Graphics.DrawLine(_penSecond, x0, y0,
                (float)(x0 + lenSecond * Math.Cos(angleSecond)),
                (float)(y0 + lenSecond * Math.Sin(angleSecond)));
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Invalidate();
        }
    }
}


Картинко:
user posted image

Автор: AET 11.1.2008, 15:52
mr.DUDA блогодарен за ответ в рисовани я 0 подскажи как можно чтобы задни фон был в виде круга и цифры были 

Автор: mr.DUDA 11.1.2008, 19:45
AET, задай форме свойство BackgroundImage.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)