Продолжаем развитие нашего проекта дальше.
Это вписывается после последнего #define. Вот сюда:
Мы записываем объявление класса в самое начало, чтобы его было видно во всем файле.
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 мы сможем увидеть, что добавился новый класс:
И изменяем класс кнопки в рамке окна:
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. Здесь логично. Выйти замуж за папу или сына разница большая. Естественно и процесс создания и вызова методов нужно изменять.
Все по старому: компиляция, сбор, запуск. По двойному щелчку левой кнопкой объект кнопка переместится вниз, а по щелчку правой вверх. Вот это да!
class CMyButton: public CButton
class CMyButton: public CButton { public: afx_msg void OnLButtonDblClk(UINT, CPoint); ......
CMyButton* MyButton;
MyButton = new CMyButton(); if (MyButton!=NULL) MyButton-> Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER, CRect(120,10,220,50),this,IDC_MYBUTTON);