ReleaseDC(GetDesktopWindow(), dcScreen);
SelectObject(dcMemory, oldBitmap);
DeleteDC(dcMemory);
DeleteObject(dbBitmap);
if (bFace) {delete bFace;}
gdiplus анимация и память...
В конце анимации, как и раньше, использую
Код:
Кто что посоветует?
Было бы не плохо увидеть чуть больше кода. Пока-что все что могу сказать - удостоверьтесь в том, что вы нигде не ссылаетесь(грубо говоря, не увеличиваете внутренний счетчик посыланий на объект, он может увеличиваться неявно при создании, например) на удаляемые объекты в других местах, до удаления.
Цитата: AlphaOmega
Делаю в 6-ом билдере анимацию, состоящую из серии png картинок методом функций библиотеки gdiplus. Делаю её таким же образом как и свои предыдущие проекты, однако в этот раз заниемая память не освобождается! То есть картинки подгружаются и заполняют память до тех пор, пока винда не выкинет прогу со словами "недостаточно памяти".
В конце анимации, как и раньше, использую
да вот только этого недостаточно.
Кто что посоветует?
В конце анимации, как и раньше, использую
Код:
ReleaseDC(GetDesktopWindow(), dcScreen);
SelectObject(dcMemory, oldBitmap);
DeleteDC(dcMemory);
DeleteObject(dbBitmap);
if (bFace) {delete bFace;}
SelectObject(dcMemory, oldBitmap);
DeleteDC(dcMemory);
DeleteObject(dbBitmap);
if (bFace) {delete bFace;}
Кто что посоветует?
что бы посоветовать чтото конкретное кода действительно не достаточно. Как происходит выделение памяти?
Код:
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;}
}
{
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 часа проработает прога - больше сотки метров не сожрёт, а то и много меньше......
Может есть что-нибудь общее для всех программ, что может уже использованную память очистить?...
Цитата: AlphaOmega
ещё, кстати инфо: этот код задействуется по несколько раз в секунду (всё-таки анимация, с изменением iFrame на единицу)
Может есть что-нибудь общее для всех программ, что может уже использованную память очистить?...
Может есть что-нибудь общее для всех программ, что может уже использованную память очистить?...
Сейчас лень копаться - посмотри в Рихтере. Скорее всего у тебя происходит не утечка памяти а ее резервирование для процесса. Посмотри в сторону Heap*- функций или перестрой алгоритм так что бы память была выделена один раз - ИМХО самое верное. Спать хочу - долго рассказывать неохота.
Кстати ИМХО для задач анимации достаточно два буфера памяти(в крайнем случае 4) - зачем выделять ее постоянно?
kot_, а кокретнее можешь с примерами?
Цитата: AlphaOmega
kot_, а кокретнее можешь с примерами?
с примерами не могу - просто некогда.
но вот фрагмент кода, который предположительно дает у тебя утечку памяти:
Код:
Bitmap* bPicture = new Bitmap(bFace);
извини, времени действительно нет анализировать весь код - но я не нашел места - да и в принципе его быть вроде нигде не может - где эта память освобождается. Создай в классе закрытую переменную типа указатель на Bitmap и работай с ней. Зачем каждый раз создавать новый объект? По меньшей мере, по приведенному коду, никакой необходимости в этом нет.