Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Вопрос про WM_CTLCOLORSTATIC


Автор: yngwie19 28.2.2009, 20:00
Всем привет. Вот кусок кода
Код

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch(msg)
    {
        HANDLE_MSG(hwnd,WM_CREATE,OnCreate);
        HANDLE_MSG(hwnd,WM_CTLCOLORSTATIC,OnCtlColorStatic)  
        HANDLE_MSG(hwnd,WM_DESTROY,OnDestroy);
        default:
            return DefWindowProc(hwnd,msg,wParam,lParam);
    }
}


в макросе для WM_CTLCOLORSTATIC испльзуется функция под названием OnCtlColorStatic,
Код

HBRUSH OnCtlColorStatic(HWND,HDC hdc,HWND,int)
{
    SetBkMode(hdc,TRANSPARENT);
    return GetStockBrush(GRAY_BRUSH);
}


Скажите пожалуйста аргумент hdc получается автоматически? т.е винда внутренне делает:
Код

PAINTSTRUCT ps;
HDC hdc BeginPaint(hwnd,&ps);           // hwnd это хэндл текста?
.......
EndPaint(hwnd,&ps);

Так да?

Автор: Earnest 2.3.2009, 14:25
Цитата(yngwie19 @  28.2.2009,  21:00 Найти цитируемый пост)
т.е винда внутренне делает:

Винда ничего внутренне не делает здесь.  Здесь "делают" макросы.
И что они делают, элементарно посмотреть: они просто преобразовывают WPARAM или LPARAM к нужному типу или раскодируют их, в соответствии с конкретным сообщением.

Цитата

 // hwnd это хэндл текста?

Какого текста? Что ты узнать-то хотел?

Автор: GremlinProg 2.3.2009, 15:10
yngwie19, Не ходи вокруг да около, опиши проблему

WM_CTLCOLORSTATIC - это уведомление родительского окна, которое введено для того, чтобы можно было управлять некоторыми настройками его дочерних девайсов перед выводом в них графики (удобно использовать в диалогах к простым компонентам типа STATIC или просто, когда процедуру окна этих контролов переназначать не хочется, а динамически выставить им цвет фона и текста надо)

рисование этих контролов встроенное, согласно зарегистрированному классу, а это уведомление приходит из процедуры класса окна в ответ на сообщения WM_PAINT, WM_ERASEBKGND и т.п., где требуется отрисовка, т.е. девайсы для них получать не надо

на сколько знаю, нет ни одного уведомления, которое требует распределять граф. девайс
если девайс и нужен, то он передается в параметрах к сообщению

все подобные сообщения маркируются словом Notification, которое обычно и подразумевает уведомление о смене определенного состояния компонента, которое может быть дополнительно скорректировано, если нужно, а может быть просто проигнорировано

Автор: yngwie19 2.3.2009, 17:24
Немного не понятно да? Щас поясню. Допустим Я хочу в главное окно моего приложения  вывести строку текста. Т.к это не диалог, то Я создаю окно со встроенным классом "STATIC". Далее обработываю сообщение WM_CTLCOLORSTATIC для того чтобы изменить фон. При описании функции, которая используется в макросе, у нее есть аргумент HDC hdc - контекст устройства. Мне интересно как он получается.

Цитата

они просто преобразовывают WPARAM или LPARAM к нужному типу или раскодируют их, в соответствии с конкретным сообщением.


Т.е (HDC)wParam ? Т.е при передаче в функцию HBRUSH OnCtlColorStatic мы получаем контекст устройства главного окна? Точно такой-же который мы получили бы с помощью

Код

PAINTSTRUCT ps;
HDC hdc BeginPaint(hwnd,&ps);           // hwnd это хэндл текста?
.......
EndPaint(hwnd,&ps);



если бы сделали в главном окне. 

Автор: GremlinProg 2.3.2009, 18:43
Цитата(yngwie19 @  2.3.2009,  19:24 Найти цитируемый пост)
Т.к это не диалог, то Я создаю окно со встроенным классом "STATIC"

ни чего не понял
что значит создать окно со встроенным классом?
наследовать, чтоли, от класса STATIC?
если так, то это бессмысленно

смотри, есть 2 окна: A и B
A - основное окно
B - дочернее
у каждого из окон выполняются своя процедура окна
пусть процедура дочернего окна(B) выглядит, к примеру, так:
Код

...
case WM_PAINT:
PAINTSTRUCT ps;
BeginPaint(hwnd,&ps);
HBRUSH brush = SendMessage(GetParent(), WM_CTLCOLORSTATIC, (WPARAM)ps.hdc, (LPARAM)hwnd);
FillRect(ps.hdc, &ps.rcPaint, brush);
TextOut(ps.hdc, 0, 0, _T("Вася Пупкин"), 11);
EndPaint(hwnd,&ps);
break;
...

пример простой, понятно что дочерний контрол рисует текст "Вася Пупкин"
если бы отсутствовала пятая строка этого фрагмента,  то контрол рисовался бы одинаково всегда и повлиять на его вид извне было бы невозможно

теперь процедура окна родителя(A):
Код

...
case WM_CTLCOLORSTATIC:
  HDC hdc = (HDC)wParam;
  ::SetTextColor(hdc,RGB(0,255,0));
  return GetSysColorBrush(COLOR_INFOBK);
...

что она делает? перехватывая WM_CTLCOLORSTATIC, она тем самым вклинивается в работу окна B перед рисованием(см. первый фрагмент, строка 5) и заставляет его рисоваться на желтом фоне зелеными буквами

вот для этого и нужен WM_CTLCOLORSTATIC, ни чего ни куда не преобразуется и не создается
это уведомление нужно понимать ровно так, как оно здесь описано, смотри внимательно код: два фрагмента - каждый для своего окна
чтобы использовать WM_CTLCOLORSTATIC, нужно иметь эту связку из двух окон: родительское и дочернее, а диалоговое это приложение или нет - не важно
(макрос HANDLE_MSG ни какой функциональной нагрузки в обработку сообщений не вносит, он лишь позволяет разделить свитч(switch) процедуры окна на мелкие процедурки, которые, возможно, проще понимать, разбирать, модифицировать)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)