Шаг 4 - События элемента управления

Создание проекта

Продолжаем развитие нашего проекта дальше.

Создаем код

Это вписывается после последнего #define. Вот сюда:

4_1.gif (2432 b)

Мы записываем объявление класса в самое начало, чтобы его было видно во всем файле.

class CMyButton: public CButton
{
public:
	afx_msg void OnLButtonDblClk(UINT, CPoint);
	afx_msg void OnRButtonDblClk(UINT, CPoint);
private:
	DECLARE_MESSAGE_MAP(); // таблица откликов кнопки
};

void CMyButton::OnLButtonDblClk(UINT, CPoint)
{
	MoveWindow(CRect(120,100,220,150),TRUE);
}

void CMyButton::OnRButtonDblClk(UINT, CPoint)
{
	MoveWindow(CRect(120,10,220,50),TRUE);
}

BEGIN_MESSAGE_MAP(CMyButton, CButton) // таблица откликов на сообщения
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONDBLCLK()
END_MESSAGE_MAP()

После добавления описания класса в окне ClassView мы сможем увидеть, что добавился новый класс:

4_2.gif (1420 b)

И изменяем класс кнопки в рамке окна:

class CMainWnd : public CFrameWnd
{
public:
	CMainWnd();
	afx_msg void OnLButtonDblClk(UINT, CPoint);
	afx_msg void OnRButtonDblClk(UINT, CPoint);
	afx_msg void OnKeyDown(UINT, UINT, UINT);
private:
	CStatic* MyStatic;      // Элемент управления для вывода текста
	CMyButton* MyButton;// Элемент управления кнопка
	CEdit* MyEdit;  // Элемент редактирования
	DECLARE_MESSAGE_MAP(); // таблица откликов
};

Меняем часть конструктора:

CMainWnd::CMainWnd()
{
	Create(NULL,"Step4",WS_OVERLAPPEDWINDOW,rectDefault,
		NULL,NULL);     // Создать окно программы
	// оператор new по умолчанию в случае ошибки вернет NULL
	// проверка указателя на NULL дает возможность избавиться от дальнейших ошибок
	MyStatic = new CStatic();
	if (MyStatic!=NULL)  MyStatic->Create("MyStatic",WS_CHILD|WS_VISIBLE|SS_CENTER,
		CRect(10,10,100,50),this);      // создали 
	MyButton = new CMyButton();  // Меняем класс, на основе которого создается объект
	if (MyButton!=NULL) MyButton->Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER,
		CRect(120,10,220,50),this,IDC_MYBUTTON);
	MyEdit = new CEdit();
	if (MyEdit!=NULL) MyEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER,
		CRect(240,10,340,50),this,IDC_MYEDIT);
}

Описание

Главная идея этого шага понять, каким методом можно изменить поведение элемента управления, и не только его. С помощью таблиц откликов можно поменять поведение практически любого объекта MFC.

Первым делом, мы создадим свой класс кнопки. Чтобы не делать все сначала, мы возьмем готовый CButton и породим от него свой CMyButton. Так же, как и вы унаследовали от родителей глаза, уши и плохие привычки, так и CMyButton точная копия CButton. Правило такое - сын точная копия папы. Public означает, что папа родной, не отчим. Получение точной копии выглядит так:

class Сын : public Папа

Пора перевоспитать наш CButton под новые требования. Добавили таблицу откликов и описали функции реакции - это знакомо по предыдущему шагу. Правило: детей надо воспитывать, иначе толку никакого.

Внутри функции отклика на кнопку есть функция MoveWindow - эта функция перемещает окно в заданное место. В описании класса CButton этого свойства нет. Но класс CButton тоже сын от CWnd, а в нем это свойство есть. Очередное правило: нет метода у сына - посмотри у папы.

И последнее. В классе главного окна изменить ссылку с CButton на CMyButton. Здесь логично. Выйти замуж за папу или сына разница большая. Естественно и процесс создания и вызова методов нужно изменять.

Все по старому: компиляция, сбор, запуск. По двойному щелчку левой кнопкой объект кнопка переместится вниз, а по щелчку правой вверх. Вот это да!

4_3.gif (3182 b)

Шпаргалка

  1. Создать сына от готового класса:
    class CMyButton: public CButton
    
  2. Воспитать сына:
    class CMyButton: public CButton
    {
    public:
    	afx_msg void OnLButtonDblClk(UINT, CPoint);
    ......
    
  3. Переопределить ссылку:
    CMyButton* MyButton;
  4. Изменить процесс создания и вызова методов сына, заменив папу (через ссылку):
    MyButton = new CMyButton();
    if (MyButton!=NULL) MyButton-> Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER,
    	CRect(120,10,220,50),this,IDC_MYBUTTON);
    

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 30.08.99 (обновлено 25.06.2001)