Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

За 2006-04-24

Re[2]: Течет ручей, бежит ручей. И ты ничья и я ничей.

Hello Ischuk и Victor,

Sunday, April 23, 2006, 1:48:44 PM, you wrote:

IP> Попробуё сделать таким-вот образом:
IP> 1 Создай переменную СBitmap *pOldBmp;
IP> 2 Вызывай функцию pOldBmp=SetBitmap(твой_рисунок);
IP> 3 Затем, в конце цикла
IP> pDC->SelectObject( pOldBmp ); //где pDC- контекст рисования

// Получаем DC для рисования
HDC hDC = ::GetDC (GetSafeHwnd());
// Выбираем свой HBITMAP в DC, запоминаем старый HBITMAP
HBITMAP hOldBit = (HBITMAP)SelectObject(hDC, NewBmp);
// Выбираем старый BITMAP в DC (освобождаем свой BITMAP из DC)
SelectObject(hDC, hOldBit);

// Удаляем BITMAP
DeleteObject (NewBmp);

// Освобождаем DC
::ReleaseDC (GetSafeHwnd(), hDC);

Вот если таким образом, то никаких утечек нет. Осталось выяснить почему на кнопке
ничего не вырисовывается :) Может неправильно задаю какие свойства кнопок.

VVV> Эти переменные надо инициализировать, сохранять, пока ведется
VVV> работа (всякие SetBitmap-ы используются, и.т.д.)
VVV> Потом, когда битмапы больше не нужны, надо выбрать для кнопки
VVV> битмап SetBitmap(NULL) и уничтожить все битмапы при помощи DeleteObject.
VVV> Тогда не будет утечки ресурсов.
Добавление перед SetBitmap'om конструкции
HBITMAP NewBmp=GetBitmap();
SetBitmap(NULL);
DeleteObject(NewBmp);
увеличивает толщину ручья (утечки памяти) в 2 раза.

VVV> Вобщем, идеология работы с ресурсами GDI такая:
VVV> 1. создал
VVV> 2. выбрал куда то, при этом сохранив то, что там было ранее
VVV> Например, при выборе битмапа в совместимый контекст устройства,
VVV> надо сохранять дескриптор битмапа, который в нем уже выбран.
VVV> 3. попользоваться
VVV> 4. вернуть все обратно (старые битмапы выбрать туда, где они были раньше,
VVV> и.т.д.).
VVV> 5. убить все созданные ресурсы
Давай представим идеальный случай: в цикле крутятся 3 HBITMAP bit1, bit2, bit3
которые загружены при старте программы. Этот цикл надо прервать только перед
выходом программы. Какие шаманские действия с SetBitmap надо сделать, чтобы
не было утечек?

>> Подскажите, люди, где про них почитать можно.
VVV> В MSDN, наверно. Ну и всякие книжки по программированию в винде, где
VVV> про рисование упоминается.
Ага. Нашел книжонку (Дэвида Круглински). Начал по-немногу заставлять себя
сидеть с ней в обнимку. Пока не помогает. Наверно, надо ее попробовать
открыть :) Так что скоро сам все пойму. Всем спасибо за ответы.

   2006-04-24 22:02:08 (#541307)

Re: Течет ручей, бежит ручей. И ты ничья и я ничей.

Здравствуйте!

>> Подскажите, люди, где про них почитать можно.
> В MSDN, наверно. Ну и всякие книжки по программированию в винде, где
> про рисование упоминается.

Могу порекомендовать книгу Павла Румянцева
"Азбука программирования в Win32 API"

С уважением, AleX

Номер выпуска : 5291
Возраст листа : 946 (дней)
Количество подписчиков : 544
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/540993
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

   2006-04-24 04:14:03 (#540993)

Re: Течет ручей, бежит ручей. И ты ничья и я ничей.

Здравствуйте !

> Попробуё сделать таким-вот образом:
> 1 Создай переменную СBitmap *pOldBmp;
> 2 Вызывай функцию pOldBmp=SetBitmap(твой_рисунок);
> 3 Затем, в конце цикла
> pDC->SelectObject( pOldBmp ); //где pDC- контекст рисования

Наверно в отношении кнопок это не очень актуально, т.к.
кнопке изначально битмап не сопоставлен.
Однако, использование MFC-шных врапперов вообще, весьма упрощает
работу с GDI-объектами.
Напрмер, применительно к исходной задаче можно создать массив объектов
CBitmap, загрузить битмапы с помощью CBitmap::LoadBitmap, а когда
битмапы больше станут не нужны, просто убить весь массив (а если
он статически выделен - вообще ничего не делать). Тогда будут
вызваны деструкторы всех элементов - объектов CBitmap.
CBitmap наследован от CGdiObject. А в деструкторе CGdiObject производится
вызов CGdiObject::DeleteObject, в которой GDI объект уничтожается
при помощи ::DeleteObject.
То есть, код будет гораздо меньше, не надо особо заботится об удалении
GDI-объектов.

   2006-04-24 00:10:26 (#540939)