Solved

How to force immediate repaint of child forms?

Posted on 1997-09-14
8
946 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
[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
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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
 
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

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

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

759 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