This will be shown to users with no Flash or Javascript.
Урок VII

Связывание событий с элементами управления
Установка таймера

Программа Graph имеет таймер, который является программным механизмом, генерирующем событие WM_TIMER через равные промежутки времени. Код в нашей программе будет задавать частоту, с которой будет выполняться событие WM_TIMER. Если вы, например, зададите рабочий интервал равный 500 милисекунд, то событие WM_TIMER и связанный с ним код будет выполняться каждые 500 миллисекунд.
Чтобы установить таймер, выполните следующие действия:
Выберете ClassWizard в меню View
Выберете закладку Message Maps в панели ClassWizard
Используйте диалоговую панель ClassWizard для выбора следующего события:
Class Name: CGraphDlg
Object ID: СGraphDlg
Messages: WM_INITDIALOG


BOOL CGraphDlg::OnInitDialog()
{
     CDialog::OnInitDialog();
     //....
     ////////Мой код начинается здесь///////////
     ///Установить системный таймер
     int iInstallResult;
     iInstallResult=SetTimer(1, 50, NULL);
     if(iInstallResult==FALSE)
     {
          MessageBox("Cannot install timer",
               "Error message",
               MB_OK+MB_ICONERROR);
     }
     ////////Мой код заканчивается здесь///////////

     return TRUE; // return TRUE unless you set the focus to a control
}

Функция SetTimer() имеет 3 параметра:
Первый - итендификатор таймер, код который вы ввели объявляет таймер как таймер#1.
Второй - устанавливает период в миллисекундах, с которым будет происходить сообщение WM_TIMER, в нашей программе оно будет генерироваться через промежутки времени равным 500 миллисекундам.
Третий - задает адрес функции, которая будет выполняться каждые 500 миллисекунд. Поскольку вы передаете в третий параметр значение NULL, это означает что вы не определяете функцию, следовательно каждые 500 миллисекунд будет генерироваться сообщение WM_TIMER.
Затем выполняется оператор IF, который проверяет установился ли таймер, если функция SetTimer() вернула значение 0,то значит таймер не установлен , и выполняется функция MessageBox, которая сообщает, с помощью предопределенной панели со значком "Error",что таймер не инсталлирован.
Всегда необходимо проверять на возможность установить таймер, потому что в зависимости от конкретной системы, можно установить ограниченное кол-во таймеров. Другие, работающие программы могут занять все существующие таймеры, поэтому вам надо закрыть одну из них.
После того, как таймер установлен, вы можете удалить его используя функцию KillTimer(). Параметром этой функции является номер удаляемого таймера. В нашей программе вы должгы тоже удалить таймер при выходе из программы. Для этого необходимо связать функцию KillTimer() с событием WM_DESTROY.
Для написания кода, который удаляет таймер, выполните следующие действияL:

Class Name: CGraphDlg
Object ID: СGraphDlg
Messages: WM_DESTROY


void CGraphDlg::OnDestroy()
{
     CDialog::OnDestroy();
     // TODO: Add your message handler code here
     ////Здесь начинается мой код////

     KillTimer(1);

     ////Здесь заканчивается мой код////
}

Проверка таймера

Перед тем, как продолжить создание программы, мы должны убедиться, что таймер работает как положено.
Для этого вы свяжете од с событием WM_TIMER.

Class Name: CGraphDlg
Object ID: СGraphDlg
Messages: WM_TIMER


BOOL CGraphDlg::OnTimer(UINT nIDEvent)
{
     //....
     ////////Мой код начинается здесь///////////

     MessageBeep(-2);
     ////////Мой код заканчивается здесь///////////
     CDialog::OnTimer(UINT nIDEvent);
}


Сохраните и запустите программу.
Вы должны слышать,что через каждые 500 миллисекунд компьютер будет подавать звуковой сигнал.
Завершите программу Graph, перед тем как продолжить работу надо поместить функцию MessageBeep() в коментарий.
Позже в этой главе вы включите в функцию OnTimer() дополнительный код.
Постройте и выполните программу, и убедитесь, что компьютер перестал подавать звуковой сигнал.
Событие WM_PAINT

Событие WM_PAINT происходит каждый раз, когда необходимо перерисовать окно. Это бывает в таких случаях, когда, например, окно другой программы налажилось на вашу, то после закрытия той программы, в вашей программе программе круга уже не будет, так как его стерло другое окно. Если вы перетащили, к примеру, половину окна программы за рабочую облать, то опять же требуется перерисовка экрана. Windows сама не будет перерисовывать экран, она будет только генерировать сообщение WM_PAINT, а наша задача уже перерисовывать.
Чтобы показать необходимость необходимость события WM_PAINT, напишем следующий код.

Class Name: CGraphDlg
Object ID: IDC_DRAWGRAPHICS_BUTTON
Messages: BN_CLICKED

BOOL CGraphDlg::OnDrawgraphicsButton()
{
     // TODO: Add your message handler code here
     ////////Мой код начинается здесь///////////
     ///Создать объект контекста устройства(DC)
     CClientDC dc(this);

     //Создать новое перо
     CPen MyNewPen;
     MyNewPen.CreatePen(PS_SOLID, 10, RGB(255,0,0));

     //Выбрать перо
     CPen* pOriginalPen;
     pOriginalPen=dc.SelectObject(&MyNewPen);
     CRect MyRectangle(20, 10, 120,110);

     //Нарисовать круг
     dc.Ellipse(&MyRectangle);

     //Выбрать первоначальное перо
     dc.SelectObject(pOriginalPen);

     ////////Мой код заканчивается здесь///////////

     CDialog::OnPaint();
}



Сначала создается объект контексного устройства:
///Создать объект контекста устройства(DC)
CClientDC dc(this);


Затем создается новое перо красного цвета, толщиной линии 10 пикселов, и стилем заливки PS_SOLID - сплошная заливка:
//Создать новое перо
CPen MyNewPen;
MyNewPen.CreatePen(PS_SOLID, 10, RGB(255,0,0));

Далее выбирается новое перо:
//Выбрать перо
CPen* pOriginalPen;
pOriginalPen=dc.SelectObject(&MyNewPen);

Обратите внимение, что выборе нового пера, текущеее заменяется новым. Поэтому функция SelectObject возвращает указатель на первоначальное перо, который присваивает указатель pOriginalPen.
Затем создается объект прямоугольника:
CRect MyRectangle(20, 10, 120,110);
Здесь вы указываете координаты верхнего левого и нижнего правого угла. На нашем примере мы задали прямоугольник, отстоящий на 20 пикселов по оси X от левой стороны и на 10 пикселов сверху. Таким образом мы задали квадрат со стороной 100 пикселов.

Далее рисуется эллипс:
//Нарисовать круг
dc.Ellipse(&MyRectangle);
Здесь рисуется эллипс, но на самом деле получается круг, так как координаты эллипса заданы квадратом. Круг является частным случаем эллипса.

И в последнем операторе вы выбираете первоначальное перо:
//Выбрать первоначальное перо
dc.SelectObject(pOriginalPen);


Посторойте и выполните программу Graph.
Появиться окно ппрограммы.
Щелкните на кнопке Draw Graphics.
Появиться такое окно вашей программы:
Теперь сдвиньте окно вашей программы за рабочую область, так чтобы осталась только половина круга на экране, а затем верните окно в состояние поялной его видимости, оно у вас должно будет выглядеть так:
Код перерисовки

Теперь кодгда вы убделись, что событие WM_PAINT необходимо, и окно в функции OnPaint() надо перерисовывать, добавим слдеующий код туда:

Class Name: CGraphDlg
Object ID: CGraphDlg
Messages: WM_PAINT

Нажмите кнопку Edit Code и напишите следующий код в функции OnPaint():
void CGraphDlg::OnPaint()
{
     if (IsIconic())
     {
     //....
     }
     else
     {
          ////Мой код начинается здесь////
          OnDrawgraphicsButton();

          ////Мой код заканчивается здесь////
          //...
     }
}


Вы добавили функцию, которая будет каждый раз выполняться, когда окно будет необходимо перерисовать. Вспомните, что функция OnDrawgraphicsButton() рисует круг- соответственно изображение будет перерисовываться.
Модификация функции OnPoint()

В предыдущем разделе вы перерисовывали экран с помощью функции OnDrawgraphicsButton(), в будущем мы напишем другой код в этой функции, поэтому ее выполнение не желательно. Значит, нам необходимо код переисовки экрана связать непосредственно с событием WM_POINT.
Модифицируйте код в функции OnPaint() следующим образом:
void CGraphDlg::OnPaint()
{
     if (IsIconic())
     {
          //....
     }
     else
     {
          ////Мой код начинается здесь////
          // OnDrawgraphicsButton();
          ///Создать объект контекста устройства(DC)
          CPaintDC dc(this);

          //Создать новое перо
          CPen MyNewPen;
          MyNewPen.CreatePen(PS_SOLID, 10, RGB(255,0,0));

          //Выбрать перо
          CPen* pOriginalPen;
          pOriginalPen=dc.SelectObject(&MyNewPen);
          CRect MyRectangle(20, 10, 120,110);

          //Нарисовать круг
          dc.Ellipse(&MyRectangle);

          //Выбрать первоначальное перо
          dc.SelectObject(pOriginalPen);
          ////Мой код заканчивается здесь////
          //...
     }
}


Вы поместили функцию OnDrawgraphicsButton() в коментарий.
Заменили оператор CClientDC dc(this) на CPaintDC dc(this), так как с этим контексным устройством работает функция OnPaint().
Остальная часть кода осталась без изменения.
Постройте и запустите программу Graph.
Подвигайте окном Graph и убедитесь, что код перерисовки функции OnPaint() работает.
Щелкните на кнопке Exit, чтобы ее завершить.
Визуальное проектирование диалоговой панели IDD_CUSTOM_DIALOG и связывание событий с элементами управления(продолжение).

<-Назад |Содержание| Дальше ->
Используются технологии uCoz