Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

[QUESTION] TForm(fStayOnTop) and TPicture weird behavior

Posted on 2003-12-05
6
Medium Priority
?
380 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 23

Accepted Solution

by:
Ferruccio Accalai earned 375 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 23

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 23

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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

618 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