How do I make an MDI Child Form Always on Top of other Child Forms?

rdavis101
rdavis101 used Ask the Experts™
on
I have an MDI app and multiple child forms...how can I make one of the child forms always on top of the others?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Unfortunately, as far as I understand the one that has the focus is on top.  That mean that if the other will never be on top is because they will never have focus, so why bother with creating them in the first place.  I think you have to rething your approach.

Author

Commented:
This kind of works...still tweaking it...

Create a new form...set the Child property to FALSE...the new form cannot be a child of the MDI Form. Then, use the SetParent API to make the MDIForm the parent of the new form.

The new form is now "above" all the MDI Child forms, and travels with the MDI Form when the MDI Form is moved or minimized.

However, in positioning the new form, it appears you have to take into consideration the width and height of any controls that are aligned to the top and left of the MDI Form.

I don't yet.

Roger

Author

Commented:
This works, but not for what I want it to do... I need a child form that can be on top and remain a child. Otherwise, the MDI Form loses the focus, and the child forms repaint when the MDI Form regains the focus. That repainting what I'm trying to prevent.

Ideas?

Roger
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

FYI, the SetWindow API doesn't work to set it to Topmost.

Have you tried making the parent of the form a picturebox that's on the MIDParent.  This would mean the form is always at the top or the bottom of the MDI Form, but maybe this is what you want.  I don't know how it will impact the repainting issue (actually it appears to work see below), but hosting it inside a control the parent already owns may be a viable idea and may prevent the repainting.

So here's the heirarchy:
MDIForm
    PictureBox at top or bottom
        MDI Child Form hosted in the picturebox.

Here's the code I have.  The MDI Child form only paints once (surprise to me!)

MDI PARENT FORM
Has a picturebox at the top named Picture1

Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Private Sub MDIForm_Load()

    Load Form2
    Load Form3
    Load Form1
   
    Dim lReturn As Long
   
    lReturn = SetParent(Form1.hWnd, Picture1.hWnd)
    Debug.Print lReturn
   
End Sub



FORM1
Private Sub Form_Paint()
 
 Debug.Print "Paint"
 
End Sub

Author

Commented:
Twalgrave,

It had never occurred to me to host a child form in a picture box...I had never thought about that, so I'm happy to add that to my box of tricks. :)

I think I solved the problem in a different way...here's the situation: I have a child form that must be a certain size and can't change. Other child forms need to be able to maximize and de-maximize at the user's whim. However, when you maximize one child form, they all want to maximize (and why is this??).

So...I tried making the size-constrained child not a child at all, just a form outside the MDI environment. That had the unhappy outcome that all the child forms repainted when the MDI Form regained focus. Lots of flicker. Unacceptable.

So...I tried setting the MDI as the parent...that had the happy possibility of letting the "child" travel with the MDI Form when it was dragged or minimized, but the flicker problem persisted. Unacceptable. It was problems with this part that motivated this question.

Next, I tried showing the child and setting its Z-order to zero:  

Form1.zorder=0
Form1.show

That makes the child appear on top, which is close enough to what I need to be workable.

However, there was still the problem with maximized forms and my one child form needing to stay a certain size.

So...I wrote a routine I call "Pseudomaximize." Basically it just exists in the MDI_Resize event. If the b_Pseudomaximize flag is true, then the child is sized so that it's title bar and edges are covered up by the border of the MDI Form. The user never knows the difference.

By intercepting the WM_MDIMaximize, you can call "PseudoMaxmimize" and make it appear that maximized forms and non-maximized forms coexist in the same MDI workspace.

Roger
good solution.  However, I can still select one of the other child windows to bring to the front of the "Always on top" window can't I(through the menu selecting the child if you have one), through code, etc.

Author

Commented:
twalgrave,

Yes, you can...it just happens that the child form that needs to be on top is part of custom menuing system I wrote...so...when it loses the focus it just needs to disappear anyway.

If the child really needed to be Always on Top, then the solution above wouldn't work.

To my knowledge, there is no way to make an MDIChild Always on Top...And yet, somewhere the OS must keep track of the Z order of the windows.

Speculation: Perhaps using the Timer control to constantly set the Z-order of the child to be Always on Top to zero would work?

Roger




OK, just confused because the original question wanted the MDI child form to be always on top.

As far as making an MDIChild Always On Top, I did come up with a creative way of doing that.  You can't get the others above it.  I did try other methods to no avail (including Setwindow).

As to your speculation, it would work UNLESS you did something like what you proposed.  If the form that is being set to the front always blocks out the other forms, there would be no way to get to them (unless you used the menus)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial