toreot
asked on
How to force immediate repaint of child forms?
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.ProcessMessage s;
Child:=TChildForm.Create(S elf);
Child.DrawPattern;
{only now the repainting is done!}
end;
How can I achieve what I want?
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
...
DialogForm.ShowModal;
if MDIChildCount >0 then
for i:= 0 to MDIChildCount-1 do
MDIChildren[i].Repaint;
Application.ProcessMessage
Child:=TChildForm.Create(S
Child.DrawPattern;
{only now the repainting is done!}
end;
How can I achieve what I want?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.ProcessMessage s;
End;
....
I can't try it from this machine, but maybe it will work
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.ProcessMessage
End;
....
I can't try it from this machine, but maybe it will work
ASKER
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).
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).
How about trying refresh instead of repaint?
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.ProcessMessage s;
MDIChildren[i].Invalidate;
MDIChildren[i].Update;
Application.ProcessMessage s;
End;
I did not test it myself (short of time right now)
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.ProcessMessage
MDIChildren[i].Invalidate;
MDIChildren[i].Update;
Application.ProcessMessage
End;
I did not test it myself (short of time right now)
ASKER
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?
ASKER
Since my last comment, I have in fact solved the problem myself. The following code does what I want:
Child:=TChildForm.Create(S elf);
if MDIChildCount >1 then
for i:= 1 to MDIChildCount-1 do
begin
MDIChildren[i].SetFocus;
MDIChildren[i].Update;
Application.ProcessMessage s;
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
Child:=TChildForm.Create(S
if MDIChildCount >1 then
for i:= 1 to MDIChildCount-1 do
begin
MDIChildren[i].SetFocus;
MDIChildren[i].Update;
Application.ProcessMessage
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
ASKER