Results 1 to 5 of 5

Thread: Set a form's parent - the RIGHT way...

  1. #1

    Thread Starter
    New Member
    Join Date
    Apr 2001
    Posts
    14
    I've done much research on this, and posted below the results of my work. To run the code and help me perfect this, you can create a new project and add a MDI form, Form1 as child, and Form2 (not a child). Keep the default names and properties. Add this code to the MDIForm1.

    This is the best I could do. For some reason, Form2 doesn't act like Form1 after I set it's parent to be MDIForm1 and changes a few properties. This is what I think the problem is, the child knows it's a child of the MDIForm, but the MDIForm doesn't know it has a new child, so it doesn't send child-specific messages to the child window. I would REALLY appreciate some help here, because it is important that I get this down.

    Code:
    Private Declare Function SetParent Lib "user32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Const GWL_HWNDPARENT = -8
    Const GWL_ID = -12
    Const GWL_STYLE = -16
    Const GWL_EXSTYLE = -20
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Const WS_CHILD = &H40000000
    Const WS_EX_MDICHILD = &H40
    Private 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
    Private Const SWP_DRAWFRAME = &H20
    Private Const SWP_NOZORDER = &H4
    Private Const SWP_NOMOVE = &H2
    Private Const SWP_NOSIZE = &H1
    Private Sub MDIForm_Load()
        Form1.Show
        Form2.Show
        SetWindowLong Form2.hwnd, GWL_STYLE, GetWindowLong(Form2.hwnd, GWL_STYLE) Or WS_CHILD
        SetWindowLong Form2.hwnd, GWL_EXSTYLE, GetWindowLong(Form2.hwnd, GWL_EXSTYLE) Or WS_EX_MDICHILD
        SetWindowLong Form2.hwnd, GWL_ID, 32769
        SetParent Form2.hwnd, GetWindowLong(Form1.hwnd, GWL_HWNDPARENT)
        SetWindowPos Form2.hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER Or SWP_NOMOVE Or SWP_NOSIZE Or SWP_DRAWFRAME
    End Sub
    Private Sub MDIForm_Unload(Cancel As Integer)
        Unload Form1
        Unload Form2
    End Sub

  2. #2
    Hyperactive Member Paul Warren's Avatar
    Join Date
    Jun 2000
    Location
    UK
    Posts
    282
    If anyone does know the right way of doing this then please help HA_VBCoder. I'm using some code to set parent/child relationships at the moment but it's a bit flakey. The program will GPF when it exits sometimes, even after the parent attrib. has been set back to the original for the child form.

    It would be really useful to have some code which sets parent/child cleanly.
    That's Mr Mullet to you, you mulletless wonder.

  3. #3
    Member
    Join Date
    Aug 1999
    Location
    Bahrain
    Posts
    41
    Thanks Paul Warren, your code has solved 90% of my problems with MDI/CHILD, the only problem i have is when you close the MDI form without closing the child form (when running from EXE only) it will crash ("This program has performed illegal operation .... ")...

    Anyway... thanks

  4. #4
    Tygur
    Guest
    It looks like you're trying to make a regular form into a mdi child without setting the MDIChild property to true. I'm not sure why you want to do this, but I do know what your problem is.

    You may know that every window has a function that processes its messages. Any messages it doesn't process get passed onto a function called DefWindowProc. The problem is that MDI child windows are supposed to call DefMDIChildProc instead. Internally, VB is still calling DefWindowProc (or whatever its replacement in vb is, if there is one). The window doesn't behave like a normal MDI child, because it doesn't have the code behind it for a normal MDI child.

    Unfortunately, I don't know of any easy way around this. If you subclass form2 and call DefMDIChildProc and then the old window procedure, the form does act like a mdi child, but it has other problems (Trust me - you don't want to do that). If you subclass it without calling the old procedure, you effectively render all the events in the form and some of the events for the controls on the form useless. Also, all labels, shapes, and lines on the form will stop working. You would have to use the API a lot just to keep the program working normally.

    If anyone doesn't understand any of my explanation, let me know. I don't think it's very easy to understand.

  5. #5
    PowerPoster
    Join Date
    Aug 2000
    Location
    India
    Posts
    2,288
    I am not sure whether this will help but see this link . This code basically makes your form a child window of any given MDI form. And it works nicely(Part of the screensaver tutorial on VB world

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width