Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8

Проблемы с отрисовкой в MFC

24.01.2013, 22:58. Показов 2275. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.

Столкнулся с проблемой при разработке графического редактора (MFC MDI), а именно, при большом кол-ве графических элементов программа не может их отобразить в документе, иногда отображает только часть, либо часть рисует с использование определенно заданных пера и заливки, а часть по умолчанию. Появляются сообщения о невозможности создания пера/заливки. Например, генерирую матрицу ячеек 64*64, то идет подвисание программы или краш, либо начинаются проявляться множественные артефакты, некорректно отрисовано меню, контексное меню и другое. Ячейки представляют собой квадрат (доп. инфа - размер ячейки 60 пикселей, режим MM_TEXT, размер документа 10000x10000).
Я использую класс CMemDC (http://www.codeproject.com/Art... ing-In-MFC) для двойного буфера, но пробовал и без него, и все равно не справляется с отрисовкой.
Использую студию VS6.0.

Что можете посоветовать в этой ситуации?
Буду благодарен любым советам.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.01.2013, 22:58
Ответы с готовыми решениями:

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

Проблемы с отрисовкой объекта Image
Написал игру. Стал все текстурами украшать и столкнулся с вот такой проблемой: объект Image с наложенной текстурой при движении по...

Игра Реверси: проблемы с отрисовкой в программе
Пытаюсь написать игру Реверси. Но вот уже долго бьюсь над одной проблемой: глючит графика..или вся программа.. Причем одни и те же действия...

17
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
25.01.2013, 21:29
посмотри на предмет утечки ресурсов
самый простой путь запускаешь свою программу и диспетчер задач
в диспетчере задач вид - выбрать столбцы
поставь галочку на "объекты GDI" и смотри на свой процесс если GDI постоянно увеличиваются значит идет утечка
винда может поддерживать ограниченное количество GDI объектов(32000 по моему)
удаляешь ли ты после отрисовки свои перья,кисти.....

нужно делать так
например выбрали кисть запомнили старую
C++
1
CBrush * oldBr=dc->SelectObject(&br);
в конце вспомнили старую
C++
1
dc->SelectObject(oldBr);
иначе кисть не удалится и будет утечка

Добавлено через 1 минуту
Цитата Сообщение от Ukuelig Посмотреть сообщение
размер документа 10000x10000).
код отрисовки покажи
1
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8
25.01.2013, 21:47  [ТС]
Код отрисовки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void CObjCell::Draw(CDC* pDC)
{
    // Подготавливаем контекст
    PrepareDC(pDC);
    // Цвет выделения
    CPen aPen;
    if(m_FlagHighlighting)
    {
        if(!aPen.CreatePen(PS_SOLID, m_iPenWidth, SELECT_COLOR))
            AfxMessageBox(_T("Не удалось создать перо для рисования ячейки"),MB_OK);
        else
            pDC->SelectObject(&aPen);
    }
    
    pDC->Rectangle(m_FirstPoint.x, m_FirstPoint.y, m_FirstPoint.x + m_Width, m_FirstPoint.y + m_Height);
 
    // Текст
    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(RGB(0,0,255));
    pDC->TextOut(m_FirstPoint.x + m_Width, m_FirstPoint.y - 5, m_NameCell);
 
    // Восстанавливаем контекст
    RestoreDC(pDC);
}
 
BOOL CObjElement::PrepareDC(CDC *pDC)
{
    // Сохраняем состояние контекста устройства
    if(!pDC->SaveDC()) return FALSE;
    // Устанавливаем перо и кисть 
    if(HPEN(m_Pen)!=NULL)
        pDC->SelectObject(&m_Pen);
    if(HBRUSH(m_Brush)!=NULL)
        pDC->SelectObject(&m_Brush);
    return TRUE;
}
 
BOOL CObjElement::RestoreDC(CDC *pDC)
{
    // Восстанавливаем состояние контекста устройства
    return pDC->RestoreDC(-1);
}
Значит получается, восстановить сохраненное состояние контекста недостаточно?
0
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
25.01.2013, 22:01
Цитата Сообщение от Ukuelig Посмотреть сообщение
void CObjCell:raw(CDC* pDC)
когда у тебя вызывается? по WM_PAINT?

Цитата Сообщение от Ukuelig Посмотреть сообщение
pDC->SaveDC()
никогда не пользовался даже не знаю зачем может пригодится

Цитата Сообщение от Ukuelig Посмотреть сообщение
if(HPEN(m_Pen)!=NULL)
* * * * pDC->SelectObject(&m_Pen);
* * if(HBRUSH(m_Brush)!=NULL)
* * * * pDC->SelectObject(&m_Brush);
вот она утечка


Цитата Сообщение от Ukuelig Посмотреть сообщение
BOOL CObjElement::PrepareDC(CDC *pDC)
возвращаем значение удачно/неудачно

Цитата Сообщение от Ukuelig Посмотреть сообщение
PrepareDC(pDC);
и не пользуемся
а если SaveDC отработала с ошибкой?
мы все равно продолжаем рисовать

Добавлено через 1 минуту
Цитата Сообщение от Ukuelig Посмотреть сообщение
Значит получается, восстановить сохраненное состояние контекста недостаточно
я же говорю посмотри в диспетчере задач количество GDI объектов растет или не растет
1
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8
25.01.2013, 22:31  [ТС]
Посмотрел, растет только так. Доходит до 10000 и все обрывается.

Добавлено через 10 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
когда у тебя вызывается? по WM_PAINT?
Нет, обработчик OnDraw
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void CMatchingCellsView::OnDraw(CDC* pDC)
{
    CMatchingCellsDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
 
    CMemDC pMemDC(pDC);
    DrawGrid(pMemDC);
 
    CObjElement* pObjElement = NULL;
    POSITION pPos = pDoc->GetHeadPositionListComponents();
    while(pPos)
    {
        pObjElement = pDoc->GetNextInListComponents(pPos);
        pObjElement->Draw(pMemDC);
    }
}
0
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
25.01.2013, 22:44
Цитата Сообщение от Ukuelig Посмотреть сообщение
OnDraw
это и есть обертка над WM_PAINT (чаще всего)
он еще и для принтера используется но редко
Цитата Сообщение от Ukuelig Посмотреть сообщение
DrawGrid(pMemDC);
странные у вас понятие о MemDC
вкратце это делается так
создается контекст в памяти
создается битмап
рисуется в памяти
потом разом копируется из памяти на экран
удаляется контекст в памяти
называется двойная буферизация
используется для исключения мельканий

Цитата Сообщение от Ukuelig Посмотреть сообщение
осмотрел, растет только так.
перепиши выбор объектов
Цитата Сообщение от Ukuelig Посмотреть сообщение
Доходит до 10000 и все обрывается
не хватает объектов
Виндос98 вообще намертво вешало
1
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8
25.01.2013, 22:51  [ТС]
Эти функции были взяты из книги, потом перекочевали в новую прогу. Опыта с GUI не так много, не особо задумался об их назначении, теперь буду опытней. Спасибо.

Заодно спрошу по этой же тематике вопрос, как оптимизировать отрисовку / обновление в окне большого кол-ва графических элементов? Прога долго их рисует (загрузка цп под 50-100%), можно почти сказать что зависла, если нажать может отвалиться. А при перемещение скорлов очень медленно сдвигает эту композицию, что работать становиться практически невозможно.
Что можете здесь посоветовать?
Буду благодарен за любые советы куда копать.

Добавлено через 3 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
странные у вас понятие о MemDC
А чем плох класс CMemDC pMemDC(pDC) (он и выполняет двойную буферизацию) от товарища с codeproject или лучше самому написать этот блок?
0
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
25.01.2013, 22:58
Цитата Сообщение от Ukuelig Посмотреть сообщение
Заодно спрошу по этой же тематике вопрос, как оптимизировать отрисовку / обновление в окне большого кол-ва графических элементов? Прога долго их рисует (загрузка цп под 50-100%), можно почти сказать что зависла, если нажать может отвалиться. А при перемещение скорлов очень медленно сдвигает эту композицию, что работать становиться практически невозможно.
Что можете здесь посоветовать?
рисовать не все а часть
например
Цитата Сообщение от Ukuelig Посмотреть сообщение
размер документа 10000x10000)
а на экран выводится 1024х726
значит вводим две переменные смешение по вертикали и по горизонтали(они могут зависеть от скроллеров)
и когда нужно рисовать рисуем 1024х726 часть экрана
другой вариант если картинка статическая (только очень большая)
рисуем в памяти
создаем битмап 10000x10000
рисуем в нем все что нужно

а при выводе копируем на экран только то что нужно
посмотри на
BitBlt
http://vsokovikov.narod.ru/New... bitblt.htm
http://www.firststeps.ru/mfc/steps/help/r.php?777
1
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8
25.01.2013, 23:05  [ТС]
Картинка статичная, никакой динамики однозначно
А что можно сделать, если есть функция масштабирования документа, и можно отобразить все объекты, то он опять же будет их очень долго прорисовывать / а при сдвиги скорлов нечеловеческая скорость работы ?
0
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
25.01.2013, 23:11
Цитата Сообщение от Ukuelig Посмотреть сообщение
если есть функция масштабирования документа, и можно отобразить все объекты,
Для масштабирования StretchBlt
http://vsokovikov.narod.ru/New... tchblt.htm
может тебе стоит посмотреть в сторону DirectDraw или OpenGl
1
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8
25.01.2013, 23:26  [ТС]
Это темный лес для меня, там новичку можно разобраться без пол литра?
Вроде бы код и простой, выводит квадраты, шины между ними и группы, а такие сложности возникают.
0
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
25.01.2013, 23:31
Цитата Сообщение от Ukuelig Посмотреть сообщение
там новичку можно разобраться без пол литра?
Андре Ламот: Программирование игр для Windows
по моему неплохо описан DirectX


Цитата Сообщение от Ukuelig Посмотреть сообщение
Вроде бы код и простой выводить квадраты, шины между ними и группы, а такие сложности.
мне приходится работать с программами редактирования электрических схем
Все поддерживают DirectDraw
если его выключить начинаются косяки с перерисовкой торможение
0
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8
26.01.2013, 00:03  [ТС]
А в структуру Doc/View нет возникнет проблем интегрировать DirectX?
Для новичка проще использовать DirectX?
0
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
26.01.2013, 00:10
Цитата Сообщение от Ukuelig Посмотреть сообщение
А в структуру Doc/View нет возникнет проблем интегрировать DirectX?
да ни каких
просто добавишь библиотеки и немного поменяешь логику отрисовки
Цитата Сообщение от Ukuelig Посмотреть сообщение
Для новичка проще использовать DirectX?
не могу сказать поскольку давно не новичек
скачай книгу и почитай
0
26.01.2013, 00:13

Не по теме:

Цитата Сообщение от Ukuelig Посмотреть сообщение
Для новичка проще использовать DirectX?
Смотря насколько новичок. Если совсем, то, думаю, может быть тяжеловато.

0
Модератор
Эксперт по электронике
8979 / 6745 / 921
Регистрация: 14.02.2011
Сообщений: 23,856
26.01.2013, 00:15
Цитата Сообщение от Croessmah Посмотреть сообщение
Смотря насколько новичок.
в gdi же рисует а там по моему ненамного сложнее, а некоторые вещи трансформация, масштабирование дак еще и проще
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
26.01.2013, 04:26
Цитата Сообщение от Ukuelig Посмотреть сообщение
Столкнулся с проблемой при разработке графического редактора (MFC MDI), а именно, при большом кол-ве графических элементов программа не может их отобразить в документе, иногда отображает только часть, либо часть рисует с использование определенно заданных пера и заливки, а часть по умолчанию. Появляются сообщения о невозможности создания пера/заливки. Например, генерирую матрицу ячеек 64*64, то идет подвисание программы или краш, либо начинаются проявляться множественные артефакты, некорректно отрисовано меню, контексное меню и другое. Ячейки представляют собой квадрат (доп. инфа - размер ячейки 60 пикселей, режим MM_TEXT, размер документа 10000x10000).
- Это говорит что твоя программа имеет утечки объектов GDI - от анального создал перо и не удалил до возможно контекст где то не сбрасываешь
1 - е чтобы убедиться в моих словах выставь в своём диспетчере задач колнку Объекты GDI да посмотри сколько их по числу когда вываливается прога(см скрин)
За тысячу дескрипторов имеют приложения уровня эксплорер, броузеры, но не такие как у тебя рисовалки. Облом происходит где то при паре тысяч дескрпторов.
2 - е научись сначала рисвоать простенькое что нибудь. Вот тебе пара линков
Прорисовка в окне по нажатию кнопки(обработчик кнопки) MFC
Мне кажется так последовательней будет, нежели пытаться написать то с чем ты не знаком. (Цитирую тебя же
Цитата Сообщение от Ukuelig Посмотреть сообщение
Это темный лес для меня, там новичку можно разобраться без пол литра?
)
Друг, какой двойной буффер?Ты лучше поучись для начала рисовать графические примитивы GDI, потом поюзать CompatibleDC, а потом уже пытайся мастерить серьёзную графику
3-е утечка GDI - утечка памяти страшна ещё и тем что её нельзя "пощупать" как число элементов в массиве - течь может даже правильный код, но с кривой DLL или при системном затыке, потому - удостоверся, что на твоём ПК не вылетают другие программы с серьёзной GDI графикой (погугли на эту тему - поймёшь о чём тебе сказал)
0
0 / 0 / 0
Регистрация: 24.01.2013
Сообщений: 8
27.01.2013, 20:39  [ТС]
А кастомные объекты, перо и заливка необходимо каждый раз создавать заново перед рисованием объекта (выгружая в конце), либо их можно создать один раз и хранить, как член класса?

Добавлено через 51 минуту
Перечитал и понял, что количество GDi объектов (перья, кисти и др) ограниченно одновременно находящихся в памяти. Верно это?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.01.2013, 20:39
Помогаю со студенческими работами здесь

Проблемы с отрисовкой изображения с камеры и закрытием программы
Добрый день! Я изучаю библиотеку OpenCV и основы работы с web-камерой по этому курсу: ...

Проблемы с дочерним окном в MFC
Проблема такого рода... на новом окне не работает ни один элемент управления - что делать? Что я пропустил при создании окна? Код вызова...

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

Проблема с отрисовкой
Здравствуйте форумчане, мне нужна помощь. я знаю как что-то выводить, но я не знаю как сделать, что бы сразу происходило закрашивание. К...

Ошибки с отрисовкой графики
Добрый вечер уважаемые форумчане. С недавних пор появилась необходимость разбираться в графике. Использую VS17 по причине того, что он...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru