Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021

Ручная прорисовка интерфейса

06.07.2009, 15:09. Показов 2765. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу программу, которая сама рисует пользовательский интерфейс на форме.
И вот столкнулся со странной проблемой.
На форме рисуются битмапы, которые до этого были загружены в ресурсы.
Битмапы вывожу так:

CBitmap bitmap;
bitmap.LoadBitmap(IDC_BIT1);
MemDC.SelectObject(bitmap);
m_memDC.BitBlt(10,10,400, 35, &MemDC, 0, 0, SRCCOPY);

При запуске все работает отлично. Но проходит некоторое время и битмапы перестают отображаться на экране или отображается какой то один из них вместо всех. Область шапки окна тоже начинает как то странно перерисовываться.

Подозреваю что это где то утечка памяти, проверил встроенным анализатором, ничего криминального не нашел.
Самое странно что все элементы управления,заливки, текст, все отлично прорисовывается.

Буду очень благодарен если кто нибудь сможет подсказать в какую сторону копать!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.07.2009, 15:09
Ответы с готовыми решениями:

Ручная прорисовка сферы
Здравствуйте, форумчани. Возник вопрос по ниже приведенному коду. Тут сфера прорисовывается треугольниками. Нужен альтернативный...

Прорисовка всего интерфейса приложения самому (например, в фотошопе)
Как самими нарисовать вот этой ? Как самим сделать красивый Progress Bar ? тоесть самим нарисовать его в фотошопе к примеру и использовать...

Как увидеть методы в классах, которые реализованы из интерфейса и перейти в них из интерфейса?
Как увидеть методы класса, которые реализованы из интерфейса и перейти в них из этого интерфейса, то есть все классы где данный метод...

12
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
06.07.2009, 15:13
А ты перерисовываешь свои рисунки на обновлении окна? Когда окно перерисовывается, ты из перерисовываешь? Ты их раз нарисовал, они там вечно не будут храниться. И скриншот, плз, в студию - до и после.
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
07.07.2009, 07:32  [ТС]
Интерфейс весь рисую так:
Когда мне нужно что то перерисовать вызываю функцию Draw, которая рисует все в копию экрана, в m_memDC. После этого вызываю Invalidate.
В onPaint идет только копирование m_memDC на экран:

CPaintDC paintDC(this);
RECT clientRect;
GetClientRect(&clientRect);
paintDC.BitBlt(0, 0, clientRect.right, clientRect.bottom,&m_memDC, 0, 0, SRCCOPY);

После того как проявился этот глюк, его на экране становится видно при первом же вызове функции Draw.
Причем перед его появлением экран был перерисован не одну сотню раз...

Добавлено через 1 час 40 минут 47 секунд
И еще после работы программы длительный срок, 1-3 дня, некоторые элементы прорисовывались в клиентской области экрана, а не окна. Можно ли как то отследить какая функция все портит?
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
07.07.2009, 08:07  [ТС]
Во вложении скрины
1 нормальная работа
2,3 глюк
Миниатюры
Ручная прорисовка интерфейса   Ручная прорисовка интерфейса   Ручная прорисовка интерфейса  

0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
07.07.2009, 08:35
Цитата Сообщение от vitaly1981 Посмотреть сообщение
Подозреваю что это где то утечка памяти
...и ожидаешь, что мы по описанию найдем у тебя утечку??
код лучше выложи.
все, что относится к рисованию.
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
07.07.2009, 09:09  [ТС]
Цитата Сообщение от Patch Посмотреть сообщение
...и ожидаешь, что мы по описанию найдем у тебя утечку??
Нет конечно, я ожидаю что может кто нибудь подскажет где находится область памяти на которую я мог залезть, и можно ли как то отловить тот момент когда в эту область попадают левые данные. Я так понимаю, что когда я напрямую беру bitmap и рисую его на экране он может не отображаться только если сам битмап битый. Копия экрана в памяти целая, все что под битмапами рисую, отображается нормально.
И еще иногда не до конца прорисовываются стандартные элементы (кнопки, эдиты) , тогда как дочерние окна, в которых я сам все рисую, продолжают работать как буд то ничего не произошло.
0
2 / 2 / 1
Регистрация: 21.05.2009
Сообщений: 12
07.07.2009, 17:14
утечка памяти происходит в самой системе. она возникает тогда когда ты не удаляешь сами обьекты типа bitmap или pen или подобные им. поэтому после окончания рисование все эти обьекты нужно удалить bitmap.DeleteObject() и еще после окончания рисования нужно убрать его из памяти dc - MemDC.SelectObject(bitmap);(вызвать повторно).

Добавлено через 2 минуты 15 секунд
Если я прав и ты это не удаляешь. то будет плохо или по отдельности прорисовываться практически все твое приложение. а при попытки сделать скриншот printscreen выпадет сообщение об не хватки ресурсов.
1
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
07.07.2009, 19:34  [ТС]
volok-aleksej, Вот этого не знал, я считал что эти обьекты сами должны деинициализироваться, так как создавались статически в функции прорисовки. Спасибо за информацию!
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
22.07.2009, 07:42  [ТС]
Все сделал как написал volok-aleksej.
В одной программе вопрос решился.
Но во второй глюк остался. Удалось отловить участок кода в функции Draw, при выполнении которого начинаются косяки, как только программа начинает прорисовывать обходя этот код, все глюки махом исчезают. Основное отличие этого участка кода это масштабирование битмапа.

Вот эти куски кода:

float Scale=1.3;

CBitmap bitmap4;
bitmap4.LoadBitmap(Analiz2(line,block));
MemDC.SelectObject(bitmap4);
HBITMAP mdcScaled= CreateCompatibleBitmap(MemDC,21*Scale,28 *Scale);
SelectObject( MemDC2,mdcScaled); StretchBlt(MemDC2,0,0,21*Scale,28*Scale, MemDC,0,0,21,28,SRCCOPY);
bitmap4.DeleteObject();

if(block<32)m_memDC.BitBlt(UpBlockX,UpBl ockY,21*Scale, 28*Scale, &MemDC2, 0, 0, SRCCOPY);
else m_memDC.BitBlt(DownBlockX,DownBlockY,21* Scale, 28*Scale, &MemDC2, 0, 0, SRCCOPY);

Закоментил этот код в программе, пока нет косяков.
0
2 / 2 / 1
Регистрация: 21.05.2009
Сообщений: 12
22.07.2009, 11:14
Итак что делает код(поправь если не так):
вначале он загружает битмап, и вносит его в контекст;
потом создает совместимый с контекстом новый битмап и заносит его в контекст,но другой, который не понятно откуда взялся;
маштабирует на этом новом контексте и удаляет первоначальный битмап(не вынося его из контекста);
после чего в зависимости от block, поразному копирует его в родной контекст.
Ну, во-первых, я уже говорил нужно выносить из контекста, перед удалением, обьекты. Далее, способ масштабирования выбран ну экстраординарный.... а не проще было создать этот второй контекст на нем нарисовать битмапу, а потом её с масштабировать на родной контекст(зачем так усложнять себе жизнь). Далее, я не вижу где удаляеться обьект mdcScaled и обьект MemDC2(кстате и где он создаеться). И последнее, если же ты уж используешь битмапу вначале на родном контексте то будь добр нарисуй на нем её, а то просто внес и все, и что это даст(она черной останется или белой, везде поразному). Когда ты вносишь битмапу в контекст, то ты таким образом говоришь, что все опирации рисования будут проводиться паралельно и на битмапе(но не наоборот), которую ты потом сможешь сохранить. Я вообще поражаюсь как она тебе её вообще рисовала...

Добавлено через 5 минут 48 секунд
Возможно я и ошибаюсь, может и можно так рисовать как ты, через контекст, но я лично пользуюсь отдельной функцией DrawState. универсальная для всех видов картинок(иконок,битмапов, курсоров...).
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
22.07.2009, 11:53  [ТС]
Контексты создавались в начале функции прорисовки, вот так:
CDC MemDC;MemDC.CreateCompatibleDC(&m_memDC) ;
CDC MemDC2;MemDC2.CreateCompatibleDC(&m_memD C);
Я так понимаю что после окончания выполнения функции они уничтожатся, или их нужно еще как то деинициализировать?

Саму технику масштабирования нашел в примерах в инете. ) Нигде не смог найти человеческого описания техники работы с этими функциями.

Фактически мне нужно получить констекст, например MemDC, который будет содержать смасштабированный битмап. Сразу вывести его в копию всей области окна ( m_memDC ) я не могу, так как для него еще может задаваться полупрозрачность в некоторых ситуациях.

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

Попробовал сделать так:

CDC MemDC;MemDC.CreateCompatibleDC(&m_memDC) ;
float Scale=1.3;
CBitmap bitmap4;
bitmap4.LoadBitmap(Analiz2(line,block));
MemDC.SelectObject(bitmap4);
StretchBlt(MemDC,0,0,21*Scale,28*Scale,M emDC,0,0, 21,28,SRCCOPY);
MemDC.SelectObject(bitmap4);
bitmap4.DeleteObject();

if(block<32)m_memDC.BitBlt(UpBlockX,UpBl ockY,21*Scale, 28*Scale, &MemDC, 0, 0, SRCCOPY);
else m_memDC.BitBlt(DownBlockX,DownBlockY,21* Scale, 28*Scale, &MemDC, 0, 0, SRCCOPY);

Рисует, но границы остаются как у несмасштабированного битмапа.
0
2 / 2 / 1
Регистрация: 21.05.2009
Сообщений: 12
22.07.2009, 18:26
Цитата Сообщение от vitaly1981 Посмотреть сообщение
Я так понимаю что после окончания выполнения функции они уничтожатся, или их нужно еще как то деинициализировать?
конечно нужно.
Цитата Сообщение от vitaly1981 Посмотреть сообщение
Фактически мне нужно получить констекст, например MemDC, который будет содержать смасштабированный битмап. Сразу вывести его в копию всей области окна ( m_memDC ) я не могу, так как для него еще может задаваться полупрозрачность в некоторых ситуациях.
а что за полупрозрачность, как ты это собераешся реализовывать? в стандартных функциях винды этого нет.Я по крайней мере их не знаю.

Цитата Сообщение от vitaly1981 Посмотреть сообщение
Рисует, но границы остаются как у несмасштабированного битмапа.
И не удивительно...
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
23.07.2009, 08:26  [ТС]
Полупрозрачность уже реализовал, тут проблем нет )

BLENDFUNCTION blend2={AC_SRC_OVER,0,255/2,0};
m_memDC.AlphaBlend(UpBlockX,UpBlockY,21, 28,&MemDC,0,0,21,28,blend2);

Очистку попробую всю сделать. Я так понял что нужно ReleaseDC делать а потом deleteDC?

Но все равно не врубаюсь почему глюки из за функции масштабирования, закоментил масштабирование, все уже больше суток пашет без единого глюка.....

Добавлено через 36 минут 28 секунд
Все, кажись я понял в чем была проблема.
Сейчас проверяю, если подтвердится то тему можно закрыть.

Добавлено через 1 час 15 минут 37 секунд
Походу все подтверждается.
Дело в том что я масштабирую и вывожу в одну область два разных битмапа, сначала один как подложку, а на нем рисую второй, второй немного меньше первого по высоте. И получилось что я в функцию масштабирования второго битмапа передал размеры первого, то есть немного больше. Сам вывод смасштабированного битмапа был написан корректно, поэтому лишний кусок не отображался.
Получается что функция StretchBlt пишет какие то данные в исходный битмап что ли, и поэтому она залазила на какую то левую область памяти, после чего начиналась такая светомузыка не только в моем окне, а на всей области экрана.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.07.2009, 08:26
Помогаю со студенческими работами здесь

Ручная сортировка
Добрый вечер! Картины выводятся из БД по id, необходимо переодически вручную менять их порядок. Подскажите, пожалуйста, как лучше...

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

Ручная модерация "тематики"?
Привет всем. Такой момент. Есть аккуратно продвигаемый СДЛ статьями на белых тематических ресурсах. ВЧ и ряд сопутсвующих НЧ запросов....

Ручная зборка LiveDVD
как сделать так чтобы в меню файла был выбор лецинзионной винды если я её добавлю в образ

Ручная подгонка параметров
Здравствуйте. У меня такая проблема. С помощью экспериментальных данных и оптимизации нужно определить коэффициенты функции, определяющие...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в КА2. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 23.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа в КА2. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru