Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

gdiplus анимация и память...

748
29 ноября 2007 года
AlphaOmega
159 / / 28.09.2004
Делаю в 6-ом билдере анимацию, состоящую из серии png картинок методом функций библиотеки gdiplus. Делаю её таким же образом как и свои предыдущие проекты, однако в этот раз заниемая память не освобождается! То есть картинки подгружаются и заполняют память до тех пор, пока винда не выкинет прогу со словами "недостаточно памяти".
В конце анимации, как и раньше, использую
 
Код:
ReleaseDC(GetDesktopWindow(), dcScreen);
SelectObject(dcMemory, oldBitmap);
DeleteDC(dcMemory);
DeleteObject(dbBitmap);
if (bFace) {delete bFace;}
да вот только этого недостаточно.

Кто что посоветует?
255
29 ноября 2007 года
Dart Bobr
1.4K / / 09.04.2004
Было бы не плохо увидеть чуть больше кода. Пока-что все что могу сказать - удостоверьтесь в том, что вы нигде не ссылаетесь(грубо говоря, не увеличиваете внутренний счетчик посыланий на объект, он может увеличиваться неявно при создании, например) на удаляемые объекты в других местах, до удаления.
1
29 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: AlphaOmega
Делаю в 6-ом билдере анимацию, состоящую из серии png картинок методом функций библиотеки gdiplus. Делаю её таким же образом как и свои предыдущие проекты, однако в этот раз заниемая память не освобождается! То есть картинки подгружаются и заполняют память до тех пор, пока винда не выкинет прогу со словами "недостаточно памяти".
В конце анимации, как и раньше, использую
 
Код:
ReleaseDC(GetDesktopWindow(), dcScreen);
SelectObject(dcMemory, oldBitmap);
DeleteDC(dcMemory);
DeleteObject(dbBitmap);
if (bFace) {delete bFace;}
да вот только этого недостаточно.

Кто что посоветует?


что бы посоветовать чтото конкретное кода действительно не достаточно. Как происходит выделение памяти?

748
29 ноября 2007 года
AlphaOmega
159 / / 28.09.2004
Код:
void SetupTransparentWindow(HWND hWindow)
{

ULONG_PTR GDIplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&GDIplusToken, &gdiplusStartupInput, NULL);

WCHAR* bFace;
if (bAnimation)
    {bFace = imgPATHa "images\\canvas.png" imgPATHz;}
else {bFace = imgPATHa "images\\wings.png" imgPATHz;}
Bitmap* bPicture = new Bitmap(bFace);
if (bPicture == NULL || bPicture->GetLastStatus() != Ok)
 {
 if (bPicture) {delete bPicture;}
 Beep(100,1000);
 Application->Terminate();
 return;
 }

RECT rRect;
GetWindowRect(hWindow, &rRect);

BLENDFUNCTION blendPixelFunction= {AC_SRC_OVER, 0, iAlpha, AC_SRC_ALPHA};
POINT ptWindowScreenPosition = {rRect.left, rRect.top};
POINT ptSrc = {0, 0};
SIZE szWindow = {bPicture->GetWidth(), bPicture->GetHeight()};

HDC dcScreen = GetDC(GetDesktopWindow());
HDC dcMemory = CreateCompatibleDC(dcScreen);

Gdiplus::Graphics gLayer(bPicture);

int iX = 0; int iY = 0; int iW = 0; int iH = 0;

 WCHAR* bHeart = imgPATHa "images\\heart.png" imgPATHz;
 Bitmap pHeart(bHeart);
 if (iFrame <= 100)  {iW = (195*iFrame)/100;} else {iW = 195;}
 iX = 150 + ((195 - iW)/2);
 iY = 76 + ((195 - iW)/2);
 iH = iW;
 gLayer.DrawImage(&pHeart, iX, iY, iW, iH);

 WCHAR* bBelt;
 if (iFrame == 101 || iFrame == 102) {bBelt = imgPATHa "images\\belt_0.png" imgPATHz;}
 if (iFrame == 103 || iFrame == 104) {bBelt = imgPATHa "images\\belt_1.png" imgPATHz;}
 if (iFrame == 105)                  {bBelt = imgPATHa "images\\belt_2.png" imgPATHz;}
 if (iFrame == 106)                  {bBelt = imgPATHa "images\\belt_3.png" imgPATHz;}
 if (iFrame >= 107)                  {bBelt = imgPATHa "images\\belt_4.png" imgPATHz;}
 Bitmap pBelt(bBelt);
 gLayer.DrawImage(&pBelt, 104, 1, 342, 237);

HBITMAP dbBitmap;
bPicture->GetHBITMAP(Color(0, 0, 0, 0), &dbBitmap);
HBITMAP oldBitmap = (HBITMAP)SelectObject(dcMemory, dbBitmap);
UpdateLayeredWindow(hWindow, dcScreen, &ptWindowScreenPosition, &szWindow, dcMemory, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA);
ReleaseDC(GetDesktopWindow(), dcScreen);
SelectObject(dcMemory, oldBitmap);
DeleteDC(dcMemory);
DeleteObject(dbBitmap);
if (bFace) {delete bFace;}
}
Вот - код.
Как происходит выделение памяти - не знаю, знаю лишь, что со скоростью мегабайт 5 в секунду в диспетчере задач видно что увеличивается у проги потребление - как доходит до 512 вылетает сообщение "винде не хватает виртуальной памяти - будем увеличивать" и начинаются жуууткие тормоза.....


В старых прогах (откуда приблизительно брал код) - обновление каждую секунду, но при этом хоть 24 часа проработает прога - больше сотки метров не сожрёт, а то и много меньше......
748
29 ноября 2007 года
AlphaOmega
159 / / 28.09.2004
ещё, кстати инфо: этот код задействуется по несколько раз в секунду (всё-таки анимация, с изменением iFrame на единицу)

Может есть что-нибудь общее для всех программ, что может уже использованную память очистить?...
1
29 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: AlphaOmega
ещё, кстати инфо: этот код задействуется по несколько раз в секунду (всё-таки анимация, с изменением iFrame на единицу)

Может есть что-нибудь общее для всех программ, что может уже использованную память очистить?...


Сейчас лень копаться - посмотри в Рихтере. Скорее всего у тебя происходит не утечка памяти а ее резервирование для процесса. Посмотри в сторону Heap*- функций или перестрой алгоритм так что бы память была выделена один раз - ИМХО самое верное. Спать хочу - долго рассказывать неохота.

1
29 ноября 2007 года
kot_
7.3K / / 20.01.2000
Кстати ИМХО для задач анимации достаточно два буфера памяти(в крайнем случае 4) - зачем выделять ее постоянно?
748
29 ноября 2007 года
AlphaOmega
159 / / 28.09.2004
kot_, а кокретнее можешь с примерами?
1
30 ноября 2007 года
kot_
7.3K / / 20.01.2000
Цитата: AlphaOmega
kot_, а кокретнее можешь с примерами?


с примерами не могу - просто некогда.
но вот фрагмент кода, который предположительно дает у тебя утечку памяти:

 
Код:
Bitmap* bPicture = new Bitmap(bFace);

извини, времени действительно нет анализировать весь код - но я не нашел места - да и в принципе его быть вроде нигде не может - где эта память освобождается. Создай в классе закрытую переменную типа указатель на Bitmap и работай с ней. Зачем каждый раз создавать новый объект? По меньшей мере, по приведенному коду, никакой необходимости в этом нет.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог