C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 289 - Изучаем сообщения на примере WM_CTLCOLOR / MFC шаг за шагом / Visual C++

Шаг 289 - Изучаем сообщения на примере WM_CTLCOLOR

Это очень показательное сообщение. Сообщение WM_CTLCOLOR посылается каждый раз когда само окно или одно из его средств управления должно перерисоваться. В ответ должна вернуться кисть для перерисовки.

Итак, давайте изучать. Создаем приложение на базе MFC AppWizard с именем TestDlg как диалоговое окно. Для класса CTestDlgDlg вызовем Add Windows Message Handler. Найдем там сообщение WM_CTLCOLOR и добавим его обработку к классу.

////////////////////////////////
// CTestDlgDlg dialog

class CTestDlgDlg : public CDialog
{
	......
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

HBRUSH CTestDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO: Change any attributes of the DC here

	// TODO: Return a different brush if the default is not desired
	return hbr;
}

Давайте заменим кисть, чтобы окрасить окно в разные цвета:

HBRUSH CTestDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    pDC->SetBkColor(RGB(127,127,127));
    return (HBRUSH)::GetStockObject(GRAY_BRUSH);
}

Если Вы сейчас запустите приложение, то окно будет серым. Это нормально, мы так и хотели. Поместите на диалоговую панель Edit Box, Static Box. Запустите приложение. Они тоже будут серыми. Эти элементы управления спрашивают кисть для покраски у родителя, то есть они посылают сообщение диалоговому окну с просьбой указать чем красить. Давайте попробуем это исправить.

HBRUSH CTestDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	if (CTLCOLOR_EDIT == nCtlColor)
	{
		pDC->SetTextColor(RGB(0,0,0)); 
		pDC->SetBkColor(RGB(255,255,255));
		return (HBRUSH)::GetStockObject(WHITE_BRUSH);
	}

	if (CTLCOLOR_STATIC == nCtlColor)
	{
		pDC->SetBkColor(RGB(255,0,255));
		return (HBRUSH)::GetStockObject(GRAY_BRUSH);
	}

	pDC->SetBkColor(RGB(127,127,127));
    	return (HBRUSH)::GetStockObject(GRAY_BRUSH);
	
}

Вот теперь совсем другое дело. Белое поле редактирования, красный статический элемент. Работает. А что если у нас много элементов управления ??? Как разобраться какой красить ??? Поместите второй элемент управления и код для него:

HBRUSH CTestDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	if (CTLCOLOR_EDIT == nCtlColor)
	{
		UINT id = pWnd->GetDlgCtrlID();
		if (id == IDC_EDIT2)
		{
			pDC->SetTextColor(RGB(0,0,0)); 
			return (HBRUSH)::GetStockObject(WHITE_BRUSH);
		}
		if ( id == IDC_EDIT1)
		{
			pDC->SetTextColor(RGB(0,0,0)); 
			return (HBRUSH)::GetStockObject(DKGRAY_BRUSH);
		}
	}

	if (CTLCOLOR_STATIC == nCtlColor)
	{
		pDC->SetBkColor(RGB(255,0,255));
		return (HBRUSH)::GetStockObject(GRAY_BRUSH);
	}

    pDC->SetBkColor(RGB(127,127,127));
    return (HBRUSH)::GetStockObject(GRAY_BRUSH);
}

Как видите разобраться можно. Есть следующие идентификаторы:

  • CTLCOLOR_BTN - Кнопка
  • CTLCOLOR_DLG - Диалог
  • CTLCOLOR_EDIT - Элемент редактирования
  • CTLCOLOR_LISTBOX - Список
  • CTLCOLOR_MSGBOX - Окно сообщений
  • CTLCOLOR_SCROLLBAR - Скролинг
  • CTLCOLOR_STATIC - Статический текст

Все это хорошо, только сейчас мы реализовали все как при программировании на WIN32 API без всяких там классов. Но в реальности правильно, если за закраску будет отвечать сам класс. Так должно быть. Не должен диалог отвечать за закраску своих элементов. Иначе при большом количестве идентификаторов ваша функция OnCtlColor() превратится в сплошной switch. Об этом в следующем шаге. А пока посмотрите на результат. Он у Вас должен быть такой же.

289.gif (1783 b)


| |
Автор Каев Артем.
[AD]