How do you set the Z order on a control in VB6? There doesn't seem to be a property for it...

It seems as though I have no control over which control takes the foreground :( I suspect it is based on the order they are declared in the .frm file (stuff you can't see in the IDE) but I want to do it programatically.

Dani AI

Generated

Short summary and practical patterns that build on ’s answer and address ’s frustration.

If the goal is a specific stack order, the usual approach is to call ZOrder for each overlapping control in the order you want—there’s no built‑in single call to insert a control at an arbitrary z‑position. Use the Controls collection and a small routine to avoid hand‑calling each control. (learn.microsoft.com)

A compact helper (pass a list where the first name should end up on top):

' orderList is a zero‑based Variant array of control names,
' first item becomes topmost after the loop
Private Sub ApplyZOrder(orderList As Variant)
    Dim i As Long
    For i = 0 To UBound(orderList)
        Me.Controls(orderList(i)).ZOrder 0
    Next i
End Sub

' Example call:
' ApplyZOrder Array("picBackground","lblTitle","txtInput","cmdOK")

Use the Controls collection when looping by name or index (Me.Controls(...)) and call this after the controls exist (Form_Load or Form_Activate, or right after runtime creation). (learn.microsoft.com)

Important pitfalls and alternatives: VB6 has two z‑layers — "windowed" (standard) and "windowless" (lightweight) controls — and windowless controls will never draw above windowed controls unless placed inside a container that changes the drawing context. If a label or Image refuses to appear above a TextBox, check whether it is windowless. For more direct hWnd-level reordering you can use the Win32 API SetWindowPos, but that only works for windowed controls (you need a valid hWnd). Grouping related controls inside a PictureBox/Frame is often the simplest practical fix. (jeffpar.github.io)

If something still draws wrong at startup, try forcing the ordering after the form is shown (Form_Activate) or recreate the offending controls as windowed controls; those two tricks resolve most VB6 stacking headaches.

Recommended Answers

All 2 Replies

ZOrder is actually a method, not a property. You can only move a control all the way to the back:

me.myControl.ZOrder 1

or all the way to the front:

me.myControl.ZOrder 0

So, as you can guess, if you want specific controls to overlap in a specific order, you have to issue a ZOrder method against each overlapping control, in the proper order. What a pain.

Here's a little science-experiment code snippet that demonstrates how ZOrder works. Please note that you can alter this to suit your own needs:

Private Sub cmdChangeZOrderB2F_Click()
Me.Text1.ZOrder 0
Me.Text2.ZOrder 0
Me.Text3.ZOrder 0

End Sub

Private Sub cmdChangeZOrderF2B_Click()
Me.Text1.ZOrder 1
Me.Text2.ZOrder 1
Me.Text3.ZOrder 1
End Sub

This assumes three overlapping TextBox controls on a form, and two command buttons. Alternately clicking the command buttons will cause the overlap of the controls to flip. You could also use the same ZOrder parameter, but invert the order, like so:

Me.Text3.ZOrder 0
Me.Text2.ZOrder 0
Me.Text1.ZOrder 0

Hope this answers your question! Good luck!

commented: Good help +9

ZOrder is actually a method, not a property. You can only move a control all the way to the back:

me.myControl.ZOrder 1

or all the way to the front:

me.myControl.ZOrder 0

So, as you can guess, if you want specific controls to overlap in a specific order, you have to issue a ZOrder method against each overlapping control, in the proper order. What a pain.

Here's a little science-experiment code snippet that demonstrates how ZOrder works. Please note that you can alter this to suit your own needs:

Private Sub cmdChangeZOrderB2F_Click()
Me.Text1.ZOrder 0
Me.Text2.ZOrder 0
Me.Text3.ZOrder 0

End Sub

Private Sub cmdChangeZOrderF2B_Click()
Me.Text1.ZOrder 1
Me.Text2.ZOrder 1
Me.Text3.ZOrder 1
End Sub

This assumes three overlapping TextBox controls on a form, and two command buttons. Alternately clicking the command buttons will cause the overlap of the controls to flip. You could also use the same ZOrder parameter, but invert the order, like so:

Me.Text3.ZOrder 0
Me.Text2.ZOrder 0
Me.Text1.ZOrder 0

Hope this answers your question! Good luck!

Ouch! I'll tack this onto to the long list of reasons why VB6 sucks. Thanks for the help!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.