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

x
?
Solved

Force Form To Show

Posted on 2001-08-07
33
Medium Priority
?
287 Views
Last Modified: 2010-04-06
I have an app that checks for command-line options in the OnActivate event and based on the option specified a procedure might be called.  The problem is that if a procedure is called from the OnActiviate the form doesn't show until after the procedure has finished.  It did use to show first but not any more.  How can I force the form to show?
0
Comment
Question by:dokken
[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
  • 10
  • 8
  • 6
  • +5
33 Comments
 
LVL 4

Expert Comment

by:YodaMage
ID: 6360123
Why don't you move your call to the OnShow then? Or check your options in the on activate, then based on result, use a boolean to call the procedure from the OnShow?
0
 
LVL 4

Expert Comment

by:fva
ID: 6360134
It's possible to show it but even if you can make it to show first it won't respond to user actions until the proc finishes. I would suggest other approaches:

1. Show a splash screen instead the main one until the processing finishes. This would be better suited if the processing is mandatory for the main program to run properly.

2. Start a thread and run the proc inside it. This would be better if the completion of the proc is not required in order to start using the application.

F.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6360280
use

application.processmessages;

in your activate event
(not tested)

meikl ;-)
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 3

Expert Comment

by:nnbbb09
ID: 6360300
Hello,

I think the reason your form won't show is because you've started some lengthy process before all the windows paint messages have been processed properly. This is a PAQ that I answered a while ago that deals with the same sort of problem. http://www.experts-exchange.com/jsp/qShow.jsp?ta=delphi&qid=20118669
What happens is that the main form posts a message to itself which you need to write a handler for. The message goes to the end of the queue, the form paints itself correctly. Your custom message is then handled and you can start your processing.

Hope this helps

Jo

0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6360312
now tested

procedure TForm1.FormActivate(Sender: TObject);
var i : Integer;
begin
  Application.Processmessages;
  i := gettickcount;
  while gettickcount - i < 5000 do; //nothing for five seconds as sample for doing somewaht
  showmessage('On End');
end;

meikl ;-)
0
 
LVL 2

Accepted Solution

by:
FrodoBeggins earned 1000 total points
ID: 6360512
NEVER use Application.Processmessages in an event handler! It may cause big and hard-to-find problems.

The form will not show because it can't handle PAINT and other messages until you are in the OnActivate event handler. This is the reason. Application.Processmessages is a walkarround, bur very bad. It may work, but once an 100 starts to crush your app.

The solution I see is: if you need to do something send a custom message to your own message queue. In your main form's unit write:

unit Main;
const
  WM_MYMESSAGE1 = WM_USER + 100;
  WM_MYMESSAGE2 = WM_USER + 101;
...
type TMainForm = class(TForm)
.....
privte
  procedure WMDoSomething1(var Message: TMessage); message WM_MYMESSAGE1;
  procedure WMDoSomething2(var Message: TMessage); message WM_MYMESSAGE2;
....
procedure TMainForm.WMDoSomething1(var Message: TMessage);
begin
  //DoSomething1;
end;

procedure TMainForm.WMDoSomething2(var Message: TMessage);
begin
  //DoSomething2;
end;

procedure TMainForm.FormActivate(Sender: TObject);
begin
  ...
  // need to call procedure 1
  SendMessage(MainForm.Handle, WM_MYMESSAGE1, 0, 0);
end;

I hope you get the idea ;-)

Rgds,
Frodo


0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6360569
NEVER had a problem with
application.processmessages
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6360602
to: FrodoBeggins
just to say, if the application does not process the messages,
your custom-messages will only then processed when the application becomes idle

in short to all,

the form is not shown, because the applcation got not the time
to process the message for show and paint the form,

with application.processmessages you force the application to process all waiting messages,
also the show and paint-messages for display the form

regards

meikl ;-)
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6360609
Hehe. I had. Many problems.
This is common rule. ProcessMessages may cause reentrancy problems.

Rfds,
Frodo
0
 
LVL 4

Expert Comment

by:YodaMage
ID: 6360641
The only problems I've seem with processmessages, is that it sometimes slows down a HUGE looping procedure, especially if many data aware components and controls are not disabled first.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6360684
In very specific situations Application.ProcessMessages may really make problems due to strange reentrance situations, but I would not go that far to say, that you should never use it in an event handler, that's by far too strict IMHO. You should simply not use it in situations where it is dangerous. Here is a little example for such a situation:

type
  TForm1 = class...
  private
    globalList : TList;
    procedure ReceivedDeviceChangedMessage(...); message WM_DEVICECHANGE;
    ...
  end;

procedure TForm.ReceivedDeviceChangedMessage(...);
begin
  for i1 := 0 to globalList.Count - 1 do begin
    DoSomethingComplicated(globalList[i1]);
    Application.ProcessMessages;
  end;
  globalList.Delete(0);
end;

In this situation is might happen, that the Application.ProcessMessages call handles just another WM_DEVICECHANGE message. In that case the first WM_DEVICECHANGE handler will throw out an exception, because the list got shorter during Application.ProcessMessages.

I didn't first believe it, but even SendMessage can have the same problems, because if our thread calls SendMessage, then while waiting for the result of the message our thread is not totally blocked, it still reacts to messages that are sent from other threads via SendMessage. So SendMessage can have the same problems as in the example above. As a result I sometimes call SendMessageTimeout with the SMTO_BLOCK flag to avoid this reentrance problem...   :-(

Regards, Madshi.
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6360685
Well, get the foloqing scenario.
You enter OnActivate, do something, process the messages... and somewhere in the messages the form gets activated again. Nowa you get in OnActivate again, BEFORE you've finished the first activate processing. Can you imagine HOW MANY problems can occure? :))

here's an example:

var BlahBlah:TStingList;

procedure Form1.FormActivate(Sender : TObject);
begin
  BlahBlah := TStringList.Create;
  // do something...
  Application.ProcessMessages;
  // do something...
  BlahBlah.Free;
end.

Now, the form gets activated, creates the stringlist, proccesses another activation, creates the stringlist... Oops! Ith is already created :)

This, of cource, is just a basic example. Do you needa a more complex one?

Rgds,
Frodo
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6360701
Well, Madshi, let's say "Use ProcessMessages in an event handler only if you are sure what are you doing" :-)

You are right about SendMessage too. My mistake. Should use PeekMessage in the example.

Rgds,
Frodo
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6360714
kretzschmar: Right, my own messages will be processed after all previous messages, like PAINT. The form will get shown, and then will execute the code in DoSomething1.

Rgds,
Frodo
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6360723
its simple to avoid such situations,

by using a flag or just deassigning
the procedure from the event for this code step,

and if you had many problems,
then your coding concept wasn't good enough

;-)
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6360798
Yes, there is a walkarround. I couldn't see your flags-warning when you told us to use ProcessMessages ;-))

Anyway, the flag stuff has a bad side too. You suggest to skip some of the processing in the procedure. But that may have a side effects too. I usualy write event-handlers with the thought they'll be executed afterwards, the events will get handled. I'm not sure if it is good coding concept or not, but... :-))

Rgds,
Frodo
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6360886
at least it depends, what you are doing,
but i guess the use of application.processmessages is the easiest method for dokken
(depending what he is doing)

meikl ;-)
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6360925
OK. I definitely agree with you. Your method is easier to implement, mine - more robust. Of course I say mine is better, and you don't agree. That's called deadlock, right ;-))

I can't get further without more secific knowing of what exactly should be done.

Rgds,
Frodo
0
 
LVL 3

Expert Comment

by:nnbbb09
ID: 6360995

Frodo, I agree that my/your solution is more robust than using application.processmessages. Incidentally I think the message should be posted from the FormShow event.

Jo
0
 

Author Comment

by:dokken
ID: 6361025
Wow, a lot posts.  I added Application.ProcessMessages to the first line of the OnActivate event but the form still didn't show.

If I move the code to the OnShow should that show the form first or will I end up with the same thing?

This used to work, I don't know what changed it.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6361039
:-)) waiting for dokkens response

i know this trick, which u use, frodo,
even the release-method of tform does the same
to ensure that the method where its called is left,
but i don't think that this must be done on every event-procedure,
even i think the need for this happens not often.

meikl ;-)
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6361171
Dokken, you need to put Application.ProcessMessages in your lenghty operation's loop. It does not help you at the first line of OnActivate :)

meikl, it is done in the release method not because something should be done after the current procedure finishes (as in our case). Well, not only. It is used there to call CMRelease, which calls free, which frees the form. If release directly calls free, then when it comes to execute the next line of release's procedure, or anything which comes after release, the form will be gone but you'll work with it. And poof! - Access violation :)

Rgds,
Frodo
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6361177
Working with already-freed object is not good coding concept, in my oppinion ;-))

Rgds,
Frodo
0
 

Author Comment

by:dokken
ID: 6361204
FrodoBeggins, I do have Application.ProcessMessages in the code being run from the OnActivate event.  It's in there numerous times.
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6361255
Well, I'm so happy for you. I have a mountain house. So?

Seriously, If you select the processmessages method, you may crush, once for 1000 times, or 10E14,  or never... I'm glad it works for you. But I will not use it. A question of vision, I guess... :)

Rgds,
Frodo
0
 

Author Comment

by:dokken
ID: 6361370
I was replying to your line "you need to put Application.ProcessMessages in your lenghty operation's loop. It does not help you at the first line of OnActivate".  I wasn't commenting on whether or not it was a good idea to place that within an event.

0
 
LVL 20

Expert Comment

by:Madshi
ID: 6361667
Okay, here comes what I'm usually doing if I want the form to be shown first and then do something: I put it in FormPaint (because FormShow is too early, too) like this:

procedure TForm1.FormPaint(...);
begin
  OnPaint := nil;  // to make sure we're only doing this one time
  CallYourLengthyProc;
end;

Regards, Madshi.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6362666
yup, thats it, madshi :-)
0
 
LVL 3

Expert Comment

by:rondi
ID: 6363308
i use that all the time, too :>)
0
 
LVL 3

Expert Comment

by:rondi
ID: 6363466
i use that all the time, too :>)
0
 

Author Comment

by:dokken
ID: 6364702
Madshi,  Almost works... it's not painting the entire thing though until after it finishes what it's doing.
0
 

Author Comment

by:dokken
ID: 6364839
You guys are not going to believe this.  I moved the code back to OnActivate (where it originally was) and now it's showing the form first like I wanted it to.  No code was changed.  This is what I was I talking about in my question, sometimes it works and sometimes it doesn't.  Except now certain things that did work are producing Access Violations.  I'm going to try creating a message queue as suggested.
0
 

Author Comment

by:dokken
ID: 6365241
Works great.
0

Featured Post

Tech or Treat!

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

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

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
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