В прошлый раз мы с Вами остановились на том, что неудобно производить обработку событий в классе родителя, а лучше это делать в классе элемента управления. Итак, работаем дальше. Давайте для нашего одного CEdit создадим класс. Внимание будем делать немного по другому, чем раньше. Давайте сначала добавим класс Insert - New Class с именем CMyEdit на основе CEdit. Мы это делали несколько раз, поэтому не буду расписывать. Переходите на диалоговую панель и удерживая клавишу CRTL два раза щелкните по элементу редактирования. Сразу появится окно Add member Variable. Дайте имя переменной m_Ed категория Control, а в поле Variable type выберите наш класс CMyEdit. Нажмите OK. Появится окно сообщения о том, что в TestDlgDlg.h нужно указать ссылку на наш класс CMyEdit, так сделаем это.
// TestDlgDlg.h : header file // #if !defined(AFX_TESTDLGDLG_H__0550E988_BB30_11D4_9414_82C58CEB8362__INCLUDED_) #define AFX_TESTDLGDLG_H__0550E988_BB30_11D4_9414_82C58CEB8362__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "MyEdit.h" ......
Посмотрев внимательно на наш класс диалога мы увидим, что переменная нашего класса там уже есть.
class CTestDlgDlg : public CDialog { // Dialog Data //{{AFX_DATA(CTestDlgDlg) enum { IDD = IDD_TESTDLG_DIALOG }; CMyEdit m_Ed; ...... }
Все настроено, в том числе и DDX. Давайте из класса диалога удалим обработку события WM_CTRLCOLOR. То есть функцию OnCtrlColor(). Если Вы правой кнопкой мыши щелкните на этой функции, то увидите пункт меню delete. Запустите приложение и Вы увидите, что все стало как раньше и цвета больше не меняются. Если мы добавим обработку сообщения WM_CTRLCOLOR в класс CMyEdit, то работать это не будет. По понятиям и не будет. Это сообщение посылается окну родителя, чтобы оно вернуло кисть. А мы хотим, чтобы обработка этого сообщения была именно в классе элемента управления. Вот в этом нам и поможет OnChildNotify(). Это виртуальная функция и она есть у нашего класса CMyEdit. Перегрузите ее:
BOOL CMyEdit::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) { // TODO: Add your specialized code here and/or call the base class return CEdit::OnChildNotify(message, wParam, lParam, pLResult); }
И давайте изменим код, чтобы она что-то делала. Добавим в наш класс ссылку на кисть.
class CMyEdit : public CEdit { ...... public: CBrush m_bg; virtual ~CMyEdit();// Generated message map functions ...... }
А теперь поменяем код:
/////////////////////////////// // CMyEdit message handlers BOOL CMyEdit::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) { if (message != WM_CTLCOLOREDIT) { return CEdit::OnChildNotify(message,wParam,lParam,pLResult); } HDC hdcChild = (HDC)wParam; SetTextColor(hdcChild, RGB(0,0,255)); SetBkColor(hdcChild, RGB(0,128,0)); m_bg.CreateStockObject(GRAY_BRUSH); *pLResult = (LRESULT)(m_bg.GetSafeHandle()); return TRUE; }
Итак, мы с Вами сделали главное. Посмотрели, что внутри класса можно обрабатывать сообщения. Это уже лучше, потому что не надо перегружать класс родителя.