Toon posts:

[Delphi] invalid parameter fout

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een naar een nogal hardnekkig probleem. Namelijk dit:

ik heb een soort slideshow met JPeg's.

daarvoor heb ik in een timer wat code opgenomen:

code:
1
imgMain.Canvas.Draw(0, 0, grImg[iImgNum]);


maar op deze regel wil het programma nog wel eens een fout geven. Namelijk de "invalid parameter" fout. Deze code staat in een OCX maar als ik wat uitgebreider debug blijkt dat het programma out of resources is. Ik heb met allerlei programma's gecontroleerd maar het lijkt erop dat er echt geen geheugenlek in het programma zit.

Deze error komt alleen in windows 98 voor, na zo'n anderhalf a 2 uur.... altijd wachten dus :Z

Een vriend van me zei toen dat dit best een error kon zijn die aangaf dat windows 98 door zijn handles heen is.

Ik heb ook al geprobeerd de regel code om te schrijven naar variaties als:
code:
1
imgMain.Picture.graphic.assign(grImg[iImgNum]);

maar de error blijft hetzelfde. :'(

Heeft iemand hier een oplossing/workaround voor?

Verwijderd

Volgens mij laat je telkens een nieuw plaatje zonder het andere plaatje weg te halen (destroyen / free'en). Het geheugen loopt dan op den duur vol.

Verwijderd

Topicstarter
volgens mij niet. Of anders moet je me even zeggen wat ik verkeerd doe, want zover ik weet is tekenen op een canvas niet geheugenvragend, omdat de canvas zelf een blok geheugen is waar je gewoon wat functies op los laat.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ik denk dat je even wat meer code moet laten zien....
Hoe/wanneer wordt de imgMain gecreeerd? En hoe vul je grImg?

En waarom gebruik je niet meteen de Paint van het form ipv een TImage?

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if bShowMain then
begin
  try
    iImgNum := (iImgNum + 1) mod high(grImg); //naar volgende img in de slideshow
    imgMain.tag := iImgNum; //zorg dat ik weet welke image in de slideshow staat

    imgMain.Canvas.Draw(0, 0, grImg[iImgNum]); //teken de jpeg (HIER FAALT IE!)

    imgMain.BringToFront; //anders staat het achter de alle andere components
    imgMain.Visible := true; //en natuurlijk zichtbaar maken.
  except
    showmessage('error in slidetimer');  //hier komt ie niet langs bij de parameter error
  end  
end else begin
  imgMain.visible := false; //onzichtbaar maken
end;
bShowMain := not bShowMain;


grImg is dus een array van TGraphic. Maar ook als ik er een array van TImage of iets dergelijks van maak blijft het probleem.

grImg wordt geladen uit streams van bestanden. Maar deze functionaliteit werkt prima aangezien deze functie slechts 1 keer (en goed) wordt uitgevoerd ligt hier het probleem hoogstwaarschijnlijk niet.

De reden dat ik hem niet op de form zelf laat tekenen is dat ik anders een volledige redraw moet maken, als ik het Image weer weghaal. Dan is het invisible maken van een TImage een stuk makkelijker.

Ik hoop dat ik zo wat meer achtergrond heb gegeven.

edit:
ff wat tekst duidelijker gemaakt

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

ik heb nog wat meer nodig.

Hoe/waar maak je imMain aan? of gooi je die gewoon op je form?
Hoe/waar vul je grImg en waar/hoe free je m weer?

code graag :)

PS: Delphi 7 is zojuist geannounced! :9~ http://www.borland.com/delphi/

[ Voor 0% gewijzigd door LordLarry op 06-08-2002 15:44 . Reden: typo ]

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
Hoe/waar maak je imMain aan? of gooi je die gewoon op je form?
Deze staat inderdaad op het form.
Hoe/waar vul je grImg en waar/hoe free je m weer?
Die haal ik uit een eigen bestandsformaat.

enigszins vereenvoudigt en verduidelijkt:

dit komt uit de laadfunctie die ik gebouwd heb.
code:
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
    //open de filestream
    strmFile := TFileStream.create(filename, fmOpenRead);

    //lees de grootte van de thumb
    strmFile.Read(iThumbSize, 4);

    jpgThumb := TJPegImage.create(); //creeer de TJpegImage's
    jpgMain := TJpegImage.create();

    //maak een aparte memorystream; bij het laden van de jpeg leest
    //een TJPegImage anders de hele stream weg. Beetje wazig, maar dit
    //is dus mijn workaround.
    strmTemp := TMemoryStream.create();
    strmTemp.CopyFrom(strmFile, iThumbSize);
    strmTemp.Position := 0;

    //load from stream; jpgThumb laad de bytes het nu in zijn TJpegData
    jpgThumb.LoadFromStream(strmTemp);

    //nieuwe stream voor de grote plaat.
    strmTemp.free;
    strmTemp := TMemoryStream.create();
    strmTemp.CopyFrom(strmFile, strmFile.Size - strmFile.Position);
    strmTemp.Position := 0;

    if strmTemp.Size > 0 then
      //laad de mainimage uit het bestand
      jpgMain.LoadFromStream(strmTemp)
    else
      grImd[ImgCount] := nil;

    grImg[imgCount] := jpgMain;
    grThmb[imgCount] := jpgThumb;  //toewijzen

    jpgMain.Free;  //kennelijk kan dit, want het gaat ruim anderhalf uur goed :?
    jpgThumb.free;
    strmTemp.free;
    strmFile.Free;


Dus dit is mijn code... Moet je nog meer hebben??? :)

de grImg array wordt dus eerst op goeie grootte gebracht en daarna worden alle files geladen en alle mainimgs in de array geplant. De grImg array wordt geleegd als de form gedestroyed wordt. De array wordt aangemaakt in een functie.
PS: Delphi 7 is zojuist geannounced! :9~ http://www.borland.com/delphi/
ah gaaf :) gelijk ff kijken

edit:
foutje in het vereenvoudigen van de code

Verwijderd

Wat denk je dat hier:

code:
1
2
3
4
5
grImg[imgCount] := jpgMain;
grThmb[imgCount] := jpgThumb;  //toewijzen

jpgMain.Free;  //kennelijk kan dit, want het gaat ruim anderhalf uur goed :?
jpgThumb.free;

gebeurt?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

code:
1
2
3
4
5
6
7
8
    if strmTemp.Size > 0 then
      //laad de mainimage uit het bestand
      jpgMain.LoadFromStream(strmTemp)
    else
      grImd[ImgCount] := nil;

    grImg[imgCount] := jpgMain;
    grThmb[imgCount] := jpgThumb;  //toewijzen

Ik neem aan dat dit door het vereenvoudigen komt, maar die nil toekennen wordt later weer ongedaan gemaakt.


code:
1
2
    jpgMain.Free;  //kennelijk kan dit, want het gaat ruim anderhalf uur goed :?
    jpgThumb.free;


Tja, dit kan niet. Het kan lang aan, want het geheugen wordt niet direct overschreven en de handles niet direct hergebruikt, maar je moet pas als je programma sluit die images freeen.

Je zet alleen de pointer in de array, je maakt geen copy. Dus je kan m nog niet freeen. Bij jouw wijst de pointer naar iets wat er eigenlijk al lang al niet meer is.

Verder hoop ik dat je je laad functie maar 1x aanroept :)

[ Voor 0% gewijzigd door LordLarry op 06-08-2002 16:33 . Reden: kleine uitleg toegevoegd ]

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
Ik neem aan dat dit door het vereenvoudigen komt, maar die nil toekennen wordt later weer ongedaan gemaakt.
oops, klopt. moest
code:
1
jpgMain := nil;

zijn.
Tja, dit kan niet. Het kan lang aan, want het geheugen wordt niet direct overschreven en de handles niet direct hergebruikt, maar je moet pas als je programma sluit die images freeen.
Ik laat hem nu voor de zekerheid lopen. Maar ik weet vrijwel zeker dat dit het probleem niet is. Ik heb deze code namelijk al een keer gewijzigd. En toen was dit niet van toepassing.
Verder hoop ik dat je je laad functie maar 1x aanroept :)
doe ik :)

Verwijderd

Topicstarter
Ik moet eerlijk zeggen dat die code voor het laden van de JPeg er extreem brak uitzag, maar het blijkt toch echt niet de reden te zijn voor mijn falende app. :(

Als iemand nog suggesties heeft. Ik sta er voor open. Na precies 1 uur en 43 minuten kwam de error als vanouds weer naar boven. :'(

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

oops, klopt. moest
code:
1
jpgMain := nil;

zijn.
Dat is ook een memory leak. Dat moet
FreeAndNil(jpgMain);
zijn. Of je moet je if then else even beter positioneren

We adore chaos because we like to restore order - M.C. Escher


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Moet iets zijn met handles ofzo dan. Maar ik kan me niet voorstellen hoe dan. Ik zou alles omgooien en bijvoorbeeld een array van TImages namen ipv een array van TGraphics en dan elke keer dus het andere TImage laten zien ipv over te pompen naar 1. Of de paint functie gebruiken van het form en direct op het canvas tekenen.

We adore chaos because we like to restore order - M.C. Escher


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

probeer m anders eens door
http://www.automatedqa.com/products/memproof.asp
te halen en kijk of die wat vind

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1