Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2018.04.22;
Скачать: [xml.tar.bz2];

Вниз

Метафайлы тормозят при ресайзе   Найти похожие ветки 

 
ProgRAMmer Dimonych ©   (2010-09-30 21:46) [0]

Пишу "графический редактор" с использованием HENHMETAFILE"ов. Для рисования создаю отдельный класс окна. Всё рисование производится одновременно в memory bitmap (hDC+hBitmap) и метафайл (hMFDC). Битмап используется для быстрой отрисовки окна, метафайл - для хранения собственно действий, приводящих к получению изображения.

Добавляю обработку WM_SIZE, выполняю следующие действия:

1. Пересоздаю битмап в памяти (разумеется, с отсоединением и последующим присоединением к hDC).
2. hMF:=CloseEnhMetaFile(hMFDC)
3. hMFDC:=CreateEnhMetaFile(...)
4. PlayEnhMetaFile() в hDC и hMFDC.
5. DeleteEnhMetaFile(hMF)
6. Перерисовка окна.

При многократных ресайзах наблюдаю постепенное замедление процесса: после 2-3 десятков ресайзов (независимо от того, увеличение или уменьшение) обработка WM_SIZE начинает занимать несколько секунд.

Все метафайлы создаются в памяти, без привязки к файлам на диске.

Сталкивался ли кто-нибудь с такой проблемой?


 
Дмитрий Тимохов 2   (2010-10-01 00:02) [1]

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


 
ProgRAMmer Dimonych ©   (2010-10-01 01:10) [2]

На сях он, правда :)

SelectObject(pbs->hdcMem,pbs->hbmMemO);
DeleteObject(pbs->hbmMem);
hdc = GetDC(hWnd);
pbs->hbmMem = CreateCompatibleBitmap(hdc,wr.right,wr.bottom);
SelectObject(pbs->hdcMem,pbs->hbmMem);
ReleaseDC(hWnd,hdc);

FillRect(pbs->hdcMem,&wr,pbs->hbrBack);
hMF = CloseEnhMetaFile(pbs->hMFDC);
pbs->hMFDC = PaintBox_CreateMetaFile(pbs,NULL,&wr);
PlayEnhMetaFile(pbs->hMFDC,hMF,&wr);
PlayEnhMetaFile(pbs->hdcMem,hMF,&wr);
DeleteEnhMetaFile(hMF);
InvalidateRect(hWnd,NULL,FALSE);
UpdateWindow(hWnd);


pbs - это указатель на структуру с хэндлами, коорднатами и прочей внутриклассовой ересью.
pbs->hbmMemO - то, что вернула SelectObject() при привязке битмапа к DC
wr - структура RECT, результат выполнения GetClientRect()
pbs->hMFDC - DC, полученный при вызове CreateEnhMetaFile()

HDC PaintBox_CreateMetaFile(PPaintBoxStruct pbs, TCHAR lpFileName[], const LPRECT rect)
{
 int iWidthMM, iHeightMM, iWidthPels, iHeightPels;
 RECT tr;

 if (rect == NULL)
   return CreateEnhMetaFile(pbs->hdcMem,lpFileName,NULL,NULL);

 iWidthMM    = GetDeviceCaps(pbs->hdcMem,HORZSIZE);
 iHeightMM   = GetDeviceCaps(pbs->hdcMem,VERTSIZE);
 iWidthPels  = GetDeviceCaps(pbs->hdcMem,HORZRES);
 iHeightPels = GetDeviceCaps(pbs->hdcMem,VERTRES);

 tr = *rect;
 tr.left   = (tr.left   * iWidthMM  * 100) / iWidthPels;
 tr.top    = (tr.top    * iHeightMM * 100) / iHeightPels;
 tr.right  = (tr.right  * iWidthMM  * 100) / iWidthPels;
 tr.bottom = (tr.bottom * iHeightMM * 100) / iHeightPels;
 return CreateEnhMetaFile(pbs->hdcMem,lpFileName,&tr,NULL);
}


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


 
han_malign   (2010-10-11 17:24) [3]

уверен что pbs->hbmMemO != NULL?
попробуй DeleteObject(SelectObject(pbs->hdcMem,pbs->hbmMem));


 
ProgRAMmer Dimonych ©   (2010-10-26 21:36) [4]

Выкроил наконец-то время.

pbs->hbmMemO != NULL, гарантированно. Отладчик не врёт, SelectObject() возвращает корректный хэндл, равный сохранённому ранее в pbs->hbmMem. Удаление происходит корректно.

С OllyDbg в зубах выяснил, что утечка происходит при отрисовке PlayEnhMetaFile(), причём, похоже, только тогда, когда отрисовка идёт в DC нового метафайла. При отрисовке в обычный DC утечек, похоже, нет.

Кроме того, сделав EnumEnhMetaFile() и поставив бряк в callback-функции, выяснил, что уже при первой отрисовке помимо мелочей вроде SetBkColor() в DC нового метафайла отрисовывается всякая экзотика вроде TextOut() и RoundRect(), хотя ничего подобного в исходном метафайле не было.

Из упоминаний утечек нарыл только про утечку в Win9x, но конкретно у меня сейчас проблема в WinXP, а по ней замечаний гугл не даёт. :(


 
ProgRAMmer Dimonych ©   (2010-10-28 01:04) [5]

Наткнулся на краткое упоминание про утечку в остальных системах. Но ответа на вопрос, как этого избежать, там, к сожалению, нет. А тормоза и правда ощутимые. :(



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2018.04.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.001 c
4-1285868805
ProgRAMmer Dimonych
2010-09-30 21:46
2018.04.22
Метафайлы тормозят при ресайзе


15-1470208803
Юрий Зотов
2016-08-03 10:20
2018.04.22
Разновидность шахмат


2-1459763922
Dmk
2016-04-04 12:58
2018.04.22
Вращение


15-1471959711
Игорь Шевченко
2016-08-23 16:41
2018.04.22
Раздается Delphi 10.1 starter edition


2-1461353048
BondFx
2016-04-22 22:24
2018.04.22
MD5





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский