kpollock
kpollock

Reputation: 3989

MDI Child refresh/repaint problems (C#, Winforms, .NET 2.0, VS2005, DevExpress 8.2)

Hiya - been pointed at you guys by a friend of mine.

I have an MDI application (C#, Winforms, .NET 2.0, VS2005, DevExpress 8.2) and one of my forms is behaving very strangely - not repainting itself properly where it overlaps with another instance of the same form class.

The forms contain a custom control (which contains various DevExpress controls), and are inherited from a base form (which is itself inherited).

Due to issues with form inheritance (that old chestnut) there is a bit of control rearranging going on in the constructor.

Problem 1 (minor): None of this control repositioning/resizing seems to take effect unless the form is resized, so I nudge the width up and down by one pixel after the rearranging. Ugly, hacky and I'd really like to not have to do this.

Problem 2 (major): If forms are shown then attached to the MDI form using the API call SetParent, when I display the 2nd instance, various parts of the two forms are not correctly drawn where they overlap - bits of the top one are behind the existing one - and this problem gets worse when the forms are moved around, rendering them basically unuseable. Other child forms (if present) of a different type seem unaffected...

STOP PRESS: I've established that it doesn't have to be 2 instances of the child form. With only one there are still problems - mainly round the edges of the form, like the area that's being refreshed is smaller than the form itself.

The problem does not occur if the parent is set using the .MDIParent property of the child form - but we cannot do this as the form may be being displayed by a control hosted in a non-.Net application. Also I need to display the child forms non-maximised even if the existing children (of a different type) are maximised, and that only happens using SetParent.

I have tried Refresh() on all the forms of this type (I have a controller that keeps a list of them), but no joy. I have tried to reproduce this effect form a basic app with the same inheritance structure, but I can't. Clearly it is something about the form - since I recreated the form from scratch yesterday and it is still the same it must be the code - but what??

I am not the hottest on form painting events etc. so have I missed something?

Upvotes: 1

Views: 6077

Answers (3)

acoustique
acoustique

Reputation: 1

I know this is an old thread, but something I did fixed the issue for me. This might help someone with a similar problem.

My problem: We have an application in which we embed two external applications in a parent window separated by a splitter. Its used for displaying information from the two applications side by side. The problem we were facing was that the two child windows were getting drawn on the parent window just fine (using SetParent, SetWindowLong and MoveWindow), but while moving or performing operations in the child windows, they would have paint / refresh issues (more specifically, the parent panel would get drawn over the child windows)

After reading tons of articles about embedding windows, SetParent problems, the MSDN page http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx gave me a clue.

Solution: When using SetWindowLong (to set styles) use the WS_CLIPCHILDREN style -

::SetWindowLong(hwnd, GWL_STYLE, WS_VISIBLE | WS_CLIPCHILDREN));

What this style does is it prevents the parent window from re-drawing the area occupied by the child windows. This resolved the issue completely for me.

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 942119

Yes, that would do it. Changing the FormBorderStyle requires Windows Forms to recreate the window from scratch, now using different style flags in the CreateWindowEx() call. That would make it completely forget about the parent you set with the SetParent() P/Invoke. There are lots of other properties that causes this to happen. Avoid the kind of trouble you got into by making these calls in an override of the OnHandleCreated() method.

Better yet, avoid troublesome APIs like SetParent() completely by putting all your controls and logic in a UserControl.

Upvotes: 1

kpollock
kpollock

Reputation: 3989

Ah ha!

I was changing the FormBorderStyle in code before showing the form. I removed that line and the problem went away...

That'll do for me. :-)

Upvotes: 0

Related Questions