Using reflection on VB6 Collections

dotnet framework

    Next

  • 1. axWebbrowser and Credentials
    Hello: I need to access a forms authenticated website from a winforms application thru a webbrowser. I haven't came across any examples yet. The winforms app already knows the credentials for the website and so I should be able to access the website without the user having to logon again. Thanks danths
  • 2. passing C# array to and from C array
    I have what I imagine is a simple question, but don't know how to approach it really. I have a dll compiled from ANSI C, which has a function declaration with an array; void myFunc(int data[], ...); How can I send in a C# array to "data[]" and get it back out? Thanks.
  • 3. SWStringArray to .Net string array or ArrayList
    Any idea or code example how i can marshal a SWStringArray to a .Net string array or ArrayList?
  • 4. AxSHDocVw.AxWebBrowser and Window Activation issue
    We have created a MDI application that uses a AxSHDocVw.AxWebBrowser component on one of the child windows. As soon as this child window is created, none of the open MDI child windows is activated if clicked upon, except for when the window border or title bar is clicked. So the problem is: AxSHDocVw.AxWebBrowser if contained by a MDI child window, prevents child windows from being activated properly. It is even possible to have two active MDI child windows! I could not find a bug report in support database. Am I doing something wrong or is this truly a bug? Is there a workaround?

Using reflection on VB6 Collections

Postby tschulken » Sun, 02 Mar 2008 12:11:00 GMT

I am working on a conversion project from VB6 -> .Net. The first pass
is to just convert over w/o restructuring any of the classes. For
testing of the business object classes, I am writing a .Net utlility
to instantiate the VB6 objects, use reflection on them to get their
property values. I will then do the same against the converted .Net
classes to ensure all results are the same.

It seems I have no problems going down a object heirarchy unless the
property is of type collection. If the property is another object, no
problem.

When I run into a collection class, I cast like this (note: prop is of
type PropertyInfo):
Dim aList As VBA.Collection = CType(prop.GetValue(Source, Nothing),
VBA.Collection)

I then try and iterate through the collection using reflection but all
it says
        For Each item In aList
             Dim aType As Type = CType(item , Object).GetType
             Dim aPropInfo() As PropertyInfo = aType.GetProperties
        Next

When I get the type info from the item in the collection, all it says
is: {System.__ComObject} and has no additional information for me to
use.

Is there a way to get the information from a VBA Collection class
using reflection?

Tim

Re: Using reflection on VB6 Collections

Postby Jeroen Mostert » Sun, 02 Mar 2008 19:29:03 GMT


__ComObject is a proxy wrapping around the actual class. In order to do 
anything meaningful with the object, you must cast it to a specific type 
(not Object), which will retrieve the proper interface in the background. 
See  http://www.**--****.com/ 

However, you don't know an actual type in this case. There is a helper 
method that will retrieve an actual type by going through IDispatch, 
Microsoft.VisualBasic.Information.TypeName(). You could use that to 
dynamically cast, like this:

Dim typeName As String = Information.TypeName(item)
CType(item, Type.GetType(typeName))

Disclaimer: I have no idea if this actually works and I can't test it. It 
will at least require that all VB6 types you encounter have been imported 
into .NET.

-- 
J.



Re: Using reflection on VB6 Collections

Postby tschulken » Wed, 05 Mar 2008 14:26:16 GMT

Thanks for the reply, in theory that looked like it would work
unfortunatly it seems that the GetType does not work off of COM
objects. I was wondering if anyone else knew of a way to get the Type
information of an COM object using a prog id.

I did try using:
Dim comProgType As Type =
Type.GetTypeFromProgID("ComCollectionTest.Person")

My comProgType object ends up being "FullName = "System.__ComObject".
Even though I have a reference to ComCollectionTest.Person and can
early bind to it.

Any help would be appreciated.

Tim



Re: Using reflection on VB6 Collections

Postby Willy Denoyette [MVP] » Wed, 05 Mar 2008 17:49:20 GMT





System.__ComObject is a generic wrapper, that means a RCW that does not 
carry any metadata other than it's own.
The reason for this is simple, by calling Type.GetTypeFromProgID, you are 
ignoring the imported metadata from the interop assembly, in order to get at 
the type info you will have to cast the generic wrapper to the type 
ComCollectionTest.Person.

Willy.


Re: Using reflection on VB6 Collections

Postby tschulken » Thu, 06 Mar 2008 04:54:34 GMT

On Mar 4, 3:49燼m, "Willy Denoyette [MVP]"






Thanks Willy. The problem is when i am using reflection, when I run
into the VBA.Collections I don't get the type information for the
items inside. I can get a string representation of the type name
(Information.TypeName). I was wondering if I could get the type info
using that string typename. I am writing a utility to get all of the
property values of my COM objects. When I run into objects inside the
collection, I can't get the type info to get the properties, to get
their values.

I have the references to the com dll's but there are a ton of classes
that I wanted to do all of this dynamically.

Any additional hlep would be appreciated (i.e. is there another way to
get the property values when I don't have the type info?)

Tim


Similar Threads:

1.Using reflection on collections w/in objects

Hello,

I have a generic subroutine that I pass an object and 
fieldname as arguments.  The subroutine then uses 
reflection to search for the value of the fieldname.

For example:

'Calling the Sub
GetObjectValue(objMyCustomer, "Address.Zip")

'The definition of the Sub
Public Shared GetObjectValue(MyObj as Object, FieldName As 
String)

Dim Field As FieldInfo
Dim colObject As Object


If FieldName.IndexOf(".") > 0 Then
   Do While strTemp.IndexOf(".") > 0
      Field = colObject.GetType.GetField(Left(strTemp, _
strTemp.IndexOf(".")))
      If Field Is Nothing Then Return Nothing
      strTemp = Mid(strTemp, strTemp.IndexOf(".") + 2, _
Len(strTemp) - strTemp.IndexOf("."))
      colObject = Field.GetValue(colObject)
   Loop

'A bunch of other junk goes here

End Sub

The logic works, there's a problem when what you're trying 
to look for is in a collection.  For instance, if I have 
collection of Addresses, like home address, mailing 
address, work address, etc.

I want to get the Zip code of, say, the work address.  
When I call it, GetType.GetField successfully assigns 
Field as a {System.Reflection.RuntimeFieldInfo}.  I don't 
see a way to test for Field (actually Address) being a 
collection.  Try to do a Ctype and then test for not 
returning that particular error code?  

I'd then like loop through my collection and return the  
zip code for a particular element, like Address(1).Zip.

The reason I'm going to all this trouble is that I want 
the piece that calls GetObjectValue not to have to know 
what the type of object that it's working with.  I just 
give him an object and he parses through it looking for 
fields in an XML document that is passed to him as well.

-Eric

2.How can i get the Property value using Reflection (Return type: Collection of controls)

i want to get the property value using reflection.

Scenerio:
  i have a status bar on MDI form. it has property named "Panels" and i want 
to get a specific panel from that
panels collection using reflection.
    Please let me know.

Thanks
C# Developer
Mudassar 


3.Datagrid columns using AutoGenerate via the autoGenColumnsArray private member array collection (reflection)

I have seen several people looking for a way to access the Columns
collection when using the AutoGenerate = true option.  Some
people have gotten so far as to find the private autoGenColumnsArray
that has the information, but we as developers have no way to access
this information.

I have come up with a solution for the problem, (as I am sure many
others have) using reflection.  Here is some sample code that will
print out the auto generated column names from a datagrid.

As stated, this code uses reflection. Reflection is slow. It might not
also be allowed depending on your system's security settings. Also, if
MS changes the internal structure of the DataGrid, this might break.
(We are breaking encapsulation)
 
Provided, is a function that will generically allow you to get the
value of any private member of a class using reflection.

  Sorry about the formatting, I dont know a good way to format code for
  usenet. Visual Studio should clean up the code just find for you tho.
  
  <code>
  DataGrid dg = new DataGrid();
  dg.DataSource =new DataTable();// (Run some query or whatnot here)
  dg.DataBind
  
  ArrayList AutoGeneratedColumns 
    = (ArrayList) GetPrivateField(dg,"autoGenColumnsArray") ;
  
  if (AutoGeneratedColumns!= null)
   foreach (DataGridColumn CurrentColumn in AutoGeneratedColumns)
    {
     Response.Write(CurrentColumn.HeaderText);
    }
  
  
  public static object GetPrivateField(object PassedObject, string
  FieldName)
  {
  
  object Field=null;
  
  if (PassedObject == null)
   throw new ArgumentNullException("PassedObject"
     ,"PassedObject must be an instantiated object.");
  
  if (FieldName == null || FieldName.Trim() == "")
   throw new ArgumentOutOfRangeException("FieldName"
    ,"Fieldname must be a non empty string."); 
  		
  Type ObjectType = PassedObject.GetType();
  System.Reflection.FieldInfo PrivateField =
  ObjectType.GetField(FieldName
  ,System.Reflection.BindingFlags.Instance 
  | System.Reflection.BindingFlags.NonPublic 
  | System.Reflection.BindingFlags.Public 
  | System.Reflection.BindingFlags.IgnoreCase);
  
  if (PrivateField == null)
   throw new ArgumentOutOfRangeException("FieldName"
  , ObjectType.FullName + " does not have a field : " + FieldName +
  ".");
  
  Field =  PrivateField.GetValue(PassedObject);
  return Field;
  }
  </code>

4.Confused about using Reflection to examine a collection

5.Using Reflection with a collection class - syntax question

Hi,

I hope this is the right forum for this question.

I am trying to use reflection for several custom collection classes. For 
example, what I want to do is take a line of code like this:

    myCollection.Add(mySecondCollection.Item(i))

and rewrite it using reflection. 

So far, I have something like

object myObject = new object();
object mySecondObject = new object();
myObject = myCollection;
mySecondObject = mySecondCollection;

myCollection.GetType().GetMethod("Add").Invoke(....

After the invoke is where I am confused about the syntax to use to represent 
the second collection, and to represent the .Item syntax (.Item is a custom 
method that returns an object in the collection and takes the collection 
index as an argument).

I have read the documentation for .GetMethod, .Invoke, etc. and don't 
understand what I'm supposed to do in this case.

Any help would be greatly appreciated.

Thanks!







-- 
E. Connolly

6. Using reflection on collections w/in objects

7. Inheriting VB6 dll classes/collections into dotnet classes/collections

8. Setting a VB6 Collection to a .NET Collection



Return to dotnet framework

 

Who is online

Users browsing this forum: No registered users and 71 guest