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


Автор: regis 9.6.2006, 13:15
Здравствуйте все!

Вопрос наверное для опытных Win-программистов немного чайниковский, за что прошу извинить. Суть такая: если надо рисовать что-то в окне, для получения-освобождения графического контекста используем GetDC/ReleaseDC. Во всех примерах Win-кода, которые я видел, это делается при обработке каждого сообщения (вроме WM_CHAR или WM_KEYDOWN), что меня немного смущает. Почему, собственно, нельзя получить GC один раз при создании окна? Или есть какие-то веские причины для того, чтобы GC создавать/уничтожать каждый раз? Буду признателен специалистам, если объяснят, в чем тут дело.

 

Автор: _hunter 9.6.2006, 13:59
веских -- нету. но ресурсы GDI довольно-таки ограничены и освобождать их максимально быстро считается хорошим тоном. 

Автор: Earnest 9.6.2006, 14:23
Очень часто окно не имеет собственного контекста, а разделяет его с другими окнами.
Тянется это еще со времен Win16, когда ресурсов было мало.
Можно, конечно, при создании окна (т.е. класса) определить, что оно будет иметь собственный контекст. А, например, поля диалога очень часто рисуются в контексте родительского окна. Вот чтобы от этого не зависеть и принято брать контекст "ненадолго". 
И лучше рисовать не в "каждом сообщении", а только в WM_PAINT, получая контекст через BeginPaint. 

Автор: regis 13.6.2006, 14:45
Всем спасибо, но вопросы остались:

Цитата

Очень часто окно не имеет собственного контекста, а разделяет его с другими окнами.
Тянется это еще со времен Win16, когда ресурсов было мало.
Можно, конечно, при создании окна (т.е. класса) определить, что оно будет иметь собственный контекст. А, например, поля диалога очень часто рисуются в контексте родительского окна. Вот чтобы от этого не зависеть и принято брать контекст "ненадолго". 


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

Кстати, еще один вопрос возник: если несколько раз (при обработке одного сообщения, я имею в виду)
сделать GetDC, то будут ли возвращенные контесты одними и тем же, или различными. Я имею в виду примерно следующее:

Код

HDC gc1 = GetDC (hWnd);
HDC gc2 = GetDC (hWnd);

SelectObject (gc1, my_font);


станет ли my_font текущим шрифтом для gc2 или нет?

Цитата

И лучше рисовать не в "каждом сообщении", а только в WM_PAINT, получая контекст через BeginPaint. 


Естественно. Я имею в виду другие ситуации вывода в окно, помимо отрисовки по WM_PAINT. (Если, скажем, надо нарисовать там нечто по нажатию клавиши, движению мыши или по WM_COMMAND.)
 

Автор: Earnest 13.6.2006, 18:29
Цитата(regis @  13.6.2006,  15:45 Найти цитируемый пост)
А как можно разделить контекст с другими окнами? Вроде бы, у контекста слишком много уникальных аттрибутов (кистья, перья, шрифты, своя область отсечения и пр.)?

Контекст - это всего лишь структура данных, с окном особо не связанных. Она больше привязана к девайсу, на котором ты будешь рисовать. Когда ты сначала устанавливаешь свои перья-кисти, а потом убираешь за собой (восстанавливаешь, что было), ты как раз и способствешь безпроблемному использованию этого контекста другими.
Дело даже не столько в том, что контексты могут совместно использоваться, а в том, что "правильный" код сумет нарисовать в любом переданном контексте (а это могут быть экран, принтер, метафайл, etc). Поэтому идиома "получил контекс - установил свои параметры - нарисовал - убрал за собой" и является общепринятой. Насчет многих атрибутов: когда их больше одного-двух удобнее перед установкой своих параметров сохранить состояние контекста (CDC::SaveDC), а потом ахом все восстановить (RestoreDC).

Цитата(regis @  13.6.2006,  15:45 Найти цитируемый пост)
 если несколько раз (при обработке одного сообщения, я имею в виду)
сделать GetDC, то будут ли возвращенные контесты одними и тем же

Точно не знаю, но легко проверить. Думаю, что это зависит от класса окна: если в классе используется common или class DC, то, очевидно, это будет тот же самый контекст. Если private - скорее всего тоже. Но при вызове ReleaseDC установленные атрибуты ведут себя по разному (сбрасываются или нет). 

Зачем усложнять себе жизнь, если можно пользоваться устоявшимися практиками?
 

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