Solved

[QUESTION] TForm(fStayOnTop) and TPicture weird behavior

Posted on 2003-12-05
6
369 Views
Last Modified: 2010-04-05
Hi everyone,

i have a strange problem (i've a workaround but...) involving in appearance order : Delphi7 Enterprise, a TForm and a Timage component.

i set my FormStyle as fsStayOnTop. i put a TImage component on my form and add the JPEG unit in the uses clause.

When i load an image for the first time (with the form shown on screen), everything goes fine, my jpeg picture is loaded and displayed with no error.

Then, when i load another picture, i got a violent 'Access Violation' with the TPicture.loadfromfile at this place :

procedure TPicture.LoadFromFile(const Filename: string);
var
  Ext: string;
  NewGraphic: TGraphic;
  GraphicClass: TGraphicClass;
begin
  Ext := ExtractFileExt(Filename);
  Delete(Ext, 1, 1);
  GraphicClass := FileFormats.FindExt(Ext);
  if GraphicClass = nil then
    raise EInvalidGraphic.CreateFmt(SUnknownExtension, [Ext]);

  NewGraphic := GraphicClass.Create;
  try
    NewGraphic.OnProgress := Progress;
    NewGraphic.LoadFromFile(Filename);     <=== AccessViolation Here !
  except
    NewGraphic.Free;
    raise;
  end;
  FGraphic.Free;
  FGraphic := NewGraphic;
  FGraphic.OnChange := Changed;
  Changed(Self);
end;

after several hours of debugging, a lot of cup of coffee, i've found a workaround setting the form as normal and using the SetForegroundWindow function...

But it's not very satisfying...

So if anyone has an explanation... just listening...

thanks in advance,

best regards,

Guillaume

ps: setting 125 points for it, as it's not, for the moment very important, but i think it might not be very easy to find the solution...
0
Comment
Question by:fsurfer
  • 3
  • 3
6 Comments
 

Author Comment

by:fsurfer
ID: 9881386
After some more debugging sessions, it appears that my workaround 'SetForegroundWindow' API call is producing the same error.

it seems that when a TImage Component is on a form which is either with the fsStayOnTop's FormStyle or in the foreground using SetforegroundWindow, you can't load another picture once one is loaded...

am i doing something wrong or has anyone reproduced this ?

thanks in advance,

best regards,

Guillaume
0
 
LVL 22

Accepted Solution

by:
Ferruccio Accalai earned 125 total points
ID: 9881698
in my d7 test (on W2K sp4) nothing's wrong....wich is your os? and how are you loading the new image....
post a little more code....
0
 

Author Comment

by:fsurfer
ID: 9881746
hi Ferrucio,

thanks for your answer.

Effectively, nothing was wrong.

in fact, it's my mistake. Here's why :
In the FormClose event, i was setting Action to caFree. BUT, the Form variable was not freed except that the Canvas was freed. So, when reusing the form to display another image, i had an error when it was trying to load it.

here're parts of my code :

FormClose event :
procedure TfrmGrandEcran.FormClose(Sender: TObject;  var Action: TCloseAction);
begin
       ... MyStuff ...
      Action:=caFree;
end;

Elsewhere in my code when reusing the form :

... my stuff ...
if Assigned(frmGrandEcran) then
    frmGrandEcran.Image1.LoadFromFile('myimage.jpg'); <= here the access violation triggered.

And in fact, everything is normal (everything on the form is freed and destroyed) except the form itself !

but i'll give you the points any way... some may know why...

Thanks again for your interest !

best regards,

Guillaume
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 9881942
Many thanks to you...i really got a present with this :)
SO now let's see why it appens:

From delphi help:
When you call Free for a component, it calls Free for all components that it owns—that is, all components in its component list. Since a form owns all the controls and nonvisual components that are created on it in design mode, those components are automatically freed when the form is freed. By default, all forms are owned by the Application object....

Because you have stored a variable pointed to the form in the app. then the allocated memory for that variable will be realased just on freeing the Application (closing it), so freeing a form, it never will become nil.
So how to workaround it?
Well, let's create the form and then, after using it, let's release its memory...

if form2 = nil then
form2 := Tform2.create(form2);
form2.Showmodal;
freeandnil(form2);

Just to justify your points assignment :)

F68 ;-)  
0
 

Author Comment

by:fsurfer
ID: 9882027
Hi,

In order to go a bit farer than your sample and getting close to what i've done, in your TForm2 OnClose event, put the following code :

Begin
... your stuff ...
Action:=caFree;
End;

In my opinion, you should get an error message on your 'FreeAndNil(form2)'.

(sorry, don't have time to test it, but that's waht i have done, and there was my mistake)

Guillaume
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 9882516
yes of course, in that case you'd try to re-free a destroyed form so an exception should be raised....
cafree just destroy all child components and itself, but doesn't realase  the allocated memory...
so the correct way is to let close the form without any CloseAction options and free-release it from application....
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now