Solved

How to force immediate repaint of child forms?

Posted on 1997-09-14
8
745 Views
Last Modified: 2010-05-18
My application draws mathematical patterns in child forms filling one quarter of the screen. The parameters for the patterns come from DialogForm (see code below). When DialogForm closes, the child windows already created need repainting. This is done by blitting a copy of the finished pattern to the child window in the FormPaint method of TChildForm.However,this takes place only after the pattern has been drawn in the new child, and as the drawing takes many seconds, the screen doesn't look good with partially blank child windows.
Why does not this code work? I would think that the repaint messages to the child windows would be processed when ProsessMessages is encountered, but evidently the last two lines are processed before the repainting takes place.(Update or Refresh instead of Repaint has no effect).


procedure TMainForm.MenuClick(Sender: TObject);
...
   DialogForm.ShowModal;
    if MDIChildCount >0 then
       for i:= 0 to MDIChildCount-1  do
          MDIChildren[i].Repaint;
    Application.ProcessMessages;
    Child:=TChildForm.Create(Self);
    Child.DrawPattern;
   {only now the repainting is done!}
end;

How can I achieve what I want?
0
Comment
Question by:toreot
  • 4
  • 3
8 Comments
 

Accepted Solution

by:
98113772 earned 150 total points
ID: 1344771
Well, I have something that looks a bit like it, and I do it this way:


My application draws mathematical patterns in child forms filling one quarter of the screen. The parameters for the patterns come from DialogForm (see code below). When DialogForm closes, the child windows already created need repainting. This is done by blitting a copy of the finished pattern to the child window in the FormPaint method of TChildForm.However,this takes place only after the pattern has been drawn in the new child, and as the drawing takes many seconds, the screen doesn't look good with partially blank child windows.
Why does not this code work? I would think that the repaint messages to the child windows would be processed when ProsessMessages is encountered, but evidently the last two lines are processed before the repainting takes place.(Update or Refresh instead of Repaint has no effect).


...
if MDIChildCount >0 then
for i:= 0 to MDIChildCount-1 do Begin
  MDIChildren[i].Repaint;
  MDIChildren[i].Update;
  Application.ProcessMessages;
End;
....
0
 

Author Comment

by:toreot
ID: 1344772
Sorry, the addition of Update did not make any difference. The child windows already on the screen still are not painted until the loop in my procedure DrawPattern in the newly created child form has finished, leaving gaping white holes in the earlier windows for many seconds. There must be a way of repainting them before the loop starts, or...?
0
 

Expert Comment

by:98113772
ID: 1344773
Funny!
Well the place I use it in is very fast, so I guess this is why I don't have holes.

Have you tried to give the windows focus? Something (untested) like this:

...
if MDIChildCount >0 then
  for i:= 0 to MDIChildCount-1 do Begin
    MDIChildren[i].SetFocus;
    MDIChildren[i].Repaint;
    MDIChildren[i].Update;
    Application.ProcessMessages;
  End;
....

I can't try it from this machine, but maybe it will work


0
 

Author Comment

by:toreot
ID: 1344774
Still no luck! I have also tried moving the repainting code to the onclose and ondestroy event handler of DialogForm, with no result.
I had a similar problem when DrawPattern procedure call was associated with the OKButton handler on DialogForm, after the DialogForm.Close command. Then DialogForm wouldn't close until after the pattern had been drawn. Moving the code after DialogForm.ShowModal solved that. However, I have no place to move the DrawPattern code now! Associating it with a menu or a button would be too inelegant, I want it drawn immediately after DialogForm closes with no further user intervention. Could you perhaps introduce some delaying loop in your own code to see if your windows are repainted before or after the drawing of a new window? (Have tried both D1 and D2).
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 12

Expert Comment

by:andrewjb
ID: 1344775
How about trying refresh instead of repaint?

0
 

Expert Comment

by:98113772
ID: 1344776
Well, it seems to be exactely the same problem as you have. If I make a delay, it will repaint the new window before the old ones are painted.

After I have tested that, I got a new idea. Try this one:

if MDIChildCount >0 then
  for i:= 0 to MDIChildCount-1 do Begin
    MDIChildren[i].SetFocus;
    Application.ProcessMessages;
    MDIChildren[i].Invalidate;
    MDIChildren[i].Update;
    Application.ProcessMessages;
  End;

I did not test it myself (short of time right now)

0
 

Author Comment

by:toreot
ID: 1344777
As mentioned in my original question, neither refresh, repaint or update works. To me it looks like you can't force Delphi to update a window until an event handler has finished, even with a ProcessMessages inside the handler. Is this correct? If it is, can anybody think of a way to solve my problem?
0
 

Author Comment

by:toreot
ID: 1344778
Since my last comment, I have in fact solved the problem myself. The following code does what I want:

    Child:=TChildForm.Create(Self);
    if MDIChildCount >1 then
      for i:= 1 to MDIChildCount-1  do    
      begin
        MDIChildren[i].SetFocus;
        MDIChildren[i].Update;
        Application.ProcessMessages;
      end;
    Child.DrawPattern;
    Child.SetFocus;    {must be here, not before DrawPattern !}

In the process I discovered that the last created child has index 0 (Delphi doc. says otherwise).
Thanks for suggesting that SetFocus might be important.
toreot@hellerud.vgs.no
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

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…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

757 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

24 Experts available now in Live!

Get 1:1 Help Now