Hi,
Im not able to center a child form of a parent MDIForm (MDIForm1) it shows up error message "Invalid property value" while setting the StartUpPosition property to 1-CenterOwner, or 2-CenterScreen, or 3-WindowsDefault of the child form.

How can I set all the StartUpPosition property of the child form?

Please help!

Dani AI

Generated

Quick summary tied to the thread: the StartUpPosition values that raised "Invalid property value" on are not a reliable way to place VB6 MDI child windows. The simple Move-based fixes suggested by and do work in many cases, and correctly pointed out that you must position children yourself when needed. The common pitfalls are: the MDI child is positioned inside the MDIClient window (not the full MDI form), VB6 form properties are in twips while Win32 APIs use pixels, and a child’s actual window size/handle isn’t always final until after Show/Activate.

A robust approach is to center the child against the MDIClient using the Win32 API (pixels) so you avoid twips conversions and account exactly for the client area. Put the declarations in a standard module and call the routine after the child has been created/shown (for example, from the MDI parent right after Show or from the child’s Activate). Also set the child form’s StartUpPosition to Manual in the designer to avoid the property error.

' Standard module: API declarations and centering routine
Public Type RECT
  Left As Long: Top As Long: Right As Long: Bottom As Long
End Type

Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
  (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, _
   ByVal lpszClass As String, ByVal lpszWindow As String) As Long

Public Declare Function GetClientRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Public Declare Function SetWindowPos Lib "user32" _
  (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, _
   ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Public Const SWP_NOZORDER = &H4
Public Const SWP_NOSIZE = &H1

Public Sub CenterMDIChildOnParent(MDIParentHWnd As Long, ChildHWnd As Long)
  Dim hMDIClient As Long, rcClient As RECT, rcChild As RECT
  Dim clientW As Long, clientH As Long, childW As Long, childH As Long
  Dim x As Long, y As Long

  hMDIClient = FindWindowEx(MDIParentHWnd, 0&, "MDIClient", vbNullString)
  If hMDIClient = 0 Then Exit Sub

  GetClientRect hMDIClient, rcClient
  clientW = rcClient.Right - rcClient.Left
  clientH = rcClient.Bottom - rcClient.Top

  GetWindowRect ChildHWnd, rcChild
  childW = rcChild.Right - rcChild.Left
  childH = rcChild.Bottom - rcChild.Top

  x = (clientW - childW) \ 2
  y = (clientH - childH) \ 2

  SetWindowPos ChildHWnd, 0&, x, y, 0, 0, SWP_NOZORDER Or SWP_NOSIZE
End Sub

Usage notes: call CenterMDIChildOnParent MDIForm1.hWnd, frmChild.hWnd after frmChild.Show (or from child Form_Activate). This handles maximized parent, menu/toolbars, and multiple-monitor pixel math better than a naive Move calculation.

Recommended Answers

All 7 Replies

You have to calculate the distance, and use form.move....in a module (normal code module, not class) add this:

Sub DoCenter(child As Form, parent As Form)
Dim mTop As Integer
Dim mLeft As Integer

If parent.WindowState <> vbNormal Then Exit Sub
mTop = ((parent.Height - child.Height) \ 2)
mLeft = ((parent.Width - child.Width) \ 2)
child.Move mLeft, mTop
End Sub

Then whenever you want to center the form, just call DoCenter mdiChild, mdiParent

You have to calculate the distance, and use form.move....in a module (normal code module, not class) add this:

Sub DoCenter(child As Form, parent As Form)
Dim mTop As Integer
Dim mLeft As Integer

If parent.WindowState <> vbNormal Then Exit Sub
mTop = ((parent.Height - child.Height) \ 2)
mLeft = ((parent.Width - child.Width) \ 2)
child.Move mLeft, mTop
End Sub

Then whenever you want to center the form, just call DoCenter mdiChild, mdiParent

Sorry my friend this did not work !!!
Any other ideas ?

Hmmm, worked great for me.

Why can't you just put centering code in the Form_Load event of the mdi child form? You know what window will be the parent, and it wouldn't matter is the parent is maximized or normal.

Hi,

You cannot set the Start-Up position for the MDI Child forms in VB6..
This is from MSDN Help:
The initial size and placement of MDI child forms are controlled by the Microsoft Windows operating environment unless you specifically set them in the Load event procedure.

So You can write this code in MDI, wherever, you want to show the form..:

Form1.Show
Form1.Move (Me.Width - Form1.Width) / 2, (Me.Height -  Form1.Height - 800) / 2

Note 800: Approx Height of MDI TitleBar +Windows Start/TaskBar

Regards
Veena

Thanks
that all sure did help !

In the form load of the form you want to center put this code

Me.Move (mdiMain.Width - Me.Width) / 2, (mdiMain.Height -  Me.Height) / 2
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.