Solved

[QUESTION] TForm(fStayOnTop) and TPicture weird behavior

Posted on 2003-12-05
6
373 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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

856 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