Шаг 290 - Изучаем сообщение WM_CTLCOLOR - OnChildNotify()

В прошлый раз мы с Вами остановились на том, что неудобно производить обработку событий в классе родителя, а лучше это делать в классе элемента управления. Итак, работаем дальше. Давайте для нашего одного 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;
}

Итак, мы с Вами сделали главное. Посмотрели, что внутри класса можно обрабатывать сообщения. Это уже лучше, потому что не надо перегружать класс родителя.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.