Solved

Smart function which provides me all controls that are contained in a Control Container

Posted on 2002-06-20
28
140 Views
Last Modified: 2010-05-02
Hello Experts !

I need a smart function like below:

Private Function GetAllContainedControls(CtrlContainer As Control) As Collection
    Dim colResult As Collection
    '.....
    'If ... Then
        'Set colResult = New Collection
        '....
        'Call colResult.Add(..., ...)
    'end if
    '...
    Set GetAllContainedControls = colResult
End Function
0
Comment
Question by:VK
  • 8
  • 7
  • 7
  • +1
28 Comments
 
LVL 18

Accepted Solution

by:
bobbit31 earned 50 total points
ID: 7096050
how bout:

Private Sub Command1_Click()
Dim i As Integer
Dim colControls As Collection

Set colControls = GetAllContainedControls(Frame1)

For i = 1 To colControls.Count
   MsgBox colControls(i).Name
Next

End Sub

Private Function GetAllContainedControls(CtrlContainer As Control) As Collection
   Dim colResult As New Collection
   Dim cntrl As Control

   For Each cntrl In Me.Controls
      If cntrl.Container.Name = CtrlContainer.Name Then
          colResult.Add cntrl
      End If
   Next

   Set GetAllContainedControls = colResult
End Function
0
 
LVL 4

Expert Comment

by:gencross
ID: 7096071
You beat me bobbit :)
0
 
LVL 18

Expert Comment

by:bobbit31
ID: 7096077
;)
0
 
LVL 6

Expert Comment

by:Nitin Sontakke
ID: 7096174
I am sorry to bother you all, but could you please let me know the utility of such a function. I mean when this information is available to you at runtime anyway, why would one want to put it in yet another collection?

0
 
LVL 6

Author Comment

by:VK
ID: 7096386
Hello Experts !

To eliminate the obscurities:

I need that function for example to disable all "Sub-Controls" of a control. When i have a frame Frame1 and i set Frame1.Enabled=False then the "Sub-Controls" are disabled too but are not greyed if i don't disable them too.

Regards

V.K.
0
 
LVL 6

Author Comment

by:VK
ID: 7096433
Hello bobbit31 !

Thanks for the reply.
I tried your function.
Not every control has an container.
It works if i add an "on error resume next"-statement.
If i use that statement the function isn't smart anymore.

Nevertheless i will gave you the points, but i hope you can tell me a version without error handling.

V.K.
0
 
LVL 4

Expert Comment

by:gencross
ID: 7096436
I thought that is what you were trying to do:)  

What you may want to is not put the controls in a collection.  Instead use the code to go ahead and disable the control once you see that it is part of the container.  This way you do not use more memory and eliminate a step...

Private Function DisableAllContainedControls(CtrlContainer As Control) As Collection
  Dim cntrl As Control

  For Each cntrl In Me.Controls
     If cntrl.Container.Name = CtrlContainer.Name Then
         cntrl.Enabled = False
     End If
  Next

End Function
0
 
LVL 18

Expert Comment

by:bobbit31
ID: 7096437
have you tried my code yet?
0
 
LVL 18

Expert Comment

by:bobbit31
ID: 7096450
> Not every control has an container.

can you give an example?  If it's on a form, then the form is the container unless it's in another container.
0
 
LVL 6

Expert Comment

by:Nitin Sontakke
ID: 7096456
Now, that makes some sense to me!

Here is code to achieve if, unfortunately, gencross has already put similiar code above, anyway. But now that i have written it might as well paste it.

Points to gencross, please!

Private Sub Command1_Click()
    Dim objCon As Control
    Frame1.Enabled = Not Frame1.Enabled
    For Each objCon In Me.Controls
        If objCon.Container.Name = Frame1.Name Then
            objCon.Enabled = Frame1.Enabled
        End If
    Next
End Sub
0
 
LVL 6

Author Comment

by:VK
ID: 7096483
Hello bobbit31 !

I have already tested the your function.
If cntrl is an commondialog-control for example then it hasn't a container and i get error 438.

V.K.
0
 
LVL 6

Author Comment

by:VK
ID: 7096503
To all who replied to my question !

OK, now i got 3 suggestions. And they are all similar.
The one who tells me a way without error handling will get the points. If nobody can find a "straight" way doing that bobbit31 will get the points because he was first.

regards

v.k.
0
 
LVL 4

Expert Comment

by:gencross
ID: 7096516
Here is your original call, not my modified one

You can add a TypeOf for each control without a container.


Private Function GetAllContainedControls(CtrlContainer As Control) As Collection
  Dim colResult As New Collection
  Dim cntrl As Control

  For Each cntrl In Me.Controls
    If Not TypeOf cntrl Is CommonDialog Then
        If cntrl.Container.Name = CtrlContainer.Name Then
            colResult.Add cntrl
            MsgBox cntrl.Name
        End If
    End If
  Next

  Set GetAllContainedControls = colResult
 
End Function
0
 
LVL 6

Expert Comment

by:Nitin Sontakke
ID: 7096530
Sorry, gencross, a minor improvement over your code. Not tested by me.

No points to me, please!

Private Function GetAllContainedControls(CtrlContainer As Control) As Collection
Dim colResult As New Collection
Dim cntrl As Control

For Each cntrl In Me.Controls
    Select Case True
        Case TypeOf cntrl Is CommonDialog
'       Add case with any other controls you may find have not container property...
        Case Else
            If cntrl.Container.Name = CtrlContainer.Name Then
               colResult.Add cntrl
               MsgBox cntrl.Name
            End If
   End If
Next

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 6

Expert Comment

by:Nitin Sontakke
ID: 7096536
and of course, End Case, before, Next.
0
 
LVL 6

Author Comment

by:VK
ID: 7096545
Hello  gencross.

Ok, we know now that a CommonDialog-Contol has no Container Member. But:

1. Do you know all the types of controls who have no container member. I think not because of usercontrols or third party controls or whatever.

2. This function should work for every form regardless which controls containing.

I found out that the Commondialog-Contol for example has a parent property. But if so when to use .container and when to use .parent without getting an error ?

V.K.
0
 
LVL 4

Expert Comment

by:gencross
ID: 7096552
NitanSontakke,

I tried quickly to get the select to work, but I think I messed the syntax up (I was in a hurry).  Yours works great:)

Using a select case is the way to go.  Here is the call that disables the controls with the modified code if your interested...

Private Function DisableAllContainedControls(CtrlContainer As Control) As Collection
 Dim cntrl As Control

 For Each cntrl In Me.Controls
    Select Case True
        Case TypeOf cntrl Is CommonDialog
        Case Else
   
           If cntrl.Container.Name = CtrlContainer.Name Then
               cntrl.Enabled = False
           End If
    end select
 Next

End Function
0
 
LVL 6

Expert Comment

by:Nitin Sontakke
ID: 7096574
VK,

I personally, don't see a way out, but to have 'On error resume next' and then check explicitely for the error 'Object doesnot support this property' or whatever it is.

Unfortunately, VB doesn't, to the best of my current knowledge, allow you to query the properties before accessing them. Something which is now available in .NET with Reflection classes.

What do you think?
0
 
LVL 18

Expert Comment

by:bobbit31
ID: 7096586
i'd have to agree w/ nitinsontakke that you just catch the specific error and ignore it.
0
 
LVL 4

Expert Comment

by:gencross
ID: 7096591
ditto.  It was fun trying though:)
0
 
LVL 4

Expert Comment

by:gencross
ID: 7096595
Points to bobbit
0
 
LVL 6

Author Comment

by:VK
ID: 7096608
OK, thank to all of you :-).
Points to bobbit !!

V.K.
0
 
LVL 6

Expert Comment

by:Nitin Sontakke
ID: 7096615
I am not here for points anyway. So fine with me. Mine was the most benign comment..."I am sorry to bother you all.."
0
 
LVL 18

Expert Comment

by:bobbit31
ID: 7096639
i knew i could get it w/ api... here ya go

Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2

Dim l As Long
Dim s As String * 255

Private Sub Command1_Click()
Dim i As Integer
Dim colControls As Collection

Set colControls = GetAllContainedControls(Frame1)

For i = 1 To colControls.Count
  MsgBox colControls(i).Name
Next

End Sub


Private Function GetAllContainedControls(CtrlContainer As Control) As Collection
  Dim colResult As New Collection
  Dim cntrl As Control

  l = GetWindow(CtrlContainer.hwnd, GW_CHILD)
  If l <> 0 Then
    GetWindowText l, s, 255
    colResult.Add (Me.Controls(Left$(s, InStr(s, Chr(0)) - 1)))
    Do
    l = GetWindow(l, GW_HWNDNEXT)
    If l <> 0 Then
        GetWindowText l, s, 255
        colResult.Add (Me.Controls(Left$(s, InStr(s, Chr(0)) - 1)))
    End If
    Loop While l <> 0
  End If

  Set GetAllContainedControls = colResult
End Function
0
 
LVL 6

Author Comment

by:VK
ID: 7096645
Hi NitinSontakke !

You comment was the best (but not the entire solution).
Bobbit31's solution was the first solution (without error handling). I decided to give the points to Bobbit31 becaus i didn't need help in writing an error handler. The key senmtence is "cntrl.Container.Name = CtrlContainer.Name" and that he wrote first. Sorry.

Regards

V.K.
0
 
LVL 4

Expert Comment

by:gencross
ID: 7096655
Good code bobbit.  Works great!
0
 
LVL 18

Expert Comment

by:bobbit31
ID: 7096673
thanks! i just hope VK comes back to this question and see's it ;)
0
 
LVL 6

Author Comment

by:VK
ID: 7096723
Hello bobbit31 !

Nice approach !! Now you have unclearly deseved the points.
The function (i tested it meanwhile) works too, but i get an error 738 in the configuration below:

Picture1 containing a ListView1.

Also: Windowless controls aren't detected. Usercontrols raise error 738.

Nevertheless, good work !!

V.K.

0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now