Link to home
Start Free TrialLog in
Avatar of rdavis101
rdavis101

asked on

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

I have an MDI app and multiple child forms...how can I make one of the child forms always on top of the others?
Avatar of CarlosMu
CarlosMu

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.
Avatar of rdavis101

ASKER

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

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




ASKER CERTIFIED SOLUTION
Avatar of twalgrave
twalgrave

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial