Results 1 to 23 of 23

Thread: Get Handle of Parent of a User Control

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2017
    Posts
    500

    Get Handle of Parent of a User Control

    How do I get the handle of the parent Form from the User Control

  2. #2
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,373

    Re: Get Handle of Parent of a User Control

    When the UserControl is not nested in another UserControl than just "UserControl.Parent.hWnd" is sufficient.

  3. #3
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: Get Handle of Parent of a User Control

    Parent.hWnd

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: Get Handle of Parent of a User Control

    And Parent and Container are different. The Parent will always be some form, whereas the Container will not necessarily be a form.

    If you want the hWnd of the Container, you can do: ctrl.Container.hWnd

    Enjoy,
    Elroy

    EDIT1: I seriously doubt this is what you're after, but, to cover Krool's suggested situation, if you're in a custom-user-control, and you want the main form's handle, the following will do it pretty much anywhere within the user-control: Extender.Parent.hWnd or either Extender.Container.hWnd (for a container on the main form).
    Last edited by Elroy; Apr 11th, 2017 at 02:02 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: Get Handle of Parent of a User Control

    Also, Ordinary Guy, if you're actually designing a custom User-Control, here's a link to a pastebin document that may help you. It's just something I put together a few years back.

    Enjoy,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  6. #6
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: Get Handle of Parent of a User Control

    Quote Originally Posted by Elroy View Post
    The Parent will always be some form
    Not always.
    As Krool already mentioned, the usercontrol may be inside another usercontrol, and in that case the Parent is that usercontrol, not the form.

    And if the parent Usercontrol does not have hWnd property implemented, Parent.hWnd on the child usercontrol raises an error.

  7. #7
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: Get Handle of Parent of a User Control

    @Eduardo: Agreed.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  8. #8
    PowerPoster
    Join Date
    Sep 2012
    Posts
    2,083

    Re: Get Handle of Parent of a User Control

    Code:
    '=============================================================================================
    'The following source code comes from LaVolpe's AlphaImage Control - sptRemoteRender
    'http://www.vbforums.com/showthread.php?630193-vb6-Alpha-Image-Control-v2-Final-Update-(15-Jan-2012)
    'Reorganized by Dreammanor on April 12, 2017
    '=============================================================================================
    Private Function GetParentHandle(Optional ByVal bGetContainerHandle As Boolean = False) As Long
        Dim hHandle As Long
        Dim sControlName As String
        Dim meControl As Control, myForm As Object
        Dim X As Long, Index As Integer
            
        On Error Resume Next
        
        Set myForm = ParentControls(0)                  ' set instance of form/mdi
        X = myForm.Controls.Count
        If Err Then
            Err.Clear
            Exit Function
        End If
        
        sControlName = Ambient.DisplayName              ' get our control's name
        X = InStr(sControlName, "(")                    ' indexed?
        If X Then                                       ' if so, get the index
            Index = Val(Mid$(sControlName, X + 1))      ' adjust control name & assign
            sControlName = Left$(sControlName, X - 1)
            Set meControl = myForm.Controls(sControlName)(Index)
        Else                                            ' assign
            Set meControl = myForm.Controls(sControlName)
        End If
        If Err Then Exit Function
        
        Set myForm = Nothing                            ' done with this
        
        If bGetContainerHandle = True Then
            hHandle = meControl.Container.hWnd
        Else
            hHandle = meControl.Parent.hWnd
        End If
        If Err Then Exit Function
         
        GetParentHandle = hHandle
         
    End Function
    Last edited by dreammanor; Apr 12th, 2017 at 06:52 AM.

  9. #9
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,373

    Re: Get Handle of Parent of a User Control

    Another tip. Instead .Container.hWnd use .ContainerHwnd property. Looks more direct for me and maybe somewhat faster.

  10. #10
    PowerPoster
    Join Date
    Sep 2012
    Posts
    2,083

    Re: Get Handle of Parent of a User Control

    Krool, agree with you, ContainerHwnd property should be more direct and faster. But meControl is the standard form control, which has no ContainerHwnd property, so we can only use UserControl.ContainerHwnd. In addition, meControl also has some other properties that UserControl doesn't have, such as:

    nScaleMode = meControl.Container.ScaleMode
    Last edited by dreammanor; Apr 12th, 2017 at 06:42 AM.

  11. #11
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: Get Handle of Parent of a User Control

    There is an API that will return the form's hWnd, redardeless the usercontrol sits on the form or in another usercontrol:

    Code:
    Private Declare Function GetAncestor Lib "user32.dll" (ByVal hwnd As Long, ByVal gaFlags As Long) As Long
    Private Const GA_ROOT = 2
    
    Private Sub UserControl_Show()
        Debug.Print "Parent form hWnd: " & GetAncestor(UserControl.hwnd, GA_ROOT)
    End Sub
    But it won't work at the time of the ReadProperties event.

  12. #12
    Fanatic Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    547

    Re: Get Handle of Parent of a User Control

    hParent = GetAncestor(Usercontrol.Hwnd, GA_PARENT)

    I tried this above and it just doesn't work if the container is not a form.



    Code:
    Private Function GetParentHandle(Optional ByVal bGetContainerHandle As Boolean = False) As Long
        Dim hHandle As Long
        Dim sControlName As String
        Dim meControl As Control, myForm As Object
        Dim X As Long, Index As Integer
            
        On Error Resume Next
        
        Set myForm = ParentControls(0)                  ' set instance of form/mdi
        X = myForm.Controls.Count
        If Err Then
            Err.Clear
            Exit Function
        End If
        
        sControlName = Ambient.DisplayName              ' get our control's name
        X = InStr(sControlName, "(")                    ' indexed?
        If X Then                                       ' if so, get the index
            Index = Val(Mid$(sControlName, X + 1))      ' adjust control name & assign
            sControlName = Left$(sControlName, X - 1)
            Set meControl = myForm.Controls(sControlName)(Index)
        Else                                            ' assign
            Set meControl = myForm.Controls(sControlName)
        End If
        If Err Then Exit Function
        
        Set myForm = Nothing                            ' done with this
        
        If bGetContainerHandle = True Then
            hHandle = meControl.Container.hWnd
        Else
            hHandle = meControl.Parent.hWnd
        End If
        If Err Then Exit Function
         
        GetParentHandle = hHandle
         
    End Function

    This code also does not work.

  13. #13
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,373

    Re: Get Handle of Parent of a User Control

    Another way of doing it..

    Inside UserControl:
    Code:
    GetTopUserControl(Me).Parent.hWnd
    Code:
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
    
    Public Function GetTopUserControl(ByVal UserControl As Object) As VB.UserControl
    If UserControl Is Nothing Then Exit Function
    Dim TopUserControl As VB.UserControl, TempUserControl As VB.UserControl
    CopyMemory TempUserControl, ObjPtr(UserControl), 4
    Set TopUserControl = TempUserControl
    CopyMemory TempUserControl, 0&, 4
    With TopUserControl
    If .ParentControls.Count > 0 Then
        Dim OldParentControlsType As VBRUN.ParentControlsType
        OldParentControlsType = .ParentControls.ParentControlsType
        .ParentControls.ParentControlsType = vbExtender
        If TypeOf .ParentControls(0) Is VB.VBControlExtender Then
            .ParentControls.ParentControlsType = vbNoExtender
            CopyMemory TempUserControl, ObjPtr(.ParentControls(0)), 4
            Set TopUserControl = TempUserControl
            CopyMemory TempUserControl, 0&, 4
            Dim TempParentControlsType As VBRUN.ParentControlsType
            Do
                With TopUserControl
                If .ParentControls.Count = 0 Then Exit Do
                TempParentControlsType = .ParentControls.ParentControlsType
                .ParentControls.ParentControlsType = vbExtender
                If TypeOf .ParentControls(0) Is VB.VBControlExtender Then
                    .ParentControls.ParentControlsType = vbNoExtender
                    CopyMemory TempUserControl, ObjPtr(.ParentControls(0)), 4
                    Set TopUserControl = TempUserControl
                    CopyMemory TempUserControl, 0&, 4
                    .ParentControls.ParentControlsType = TempParentControlsType
                Else
                    .ParentControls.ParentControlsType = TempParentControlsType
                    Exit Do
                End If
                End With
            Loop
        End If
        .ParentControls.ParentControlsType = OldParentControlsType
    End If
    End With
    Set GetTopUserControl = TopUserControl
    End Function

  14. #14
    Fanatic Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    547

    Re: Get Handle of Parent of a User Control

    Hello Krool, how are you? Thanks for the feedback.

    My problem is as follows: I am using a subclassing and in it I used WM_SIZING for when parent.hwnd receives the sizing call it responds to a certain event.

    The problem is that if the usercontrol is in the form everything is fine, but if it's in a container then WM_SIZING just doesn't work.

  15. #15
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Get Handle of Parent of a User Control

    @Episcopal. You should explain why it doesn't work. Is a valid hWnd being returned or is it zero. Where are you calling your function to get the parent hWnd? From which usercontrol event. It is possible the problem is when it is being called.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  16. #16
    PowerPoster
    Join Date
    Feb 2017
    Posts
    4,995

    Re: Get Handle of Parent of a User Control

    Hello, this is another option that can work with nested UserControls:

    Code:
    Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
    
    Private Function GetFormHwnd() As Long
        Dim lPar As Long
        Dim iHwnd As Long
        
        iHwnd = UserControl.hWnd
        lPar = GetParent(iHwnd)
        While lPar <> 0
            iHwnd = lPar
            lPar = GetParent(lPar)
        Wend
        GetFormHwnd = iHwnd
    End Function

  17. #17
    Fanatic Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    547

    Re: Get Handle of Parent of a User Control

    I created this control from other examples like AeroSuite ... and implemented SeabrookStan's idea for Anchor controls.

    http://www.vbforums.com/showthread.p...king-made-Easy



    my attached example ... when I change the size of the form, the controls inside the container don't work.

    thank.
    Attached Files Attached Files

  18. #18
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Get Handle of Parent of a User Control

    Well, just reviewing the code (not running it), Button.ctl & Example.ctl subclass the control, not the host/parent.

    Teste.ctl subclasses the control and also attempts to subclass the control's container. You said this works when the container is the form but doesn't when the container is not the form. I'm thinking it does work, but you may not be trapping the right message.

    If the container is a picturebox for example, then it is highly unlikely that it will receive WM_SIZING messages when the picturebox is resized. It should receive WM_SIZE message after it resizes. It's really important to read documentation for the messages you are subclassing so that you know when they occur and how to respond to them.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  19. #19
    Fanatic Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    547

    Re: Get Handle of Parent of a User Control

    Really you are the master of development.

    WM_SIZE really works.

    Thank you very much.

  20. #20
    Hyperactive Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    506

    Re: Get Handle of Parent of a User Control

    very good control.
    I hope that property could be implemented as asked in another post.
    it would be very useful.
    Greetings

  21. #21
    Fanatic Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    547

    Re: Get Handle of Parent of a User Control

    Code:
    I hope that property could be implemented as asked in another post.

    I would not venture.

  22. #22
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: Get Handle of Parent of a User Control

    For the Resize-Handling itself, I wouldn't bother with SubClassing...

    Instead - what such a "BaseContainer-Control" could support, is a mechanism -
    which will result in a CallBack (within the ContainerControl itself), when the Parent is resized.

    In the RC5-WidgetEngine I've implemented something similar - and named the internal CallBack-Method:
    Container_Resize()

    This works (without storing Parent-References within the Controls permanently - and is thus Circle-Ref-safe),
    by just enumerating all the Child-Controls within the UserControl_Resize()-Handler - and calling this method.

    Here is an example, what I mean:
    - in an empty Form-Project, add a Private UserControl and name it ucContainer
    - set its "ControlContainer"-Property to True
    - now paste the following "Anchor-Test-Code" into it:
    Code:
    Option Explicit
    
    Private AL As Boolean, AT As Boolean, AR As Boolean, AB As Boolean
    
    '*** UserControl-EventHandlers ***
    Private Sub UserControl_Paint()
      DrawWidth = 2: Cls
      Line (15, 15)-(ScaleWidth - 30, ScaleHeight - 30), vbBlue, B
    End Sub
    Private Sub UserControl_Resize()
      ResizeNotifyChildrenOf UserControl
    End Sub
    
    '*** Public Methods ***
    Public Sub SetAchors(L, T, R, B)
      AL = L: AT = T: AR = R: AB = B
    End Sub
    
    Public Sub ResizeNotifyChildrenOf(ByVal Ctl)
      On Error Resume Next
        For Each Ctl In Ctl.Controls
          Ctl.Container_Resize
        Next
      On Error GoTo 0
    End Sub
    
    Public Sub Container_Resize()
      With Extender
        Dim WP!: WP = .Parent.ScaleWidth
        Dim HP!: HP = .Parent.ScaleHeight
        
        Static dL!: If dL = 0 Then dL = WP - .Left
        Static dT!: If dT = 0 Then dT = HP - .Top
        Static dW!: If dW = 0 Then dW = WP - .Width
        Static dH!: If dH = 0 Then dH = HP - .Height
        
        Dim W!: W = .Width:  If AL And AR Then W = WP - dW
        Dim H!: H = .Height: If AT And AB Then H = HP - dH
        Dim L!: L = .Left:   If AR And Not AL Then L = WP - dL
        Dim T!: T = .Top:    If AB And Not AT Then T = HP - dT
        
        .Move L, T, IIf(W > 0, W, 1), IIf(H > 0, H, 1)
      End With
      UserControl.Refresh
    End Sub
    Now place two instances of ucContainer on the Form (as ucContainer1 and ucContainer2)
    Make sure, that ucContainer2 is placed "within" ucContainer1 as a Child-Control...
    Form-Test-Code is then:
    Code:
    Option Explicit
    
    Private Sub Form_Load()
      ucContainer1.SetAchors 1, 1, 1, 1
      ucContainer2.SetAchors 1, 1, 1, 1 'this was placed as a Child-Control on ucContainer1
    End Sub
    
    Private Sub Form_Resize()
      'only one such call, from *any* of the ucContainer-Controls on this form has to be made
      ucContainer2.ResizeNotifyChildrenOf Me
    End Sub
    HTH

    Olaf

  23. #23
    Fanatic Member Episcopal's Avatar
    Join Date
    Mar 2019
    Location
    Brazil
    Posts
    547

    Re: Get Handle of Parent of a User Control

    Private Sub Form_Resize()
    'only one such call, from *any* of the ucContainer-Controls on this form has to be made
    ucContainer2.ResizeNotifyChildrenOf Me
    End Sub

    Great master .... in your case you are using the form resize .... in my case I implemented a property in usercontrol ... By the way ... you are very creative.

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