|
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
|
|
| 06.07.2009, 15:09 | |
|
Ответы с готовыми решениями:
12
Прорисовка всего интерфейса приложения самому (например, в фотошопе) Как увидеть методы в классах, которые реализованы из интерфейса и перейти в них из интерфейса? |
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
| 06.07.2009, 15:13 | |
|
А ты перерисовываешь свои рисунки на обновлении окна? Когда окно перерисовывается, ты из перерисовываешь? Ты их раз нарисовал, они там вечно не будут храниться. И скриншот, плз, в студию - до и после.
0
|
|
|
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
|
|
|
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 | ||
![]() код лучше выложи. все, что относится к рисованию.
0
|
||
|
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
|
||
| 07.07.2009, 09:09 [ТС] | ||
|
И еще иногда не до конца прорисовываются стандартные элементы (кнопки, эдиты) , тогда как дочерние окна, в которых я сам все рисую, продолжают работать как буд то ничего не произошло.
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
|
|
|
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
|
|
| 07.07.2009, 19:34 [ТС] | |
|
volok-aleksej, Вот этого не знал, я считал что эти обьекты сами должны деинициализироваться, так как создавались статически в функции прорисовки. Спасибо за информацию!
0
|
|
|
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
|
|
|
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 | ||||
|
0
|
||||
|
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
|
|
| 23.07.2009, 08:26 | |
|
Помогаю со студенческими работами здесь
13
В программе два интерфейса и нужно чтобы при выводе сообщения в тексбоксе 1 интерфейса, текст сразу отображался Ручная модерация "тематики"? Ручная зборка LiveDVD Ручная подгонка параметров Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
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.
В качестве фильтра для отбора справочника служит группа номенклатуры.
Отбор по наименованию. . .
|