PDA

Visualizza la versione completa : [DELPHI] Errore "EOutOfResources" rilasciando hDC


Scarpetta
04-09-2011, 22:16
Salve,
ho un problema con un applicazione scritta in delphi, dopo un po si blocca con l'errore "out of resource parametro non valido", o "out of resource memoria insufficente per eseguire il comando", il cursore lo mette sempre sulla stessa istruzione "ReleaseDC(GetDesktopWindow, tmpDC);" all'inizio usavo DeleteDC ma ho letto su msdn che quello va chiamato se lo crei il dc "CreateDC" invece se lo ottieni "GetDC" devi rilasciarlo appunto con ReleaseDC, anche se sono alle prime armi sono stato meticoloso e penso di aver liberato tutte le risorse nel miglior modo possibile,
posto un po di codice vi sarei molto grato se mi aiutate a risolvere sto problema




function FindBitmap(var x, y: Integer; SubBmp: TBitmap): Boolean;
var
cx, cy, scx, scy, i: Integer;
Bmp: TBitmap;
tmpDC: HDC;
Line, SubLine: PRGB32Array;
begin
Result := False;
Bmp := TBitmap.Create;
tmpDC := GetWindowDC(GetDesktopWindow);
Bmp.Width := screen.Width;
Bmp.Height := screen.Height;
BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, tmpDC, 0, 0, SRCCOPY);
Bmp.PixelFormat := pf32bit;
ReleaseDC(GetDesktopWindow, tmpDC);
SubBmp.PixelFormat := pf32bit;
for cy := 0 to Bmp.Height - 1 do
begin
if cy >= (Bmp.Height - Subbmp.Height - 5) then Break;
Line := Bmp.ScanLine[cy];
SubLine := SubBmp.ScanLine[0];
for cx := 0 to Bmp.Width - 1 do
begin
if cx >= (Bmp.Width - SubBmp.Width - 5) then Break;
if (RGB(Line[cx].R, Line[cx].G, Line[cx].B) = RGB(SubLine[0].R, SubLine[0].G, SubLine[0].B)) then
begin
i := 0;
for scy := 0 to SubBmp.Height -1 do
begin
if scy >= SubBmp.Height -1 then break;
Line := Bmp.ScanLine[cy + scy];
SubLine := SubBmp.ScanLine[scy];
for scx := 0 to SubBmp.Width -1 do
begin
if scx >= SubBmp.Width -1 then break;
if (RGB(Line[cx + scx].R, Line[cx + scx].G, Line[cx + scx].B) =
RGB(SubLine[scx].R, SubLine[scx].G, SubLine[scx].B)) then Inc(i);
end;
end;
if i = scx * scy then
begin
Result := True;
x := cx;
y := cy;
FreeAndNil(Bmp);
Line := nil;
SubLine := nil;
Exit;
end;
end;
end;
end;
FreeAndNil(Bmp);
Line := nil;
SubLine := nil;
end;

//////////////////////////////////////////////

la funzione findbitmap la chiamo passandogli delle bitmap che carico da un file .res

SBmp:= TBitmap.Create;
SBmp.LoadFromResourceName(HInstance, 'nome_della_bitmap');
if FindBitmap(x, y, SBmp) then
begin
........
end; // e poi libero
FreeAndNil(Sbmp);



il dubbio che ho io e' che forse l'handle del LoadFromResourceName non viene rilasciato insieme alla bitmap con FreeAndNil, un altra cosa di cui non sono sicuro e' il puntatore che usa ScanLine, forse semplicemente mettendolo a Nil non libera la memoria, ma ci scrive Nullo dentro e poi ad ogni chiamata successiva alloca un altro pezzetto di memoria fino ad esaurirla, ma queste sono solo ipotesi di un principiante, l'unica cosa certa e' che l'esaurito sono io, non so piu dove sbattere la testa, spero di trovare aiuto in questo forum.

Saluti.

alka
05-09-2011, 09:25
Non ho purtroppo il tempo di analizzare e testare il codice, anche se a prima vista ci sono alcune cose che mi balzano all'occhio e destano sospetto; ad esempio, all'interno di una istruzione if...then compare una chiamata a FreeAndNil, che poi appare anche fuori... siamo sicuri che il tuo codice non provveda a distruggere più volte l'handle che hai allocato o l'oggetto bitmap?

A mio avviso, dovresti innanzitutto strutturarlo meglio, magari usando diversi metodi che si occupino ognuno di un aspetto specifico della procedura, così da poter leggere il codice più comodamente e aumentare le probabilità di individuare cosa non va.

Ciao! :ciauz:

Scarpetta
05-09-2011, 18:13
ciao Alka,
grazie per la risposta, il FreeAndNil che vedi dentro l'istruzione if precede un Exit il perche e' ovvio, se trova il riscontro esce dalla funzione, se invece non lo trova quel pezzo di codice non lo calcola e allora le libera da sotto, cmq in una procedura dove chiamavo questa funzione con un certo quantitativo di Bitmap, non ne liberavo due al termine, mi erano proprio sfuggite! e quelle ad ogni kiamata occupavano memoria e cosi dopo un po il programma sbottava, (dopo un ora due al massimo).
aspetto un paio di giorni per vedere se realmente erano queste due bmp la causa dei miei dolori, se cosi fosse metto risolto nel prim post.

Saluti.

P.S.: per il fatto di strutturare meglio le cose che scrivo sono daccordissimo con te, grazie del consiglio, come gia accennato nel primo post sono alle prime armi, piano piano anche io diventero' grande^^

Loading