By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,610 Members | 2,110 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,610 IT Pros & Developers. It's quick & easy.

reflection, base class private properties, etc.

P: n/a
Hi,
I have an old problem which I couldn't solve so far. Now I have found a post
in that group that gave me an idea, but I can not fully understand it.
The problem is: I'm trying to use a Windows.Forms.UserControl in a COM
environment, i.e. I want to host that control in a COM host. So far, so
good, I can host it, but I can not reach the parent COM object from the
control (Parent property is null :( ).
I have stopped the control in the debugger and I found in the watch window
some properties, like ActiveXInstance
{System.Windows.Forms.Control.ActiveXImpl}
The problem is that they are private to the base class, so I can not access
them.

Now the question: is it possible somehow to access these base properties
programmatically. I have found a post which mentions something about
reflection (whatever that mean). Can I use a reflection to access these
properties?

Any help will be highly appreciated.

Thanks
Sunny
Nov 15 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Hi Sunny,
I think that yes, it's possible to access the private properties of a class
using reflection, I haven't tested it but I also saw the post of Nicholas
and until now all that he said is true ;) , the thing is ( also stated in
the post ) what are you planning to do with it? it;s a private property and
you have no idea of how it's used or what it means.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Sunny" <su******@icebergwireless.com> wrote in message
news:uO*************@tk2msftngp13.phx.gbl...
Hi,
I have an old problem which I couldn't solve so far. Now I have found a post in that group that gave me an idea, but I can not fully understand it.
The problem is: I'm trying to use a Windows.Forms.UserControl in a COM
environment, i.e. I want to host that control in a COM host. So far, so
good, I can host it, but I can not reach the parent COM object from the
control (Parent property is null :( ).
I have stopped the control in the debugger and I found in the watch window
some properties, like ActiveXInstance
{System.Windows.Forms.Control.ActiveXImpl}
The problem is that they are private to the base class, so I can not access them.

Now the question: is it possible somehow to access these base properties
programmatically. I have found a post which mentions something about
reflection (whatever that mean). Can I use a reflection to access these
properties?

Any help will be highly appreciated.

Thanks
Sunny

Nov 15 '05 #2

P: n/a
Hi, it seems that I have to guess what property to get, so I'll play with
all of them, but that happen always with combination COM/.Net/Outlook :)
The problem is, that I have read some of docs for reflection, and I still
have no idea where to start and how to access these private members :(
So any example will be helpful.

Sunny

"Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message
news:ul****************@TK2MSFTNGP12.phx.gbl...
Hi Sunny,
I think that yes, it's possible to access the private properties of a class using reflection, I haven't tested it but I also saw the post of Nicholas
and until now all that he said is true ;) , the thing is ( also stated in
the post ) what are you planning to do with it? it;s a private property and you have no idea of how it's used or what it means.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Sunny" <su******@icebergwireless.com> wrote in message
news:uO*************@tk2msftngp13.phx.gbl...
Hi,
I have an old problem which I couldn't solve so far. Now I have found a

post
in that group that gave me an idea, but I can not fully understand it.
The problem is: I'm trying to use a Windows.Forms.UserControl in a COM
environment, i.e. I want to host that control in a COM host. So far, so
good, I can host it, but I can not reach the parent COM object from the
control (Parent property is null :( ).
I have stopped the control in the debugger and I found in the watch window some properties, like ActiveXInstance
{System.Windows.Forms.Control.ActiveXImpl}
The problem is that they are private to the base class, so I can not

access
them.

Now the question: is it possible somehow to access these base properties
programmatically. I have found a post which mentions something about
reflection (whatever that mean). Can I use a reflection to access these
properties?

Any help will be highly appreciated.

Thanks
Sunny


Nov 15 '05 #3

P: n/a
Here is a sample code (in VB but it shouldn't not be difficult to translate
it) I used to get UserMode property:

Dim strAssembly As String
strAssembly =
Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll",
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly = Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
Dim unmt As Type = _
Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly,
"System.Windows.Forms.UnsafeNativeMethods"))
Dim ioot As Type = unmt.GetNestedType("IOleObject")
Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
Dim site As Object = mi.Invoke(Me, Nothing)
If site Is Nothing Then Return -1

' We are hosted by a COM container

Dim dsite As IDispatch = site

' All the uninitialized arguments work fine in this case
Dim id As Guid
Dim params As DISPPARAMS
Dim lcid As System.UInt32
Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
Dim result As Object
dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing, Nothing)

If result Then
Return 1
Else
Return 0
End If

That should give you an idea how to do what you want. IIRC IOleClientSite
has method GetContainer() which I think you need (not the parent COM
object). BTW You can use ildasm on System.Windows.Forms.dll to make yourself
familiar with the internal classes and implementations.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:ui**************@tk2msftngp13.phx.gbl...
Hi, it seems that I have to guess what property to get, so I'll play with
all of them, but that happen always with combination COM/.Net/Outlook :)
The problem is, that I have read some of docs for reflection, and I still
have no idea where to start and how to access these private members :(
So any example will be helpful.

Sunny

"Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message
news:ul****************@TK2MSFTNGP12.phx.gbl...
Hi Sunny,
I think that yes, it's possible to access the private properties of a

class
using reflection, I haven't tested it but I also saw the post of Nicholas
and until now all that he said is true ;) , the thing is ( also stated in the post ) what are you planning to do with it? it;s a private property

and
you have no idea of how it's used or what it means.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Sunny" <su******@icebergwireless.com> wrote in message
news:uO*************@tk2msftngp13.phx.gbl...
Hi,
I have an old problem which I couldn't solve so far. Now I have found a
post
in that group that gave me an idea, but I can not fully understand it.
The problem is: I'm trying to use a Windows.Forms.UserControl in a COM
environment, i.e. I want to host that control in a COM host. So far,

so good, I can host it, but I can not reach the parent COM object from the control (Parent property is null :( ).
I have stopped the control in the debugger and I found in the watch

window some properties, like ActiveXInstance
{System.Windows.Forms.Control.ActiveXImpl}
The problem is that they are private to the base class, so I can not

access
them.

Now the question: is it possible somehow to access these base properties programmatically. I have found a post which mentions something about
reflection (whatever that mean). Can I use a reflection to access these properties?

Any help will be highly appreciated.

Thanks
Sunny



Nov 15 '05 #4

P: n/a
Thank you Vladimir, I'll see what will happen with this and let you know.
Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in
message news:O9**************@TK2MSFTNGP09.phx.gbl...
Here is a sample code (in VB but it shouldn't not be difficult to translate it) I used to get UserMode property:

Dim strAssembly As String
strAssembly =
Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll",
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly = Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName Dim unmt As Type = _
Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly,
"System.Windows.Forms.UnsafeNativeMethods"))
Dim ioot As Type = unmt.GetNestedType("IOleObject")
Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
Dim site As Object = mi.Invoke(Me, Nothing)
If site Is Nothing Then Return -1

' We are hosted by a COM container

Dim dsite As IDispatch = site

' All the uninitialized arguments work fine in this case
Dim id As Guid
Dim params As DISPPARAMS
Dim lcid As System.UInt32
Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
Dim result As Object
dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing, Nothing)

If result Then
Return 1
Else
Return 0
End If

That should give you an idea how to do what you want. IIRC IOleClientSite
has method GetContainer() which I think you need (not the parent COM
object). BTW You can use ildasm on System.Windows.Forms.dll to make yourself familiar with the internal classes and implementations.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:ui**************@tk2msftngp13.phx.gbl...
Hi, it seems that I have to guess what property to get, so I'll play with
all of them, but that happen always with combination COM/.Net/Outlook :)
The problem is, that I have read some of docs for reflection, and I still have no idea where to start and how to access these private members :(
So any example will be helpful.

Sunny

"Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message
news:ul****************@TK2MSFTNGP12.phx.gbl...
Hi Sunny,
I think that yes, it's possible to access the private properties of a class
using reflection, I haven't tested it but I also saw the post of Nicholas and until now all that he said is true ;) , the thing is ( also stated in the post ) what are you planning to do with it? it;s a private property and
you have no idea of how it's used or what it means.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Sunny" <su******@icebergwireless.com> wrote in message
news:uO*************@tk2msftngp13.phx.gbl...
> Hi,
> I have an old problem which I couldn't solve so far. Now I have
found a post
> in that group that gave me an idea, but I can not fully understand
it. > The problem is: I'm trying to use a Windows.Forms.UserControl in a COM > environment, i.e. I want to host that control in a COM host. So far,

so > good, I can host it, but I can not reach the parent COM object from the > control (Parent property is null :( ).
> I have stopped the control in the debugger and I found in the watch

window
> some properties, like ActiveXInstance
> {System.Windows.Forms.Control.ActiveXImpl}
> The problem is that they are private to the base class, so I can not
access
> them.
>
> Now the question: is it possible somehow to access these base properties > programmatically. I have found a post which mentions something about
> reflection (whatever that mean). Can I use a reflection to access these > properties?
>
> Any help will be highly appreciated.
>
> Thanks
> Sunny
>
>



Nov 15 '05 #5

P: n/a
Hi Vladimir,
IT WORKS IT WORKS. You are great. I have implemented this in C# and it gave
me the reference I needed. I suppose, that I had to implement all of your
code, but I stopped at the check for site is Nothing, because I can cast it
at the type I want. So, I do not know what the rest of the code have to do.
If you have a little time, pls, explain. Nevertheless so far, you are the
only guy around who have succeeded to solve that problem. I have posted it
allover, with different ideas, but ... nothing.

Thank you again
Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in
message news:O9**************@TK2MSFTNGP09.phx.gbl...
Here is a sample code (in VB but it shouldn't not be difficult to translate it) I used to get UserMode property:

Dim strAssembly As String
strAssembly =
Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll",
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly = Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName Dim unmt As Type = _
Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly,
"System.Windows.Forms.UnsafeNativeMethods"))
Dim ioot As Type = unmt.GetNestedType("IOleObject")
Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
Dim site As Object = mi.Invoke(Me, Nothing)
If site Is Nothing Then Return -1

' We are hosted by a COM container

Dim dsite As IDispatch = site

' All the uninitialized arguments work fine in this case
Dim id As Guid
Dim params As DISPPARAMS
Dim lcid As System.UInt32
Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
Dim result As Object
dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing, Nothing)

If result Then
Return 1
Else
Return 0
End If

That should give you an idea how to do what you want. IIRC IOleClientSite
has method GetContainer() which I think you need (not the parent COM
object). BTW You can use ildasm on System.Windows.Forms.dll to make yourself familiar with the internal classes and implementations.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:ui**************@tk2msftngp13.phx.gbl...
Hi, it seems that I have to guess what property to get, so I'll play with
all of them, but that happen always with combination COM/.Net/Outlook :)
The problem is, that I have read some of docs for reflection, and I still have no idea where to start and how to access these private members :(
So any example will be helpful.

Sunny

"Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message
news:ul****************@TK2MSFTNGP12.phx.gbl...
Hi Sunny,
I think that yes, it's possible to access the private properties of a class
using reflection, I haven't tested it but I also saw the post of Nicholas and until now all that he said is true ;) , the thing is ( also stated in the post ) what are you planning to do with it? it;s a private property and
you have no idea of how it's used or what it means.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Sunny" <su******@icebergwireless.com> wrote in message
news:uO*************@tk2msftngp13.phx.gbl...
> Hi,
> I have an old problem which I couldn't solve so far. Now I have
found a post
> in that group that gave me an idea, but I can not fully understand
it. > The problem is: I'm trying to use a Windows.Forms.UserControl in a COM > environment, i.e. I want to host that control in a COM host. So far,

so > good, I can host it, but I can not reach the parent COM object from the > control (Parent property is null :( ).
> I have stopped the control in the debugger and I found in the watch

window
> some properties, like ActiveXInstance
> {System.Windows.Forms.Control.ActiveXImpl}
> The problem is that they are private to the base class, so I can not
access
> them.
>
> Now the question: is it possible somehow to access these base properties > programmatically. I have found a post which mentions something about
> reflection (whatever that mean). Can I use a reflection to access these > properties?
>
> Any help will be highly appreciated.
>
> Thanks
> Sunny
>
>



Nov 15 '05 #6

P: n/a
For a some reason my post didn't come through, so I repeat:

Hi Sunny,

I'm glad that was a help.
I was trying to solve a similar problem and the code was a part of the
solution. I don't think I can convert site to IOleClientSite because the
type is not accessible in compile time - it's defined in a private nested
class. Also for a some reason late binding didn't work for the object
(probably because it's a COM object). So I ComImport-ed IDispatch (couldn't
find anything predefined) and called Invoke() to get UserMode ambient
property. I found a (relatively) simpler way of detecting UserMode:

Dim strAssembly As String
strAssembly = Type.GetType("System.Object").Assembly.CodeBase
strAssembly = strAssembly.Replace("mscorlib.dll", _
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly = Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
Dim qualifiedControlTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control")
Dim ct As Type = Type.GetType(qualifiedControlTypeName)
Dim bf As Reflection.BindingFlags = _
Reflection.BindingFlags.IgnoreCase Or _
Reflection.BindingFlags.NonPublic Or _
Reflection.BindingFlags.Public Or _
Reflection.BindingFlags.Static Or _
Reflection.BindingFlags.Instance
Dim pi() As Reflection.PropertyInfo = ct.GetProperties(bf)
Dim axipi As Reflection.PropertyInfo = getMemberByName(pi, _
"ActiveXInstance")
Dim axi As Object = axipi.GetValue(Me, Nothing)
Dim site As Object = axi.GetClientSite()
If site Is Nothing Then Return -1

Dim qualifiedActiveXImplTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control+ActiveXImpl")
Dim axit As Type = Type.GetType(qualifiedActiveXImplTypeName)
pi = axit.GetProperties(bf)
Dim dmpi As Reflection.PropertyInfo = getMemberByName(pi, "DesignMode")
Dim ret As Boolean = dmpi.GetValue(axi, Nothing)
If ret Then Return 1
Return 0

getMemberByName() is function that goes through all array elements and finds
the one with the given name. Note that I had to use "Control+ActiveXImpl"
type name - GetNestedType() didn't work (any ideas why?). Note that late
binding (GetClientSite()) works fine now. Note that DesignMode property
actually stores UserMode so it's false in design time.

For a some reason .Net control's properties don't persist in COM containers.
I'm trying now to figure out why. If you have any thought about that I'd
appreciate any input.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:O0**************@TK2MSFTNGP10.phx.gbl...
Hi Vladimir,
IT WORKS IT WORKS. You are great. I have implemented this in C# and it gave me the reference I needed. I suppose, that I had to implement all of your
code, but I stopped at the check for site is Nothing, because I can cast it at the type I want. So, I do not know what the rest of the code have to do. If you have a little time, pls, explain. Nevertheless so far, you are the
only guy around who have succeeded to solve that problem. I have posted it
allover, with different ideas, but ... nothing.

Thank you again
Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in
message news:O9**************@TK2MSFTNGP09.phx.gbl...
Here is a sample code (in VB but it shouldn't not be difficult to

translate
it) I used to get UserMode property:

Dim strAssembly As String
strAssembly =
Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll",
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly =

Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
Dim unmt As Type = _
Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly,
"System.Windows.Forms.UnsafeNativeMethods"))
Dim ioot As Type = unmt.GetNestedType("IOleObject")
Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
Dim site As Object = mi.Invoke(Me, Nothing)
If site Is Nothing Then Return -1

' We are hosted by a COM container

Dim dsite As IDispatch = site

' All the uninitialized arguments work fine in this case
Dim id As Guid
Dim params As DISPPARAMS
Dim lcid As System.UInt32
Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
Dim result As Object
dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing, Nothing)

If result Then
Return 1
Else
Return 0
End If

That should give you an idea how to do what you want. IIRC IOleClientSite
has method GetContainer() which I think you need (not the parent COM
object). BTW You can use ildasm on System.Windows.Forms.dll to make

yourself
familiar with the internal classes and implementations.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:ui**************@tk2msftngp13.phx.gbl...
Hi, it seems that I have to guess what property to get, so I'll play with all of them, but that happen always with combination COM/.Net/Outlook :) The problem is, that I have read some of docs for reflection, and I still have no idea where to start and how to access these private members :(
So any example will be helpful.

Sunny

"Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message
news:ul****************@TK2MSFTNGP12.phx.gbl...
> Hi Sunny,
>
>
> I think that yes, it's possible to access the private properties of a class
> using reflection, I haven't tested it but I also saw the post of

Nicholas
> and until now all that he said is true ;) , the thing is ( also stated in
> the post ) what are you planning to do with it? it;s a private property and
> you have no idea of how it's used or what it means.
>
> Cheers,
>
> --
> Ignacio Machin,
> ignacio.machin AT dot.state.fl.us
> Florida Department Of Transportation
>
> "Sunny" <su******@icebergwireless.com> wrote in message
> news:uO*************@tk2msftngp13.phx.gbl...
> > Hi,
> > I have an old problem which I couldn't solve so far. Now I have found
a
> post
> > in that group that gave me an idea, but I can not fully understand it. > > The problem is: I'm trying to use a Windows.Forms.UserControl in a COM > > environment, i.e. I want to host that control in a COM host. So

far, so
> > good, I can host it, but I can not reach the parent COM object
from the
> > control (Parent property is null :( ).
> > I have stopped the control in the debugger and I found in the

watch window
> > some properties, like ActiveXInstance
> > {System.Windows.Forms.Control.ActiveXImpl}
> > The problem is that they are private to the base class, so I can not > access
> > them.
> >
> > Now the question: is it possible somehow to access these base

properties
> > programmatically. I have found a post which mentions something about > > reflection (whatever that mean). Can I use a reflection to access

these
> > properties?
> >
> > Any help will be highly appreciated.
> >
> > Thanks
> > Sunny
> >
> >
>
>



Nov 15 '05 #7

P: n/a
Hi Vladimir,
my problem was not so complicated, but what I learned so far is, that to
expose your .Net property, you have to implement/reimplement it in your
component, and most probably to set a corresponding DispID.
The container I targeted (Outlook PropertyPage) needed one Property (bool
Dirty) and 2 methods (void Apply() and void GetPageInfo(ref string HelpFile,
ref int HelpContext)) so I had to implement them. And there was one
undocumented property string Caption for which I had to supply DispID to be
recognized:

[DispId(-518)]
public string Caption
{
get
{return this.Name;}
}
So maybe you have to reimplement some of the properties you want to expose
with a corresponding DispID, expected by the host.

All this stuff is new for me, so I'm just guessing, but maybe it should
work. The COM host should use these DispIDs, else what for are they :)

I'm sure that if I remove the DispID part of the declaration of Caption
property, the host didn't find it. Also I just checked, that if you supply
the correct DispID (in my case -518, which I found somewhere that means
Caption) you can change the name of your property to whatever you want. I
have renamed that property to Capsss, and the host still founds it.

Maybe you have to find what DispID's host is expecting, and just to make a
new properties with that DispID, which supplies the necessary values.

Please, let me know what happened.

Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in
message news:%2****************@TK2MSFTNGP12.phx.gbl...
For a some reason my post didn't come through, so I repeat:

Hi Sunny,

I'm glad that was a help.
I was trying to solve a similar problem and the code was a part of the
solution. I don't think I can convert site to IOleClientSite because the
type is not accessible in compile time - it's defined in a private nested
class. Also for a some reason late binding didn't work for the object
(probably because it's a COM object). So I ComImport-ed IDispatch (couldn't find anything predefined) and called Invoke() to get UserMode ambient
property. I found a (relatively) simpler way of detecting UserMode:

Dim strAssembly As String
strAssembly = Type.GetType("System.Object").Assembly.CodeBase
strAssembly = strAssembly.Replace("mscorlib.dll", _
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly = Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName Dim qualifiedControlTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control")
Dim ct As Type = Type.GetType(qualifiedControlTypeName)
Dim bf As Reflection.BindingFlags = _
Reflection.BindingFlags.IgnoreCase Or _
Reflection.BindingFlags.NonPublic Or _
Reflection.BindingFlags.Public Or _
Reflection.BindingFlags.Static Or _
Reflection.BindingFlags.Instance
Dim pi() As Reflection.PropertyInfo = ct.GetProperties(bf)
Dim axipi As Reflection.PropertyInfo = getMemberByName(pi, _
"ActiveXInstance")
Dim axi As Object = axipi.GetValue(Me, Nothing)
Dim site As Object = axi.GetClientSite()
If site Is Nothing Then Return -1

Dim qualifiedActiveXImplTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control+ActiveXImpl")
Dim axit As Type = Type.GetType(qualifiedActiveXImplTypeName)
pi = axit.GetProperties(bf)
Dim dmpi As Reflection.PropertyInfo = getMemberByName(pi, "DesignMode")
Dim ret As Boolean = dmpi.GetValue(axi, Nothing)
If ret Then Return 1
Return 0

getMemberByName() is function that goes through all array elements and finds the one with the given name. Note that I had to use "Control+ActiveXImpl"
type name - GetNestedType() didn't work (any ideas why?). Note that late
binding (GetClientSite()) works fine now. Note that DesignMode property
actually stores UserMode so it's false in design time.

For a some reason .Net control's properties don't persist in COM containers. I'm trying now to figure out why. If you have any thought about that I'd
appreciate any input.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:O0**************@TK2MSFTNGP10.phx.gbl...
Hi Vladimir,
IT WORKS IT WORKS. You are great. I have implemented this in C# and it gave
me the reference I needed. I suppose, that I had to implement all of your
code, but I stopped at the check for site is Nothing, because I can cast

it
at the type I want. So, I do not know what the rest of the code have to

do.
If you have a little time, pls, explain. Nevertheless so far, you are the only guy around who have succeeded to solve that problem. I have posted it allover, with different ideas, but ... nothing.

Thank you again
Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in message news:O9**************@TK2MSFTNGP09.phx.gbl...
Here is a sample code (in VB but it shouldn't not be difficult to

translate
it) I used to get UserMode property:

Dim strAssembly As String
strAssembly =
Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll", "System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly =

Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
Dim unmt As Type = _
Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly,
"System.Windows.Forms.UnsafeNativeMethods"))
Dim ioot As Type = unmt.GetNestedType("IOleObject")
Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
Dim site As Object = mi.Invoke(Me, Nothing)
If site Is Nothing Then Return -1

' We are hosted by a COM container

Dim dsite As IDispatch = site

' All the uninitialized arguments work fine in this case
Dim id As Guid
Dim params As DISPPARAMS
Dim lcid As System.UInt32
Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
Dim result As Object
dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing, Nothing)

If result Then
Return 1
Else
Return 0
End If

That should give you an idea how to do what you want. IIRC IOleClientSite has method GetContainer() which I think you need (not the parent COM
object). BTW You can use ildasm on System.Windows.Forms.dll to make

yourself
familiar with the internal classes and implementations.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:ui**************@tk2msftngp13.phx.gbl...
> Hi, it seems that I have to guess what property to get, so I'll play

with
> all of them, but that happen always with combination COM/.Net/Outlook :)
> The problem is, that I have read some of docs for reflection, and I still
> have no idea where to start and how to access these private members
:( > So any example will be helpful.
>
> Sunny
>
> "Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message > news:ul****************@TK2MSFTNGP12.phx.gbl...
> > Hi Sunny,
> >
> >
> > I think that yes, it's possible to access the private properties of a > class
> > using reflection, I haven't tested it but I also saw the post of
Nicholas
> > and until now all that he said is true ;) , the thing is ( also stated in
> > the post ) what are you planning to do with it? it;s a private

property
> and
> > you have no idea of how it's used or what it means.
> >
> > Cheers,
> >
> > --
> > Ignacio Machin,
> > ignacio.machin AT dot.state.fl.us
> > Florida Department Of Transportation
> >
> > "Sunny" <su******@icebergwireless.com> wrote in message
> > news:uO*************@tk2msftngp13.phx.gbl...
> > > Hi,
> > > I have an old problem which I couldn't solve so far. Now I have

found
a
> > post
> > > in that group that gave me an idea, but I can not fully
understand it.
> > > The problem is: I'm trying to use a Windows.Forms.UserControl in
a COM
> > > environment, i.e. I want to host that control in a COM host. So

far, so
> > > good, I can host it, but I can not reach the parent COM object from the
> > > control (Parent property is null :( ).
> > > I have stopped the control in the debugger and I found in the watch > window
> > > some properties, like ActiveXInstance
> > > {System.Windows.Forms.Control.ActiveXImpl}
> > > The problem is that they are private to the base class, so I can not > > access
> > > them.
> > >
> > > Now the question: is it possible somehow to access these base
properties
> > > programmatically. I have found a post which mentions something about > > > reflection (whatever that mean). Can I use a reflection to

access these
> > > properties?
> > >
> > > Any help will be highly appreciated.
> > >
> > > Thanks
> > > Sunny
> > >
> > >
> >
> >
>
>



Nov 15 '05 #8

P: n/a
Hi Sunny,

Thanks for the feedback.

Caption is a standard OLE control property. There are not many mentions of
it in the MSDN documentation, especially together with it's numeric value.
I'm pretty sure though it described in OLE 2.0 Programmer's Reference. Also
you can inspect olectl.h - a C header file that comes with VC - to find more
standard properties definitions, they start with DISPID_.

I actually have three problems: (a) Word doesn't persist _my_ properties - I
have a few properties, I can set them from Word programmatically but after
the document has been closed and loaded again the properties' values are
lost; (b) Word doesn't show my object in the drop-down box where the
document object and all other objects are (in the Properties window), I can
select my object and open the Properties window but the drop-down box is
empty (it should show the object's name and type) and; (c) Word doesn't show
my properties in it.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:#L**************@tk2msftngp13.phx.gbl...
Hi Vladimir,
my problem was not so complicated, but what I learned so far is, that to
expose your .Net property, you have to implement/reimplement it in your
component, and most probably to set a corresponding DispID.
The container I targeted (Outlook PropertyPage) needed one Property (bool
Dirty) and 2 methods (void Apply() and void GetPageInfo(ref string HelpFile, ref int HelpContext)) so I had to implement them. And there was one
undocumented property string Caption for which I had to supply DispID to be recognized:

[DispId(-518)]
public string Caption
{
get
{return this.Name;}
}
So maybe you have to reimplement some of the properties you want to expose
with a corresponding DispID, expected by the host.

All this stuff is new for me, so I'm just guessing, but maybe it should
work. The COM host should use these DispIDs, else what for are they :)

I'm sure that if I remove the DispID part of the declaration of Caption
property, the host didn't find it. Also I just checked, that if you supply
the correct DispID (in my case -518, which I found somewhere that means
Caption) you can change the name of your property to whatever you want. I
have renamed that property to Capsss, and the host still founds it.

Maybe you have to find what DispID's host is expecting, and just to make a
new properties with that DispID, which supplies the necessary values.

Please, let me know what happened.

Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in
message news:%2****************@TK2MSFTNGP12.phx.gbl...
For a some reason my post didn't come through, so I repeat:

Hi Sunny,

I'm glad that was a help.
I was trying to solve a similar problem and the code was a part of the
solution. I don't think I can convert site to IOleClientSite because the
type is not accessible in compile time - it's defined in a private nested
class. Also for a some reason late binding didn't work for the object
(probably because it's a COM object). So I ComImport-ed IDispatch (couldn't
find anything predefined) and called Invoke() to get UserMode ambient
property. I found a (relatively) simpler way of detecting UserMode:

Dim strAssembly As String
strAssembly = Type.GetType("System.Object").Assembly.CodeBase
strAssembly = strAssembly.Replace("mscorlib.dll", _
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly =

Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
Dim qualifiedControlTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control")
Dim ct As Type = Type.GetType(qualifiedControlTypeName)
Dim bf As Reflection.BindingFlags = _
Reflection.BindingFlags.IgnoreCase Or _
Reflection.BindingFlags.NonPublic Or _
Reflection.BindingFlags.Public Or _
Reflection.BindingFlags.Static Or _
Reflection.BindingFlags.Instance
Dim pi() As Reflection.PropertyInfo = ct.GetProperties(bf)
Dim axipi As Reflection.PropertyInfo = getMemberByName(pi, _
"ActiveXInstance")
Dim axi As Object = axipi.GetValue(Me, Nothing)
Dim site As Object = axi.GetClientSite()
If site Is Nothing Then Return -1

Dim qualifiedActiveXImplTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control+ActiveXImpl")
Dim axit As Type = Type.GetType(qualifiedActiveXImplTypeName)
pi = axit.GetProperties(bf)
Dim dmpi As Reflection.PropertyInfo = getMemberByName(pi, "DesignMode")
Dim ret As Boolean = dmpi.GetValue(axi, Nothing)
If ret Then Return 1
Return 0

getMemberByName() is function that goes through all array elements and

finds
the one with the given name. Note that I had to use "Control+ActiveXImpl" type name - GetNestedType() didn't work (any ideas why?). Note that late
binding (GetClientSite()) works fine now. Note that DesignMode property
actually stores UserMode so it's false in design time.

For a some reason .Net control's properties don't persist in COM

containers.
I'm trying now to figure out why. If you have any thought about that I'd
appreciate any input.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:O0**************@TK2MSFTNGP10.phx.gbl...
Hi Vladimir,
IT WORKS IT WORKS. You are great. I have implemented this in C# and it

gave
me the reference I needed. I suppose, that I had to implement all of your code, but I stopped at the check for site is Nothing, because I can cast it
at the type I want. So, I do not know what the rest of the code have
to
do.
If you have a little time, pls, explain. Nevertheless so far, you are the only guy around who have succeeded to solve that problem. I have
posted it allover, with different ideas, but ... nothing.

Thank you again
Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in message news:O9**************@TK2MSFTNGP09.phx.gbl...
> Here is a sample code (in VB but it shouldn't not be difficult to
translate
> it) I used to get UserMode property:
>
> Dim strAssembly As String
> strAssembly =
> Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll", > "System.Windows.Forms.dll")
> strAssembly = strAssembly.Replace("file:///", String.Empty)
> strAssembly =
Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
> Dim unmt As Type = _
> Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly,
> "System.Windows.Forms.UnsafeNativeMethods"))
> Dim ioot As Type = unmt.GetNestedType("IOleObject")
> Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
> Dim site As Object = mi.Invoke(Me, Nothing)
> If site Is Nothing Then Return -1
>
> ' We are hosted by a COM container
>
> Dim dsite As IDispatch = site
>
> ' All the uninitialized arguments work fine in this case
> Dim id As Guid
> Dim params As DISPPARAMS
> Dim lcid As System.UInt32
> Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
> Dim result As Object
> dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing,
Nothing) >
> If result Then
> Return 1
> Else
> Return 0
> End If
>
> That should give you an idea how to do what you want. IIRC IOleClientSite
> has method GetContainer() which I think you need (not the parent COM
> object). BTW You can use ildasm on System.Windows.Forms.dll to make
yourself
> familiar with the internal classes and implementations.
>
> thanks,
> v
>
> "Sunny" <su******@icebergwireless.com> wrote in message
> news:ui**************@tk2msftngp13.phx.gbl...
> > Hi, it seems that I have to guess what property to get, so I'll play with
> > all of them, but that happen always with combination

COM/.Net/Outlook
:)
> > The problem is, that I have read some of docs for reflection, and I still
> > have no idea where to start and how to access these private members :( > > So any example will be helpful.
> >
> > Sunny
> >
> > "Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message > > news:ul****************@TK2MSFTNGP12.phx.gbl...
> > > Hi Sunny,
> > >
> > >
> > > I think that yes, it's possible to access the private
properties
of
a
> > class
> > > using reflection, I haven't tested it but I also saw the post of
> Nicholas
> > > and until now all that he said is true ;) , the thing is ( also stated
> in
> > > the post ) what are you planning to do with it? it;s a private
property
> > and
> > > you have no idea of how it's used or what it means.
> > >
> > > Cheers,
> > >
> > > --
> > > Ignacio Machin,
> > > ignacio.machin AT dot.state.fl.us
> > > Florida Department Of Transportation
> > >
> > > "Sunny" <su******@icebergwireless.com> wrote in message
> > > news:uO*************@tk2msftngp13.phx.gbl...
> > > > Hi,
> > > > I have an old problem which I couldn't solve so far. Now I

have found
> a
> > > post
> > > > in that group that gave me an idea, but I can not fully

understand it.
> > > > The problem is: I'm trying to use a Windows.Forms.UserControl
in a COM
> > > > environment, i.e. I want to host that control in a COM host.
So far,
> so
> > > > good, I can host it, but I can not reach the parent COM object

from
> the
> > > > control (Parent property is null :( ).
> > > > I have stopped the control in the debugger and I found in the

watch
> > window
> > > > some properties, like ActiveXInstance
> > > > {System.Windows.Forms.Control.ActiveXImpl}
> > > > The problem is that they are private to the base class, so I
can not
> > > access
> > > > them.
> > > >
> > > > Now the question: is it possible somehow to access these base
> properties
> > > > programmatically. I have found a post which mentions something

about
> > > > reflection (whatever that mean). Can I use a reflection to

access > these
> > > > properties?
> > > >
> > > > Any help will be highly appreciated.
> > > >
> > > > Thanks
> > > > Sunny
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 15 '05 #9

P: n/a
Hi Vladimir,
If I understand correctly, you hooking an object and properties to a word
document. I just guess, but maybe there are something like user properties
(in Outlook there are). And after applying them, you gave to invoke Save
method to save them for next opening. Also, for the object, maybe you have
to capture the OpenDocument event (or similar) and there to hook the object
again. And maybe you have to post a new thread in
..office.developer.com.add_ins, or if there is a specific newsgroup for word
addins. Maybe someone there will know more for the word object model.
Sorry that I can not help you more, but I haven't deal with word so far.

Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in
message news:eK**************@tk2msftngp13.phx.gbl...
Hi Sunny,

Thanks for the feedback.

Caption is a standard OLE control property. There are not many mentions of
it in the MSDN documentation, especially together with it's numeric value.
I'm pretty sure though it described in OLE 2.0 Programmer's Reference. Also you can inspect olectl.h - a C header file that comes with VC - to find more standard properties definitions, they start with DISPID_.

I actually have three problems: (a) Word doesn't persist _my_ properties - I have a few properties, I can set them from Word programmatically but after
the document has been closed and loaded again the properties' values are
lost; (b) Word doesn't show my object in the drop-down box where the
document object and all other objects are (in the Properties window), I can select my object and open the Properties window but the drop-down box is
empty (it should show the object's name and type) and; (c) Word doesn't show my properties in it.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:#L**************@tk2msftngp13.phx.gbl...
Hi Vladimir,
my problem was not so complicated, but what I learned so far is, that to
expose your .Net property, you have to implement/reimplement it in your
component, and most probably to set a corresponding DispID.
The container I targeted (Outlook PropertyPage) needed one Property (bool
Dirty) and 2 methods (void Apply() and void GetPageInfo(ref string HelpFile,
ref int HelpContext)) so I had to implement them. And there was one
undocumented property string Caption for which I had to supply DispID to

be
recognized:

[DispId(-518)]
public string Caption
{
get
{return this.Name;}
}
So maybe you have to reimplement some of the properties you want to expose with a corresponding DispID, expected by the host.

All this stuff is new for me, so I'm just guessing, but maybe it should
work. The COM host should use these DispIDs, else what for are they :)

I'm sure that if I remove the DispID part of the declaration of Caption
property, the host didn't find it. Also I just checked, that if you supply the correct DispID (in my case -518, which I found somewhere that means
Caption) you can change the name of your property to whatever you want. I have renamed that property to Capsss, and the host still founds it.

Maybe you have to find what DispID's host is expecting, and just to make a new properties with that DispID, which supplies the necessary values.

Please, let me know what happened.

Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in message news:%2****************@TK2MSFTNGP12.phx.gbl...
For a some reason my post didn't come through, so I repeat:

Hi Sunny,

I'm glad that was a help.
I was trying to solve a similar problem and the code was a part of the
solution. I don't think I can convert site to IOleClientSite because the type is not accessible in compile time - it's defined in a private nested class. Also for a some reason late binding didn't work for the object
(probably because it's a COM object). So I ComImport-ed IDispatch

(couldn't
find anything predefined) and called Invoke() to get UserMode ambient
property. I found a (relatively) simpler way of detecting UserMode:

Dim strAssembly As String
strAssembly = Type.GetType("System.Object").Assembly.CodeBase
strAssembly = strAssembly.Replace("mscorlib.dll", _
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly =

Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
Dim qualifiedControlTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control")
Dim ct As Type = Type.GetType(qualifiedControlTypeName)
Dim bf As Reflection.BindingFlags = _
Reflection.BindingFlags.IgnoreCase Or _
Reflection.BindingFlags.NonPublic Or _
Reflection.BindingFlags.Public Or _
Reflection.BindingFlags.Static Or _
Reflection.BindingFlags.Instance
Dim pi() As Reflection.PropertyInfo = ct.GetProperties(bf)
Dim axipi As Reflection.PropertyInfo = getMemberByName(pi, _
"ActiveXInstance")
Dim axi As Object = axipi.GetValue(Me, Nothing)
Dim site As Object = axi.GetClientSite()
If site Is Nothing Then Return -1

Dim qualifiedActiveXImplTypeName As String = _
Reflection.Assembly.CreateQualifiedName(strAssembl y,
"System.Windows.Forms.Control+ActiveXImpl")
Dim axit As Type = Type.GetType(qualifiedActiveXImplTypeName)
pi = axit.GetProperties(bf)
Dim dmpi As Reflection.PropertyInfo = getMemberByName(pi, "DesignMode") Dim ret As Boolean = dmpi.GetValue(axi, Nothing)
If ret Then Return 1
Return 0

getMemberByName() is function that goes through all array elements and

finds
the one with the given name. Note that I had to use "Control+ActiveXImpl" type name - GetNestedType() didn't work (any ideas why?). Note that late binding (GetClientSite()) works fine now. Note that DesignMode property actually stores UserMode so it's false in design time.

For a some reason .Net control's properties don't persist in COM

containers.
I'm trying now to figure out why. If you have any thought about that I'd appreciate any input.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:O0**************@TK2MSFTNGP10.phx.gbl...
> Hi Vladimir,
> IT WORKS IT WORKS. You are great. I have implemented this in C# and it gave
> me the reference I needed. I suppose, that I had to implement all of

your
> code, but I stopped at the check for site is Nothing, because I can cast it
> at the type I want. So, I do not know what the rest of the code have to do.
> If you have a little time, pls, explain. Nevertheless so far, you are the
> only guy around who have succeeded to solve that problem. I have posted
it
> allover, with different ideas, but ... nothing.
>
> Thank you again
> Sunny
>
> "Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com>
wrote in
> message news:O9**************@TK2MSFTNGP09.phx.gbl...
> > Here is a sample code (in VB but it shouldn't not be difficult to
> translate
> > it) I used to get UserMode property:
> >
> > Dim strAssembly As String
> > strAssembly =
> >

Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll",
> > "System.Windows.Forms.dll")
> > strAssembly = strAssembly.Replace("file:///", String.Empty)
> > strAssembly =
> Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
> > Dim unmt As Type = _
> >

Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly, > > "System.Windows.Forms.UnsafeNativeMethods"))
> > Dim ioot As Type = unmt.GetNestedType("IOleObject")
> > Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
> > Dim site As Object = mi.Invoke(Me, Nothing)
> > If site Is Nothing Then Return -1
> >
> > ' We are hosted by a COM container
> >
> > Dim dsite As IDispatch = site
> >
> > ' All the uninitialized arguments work fine in this case
> > Dim id As Guid
> > Dim params As DISPPARAMS
> > Dim lcid As System.UInt32
> > Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
> > Dim result As Object
> > dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing,

Nothing) > >
> > If result Then
> > Return 1
> > Else
> > Return 0
> > End If
> >
> > That should give you an idea how to do what you want. IIRC
IOleClientSite
> > has method GetContainer() which I think you need (not the parent COM > > object). BTW You can use ildasm on System.Windows.Forms.dll to make > yourself
> > familiar with the internal classes and implementations.
> >
> > thanks,
> > v
> >
> > "Sunny" <su******@icebergwireless.com> wrote in message
> > news:ui**************@tk2msftngp13.phx.gbl...
> > > Hi, it seems that I have to guess what property to get, so I'll play > with
> > > all of them, but that happen always with combination

COM/.Net/Outlook
:)
> > > The problem is, that I have read some of docs for reflection, and I
> still
> > > have no idea where to start and how to access these private members
:(
> > > So any example will be helpful.
> > >
> > > Sunny
> > >
> > > "Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message
> > > news:ul****************@TK2MSFTNGP12.phx.gbl...
> > > > Hi Sunny,
> > > >
> > > >
> > > > I think that yes, it's possible to access the private

properties
of
a
> > > class
> > > > using reflection, I haven't tested it but I also saw the post

of > > Nicholas
> > > > and until now all that he said is true ;) , the thing is ( also stated
> > in
> > > > the post ) what are you planning to do with it? it;s a private
> property
> > > and
> > > > you have no idea of how it's used or what it means.
> > > >
> > > > Cheers,
> > > >
> > > > --
> > > > Ignacio Machin,
> > > > ignacio.machin AT dot.state.fl.us
> > > > Florida Department Of Transportation
> > > >
> > > > "Sunny" <su******@icebergwireless.com> wrote in message
> > > > news:uO*************@tk2msftngp13.phx.gbl...
> > > > > Hi,
> > > > > I have an old problem which I couldn't solve so far. Now I

have > found
> > a
> > > > post
> > > > > in that group that gave me an idea, but I can not fully

understand
> it.
> > > > > The problem is: I'm trying to use a Windows.Forms.UserControl in
a
> COM
> > > > > environment, i.e. I want to host that control in a COM host. So far,
> > so
> > > > > good, I can host it, but I can not reach the parent COM
object from
> > the
> > > > > control (Parent property is null :( ).
> > > > > I have stopped the control in the debugger and I found in the watch
> > > window
> > > > > some properties, like ActiveXInstance
> > > > > {System.Windows.Forms.Control.ActiveXImpl}
> > > > > The problem is that they are private to the base class, so I

can not
> > > > access
> > > > > them.
> > > > >
> > > > > Now the question: is it possible somehow to access these base > > properties
> > > > > programmatically. I have found a post which mentions something about
> > > > > reflection (whatever that mean). Can I use a reflection to

access
> > these
> > > > > properties?
> > > > >
> > > > > Any help will be highly appreciated.
> > > > >
> > > > > Thanks
> > > > > Sunny
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 15 '05 #10

P: n/a
Your code has been really helpful to me, as I encountered exactly the
same problem as Sunny (i.e. adding property pages to Outlook), except
that I'm using VB.NET. I thought that anyone trying to achieve this
may be interested to know that the code can be simplified to the
following:-

Public ReadOnly Property PageSite() As PropertyPageSite
Get
Dim typeUnsafeNativeMethods As Type = GetType
_(Windows.Forms.Control).Assembly.GetType
_("System.Windows.Forms.UnsafeNativeMethods")
Dim typeOleObject As Type =
typeUnsafeNativeMethods.GetNestedType _("IOleObject")
Dim methodGetClientSite As Reflection.MethodInfo = _
typeOleObject.GetMethod("GetClientSite")
Dim site As Object = methodGetClientSite.Invoke(Me,
Nothing)

Try
Return CType(site, PropertyPageSite)
Catch ex As InvalidCastException
'Handle the exception
End Try
End Get
End Property

The above PageSite property is added to your class that implements the
Outlook.PropertyPage interface.

One further necessity though, will probably be to set the caption of
the property page (the tab heading). In order to do this, I found that
I had to define my own interface as follows (substitute a GUID where
the x's are):-

<GuidAttribute("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"),
InterfaceTypeAttribute _ (ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface IMyProperties
Inherits PropertyPage
<DispId(-518)> ReadOnly Property Caption() As String
End Interface

Instead of implementing Outlook.PropertyPage, your class would then
implement IMyProperties.

"Sunny" <su******@icebergwireless.com> wrote in message news:<O0**************@TK2MSFTNGP10.phx.gbl>...
Hi Vladimir,
IT WORKS IT WORKS. You are great. I have implemented this in C# and it gave
me the reference I needed. I suppose, that I had to implement all of your
code, but I stopped at the check for site is Nothing, because I can cast it
at the type I want. So, I do not know what the rest of the code have to do.
If you have a little time, pls, explain. Nevertheless so far, you are the
only guy around who have succeeded to solve that problem. I have posted it
allover, with different ideas, but ... nothing.

Thank you again
Sunny

"Vladimir Kouznetsov" <vl*****************@REMOVETHISngrain.com> wrote in
message news:O9**************@TK2MSFTNGP09.phx.gbl...
Here is a sample code (in VB but it shouldn't not be difficult to

translate
it) I used to get UserMode property:

Dim strAssembly As String
strAssembly =
Type.GetType("System.Object").Assembly.CodeBase.Re place("mscorlib.dll",
"System.Windows.Forms.dll")
strAssembly = strAssembly.Replace("file:///", String.Empty)
strAssembly =

Reflection.AssemblyName.GetAssemblyName(strAssembl y).FullName
Dim unmt As Type = _
Type.GetType(Reflection.Assembly.CreateQualifiedNa me(strAssembly,
"System.Windows.Forms.UnsafeNativeMethods"))
Dim ioot As Type = unmt.GetNestedType("IOleObject")
Dim mi As Reflection.MethodInfo = ioot.GetMethod("GetClientSite")
Dim site As Object = mi.Invoke(Me, Nothing)
If site Is Nothing Then Return -1

' We are hosted by a COM container

Dim dsite As IDispatch = site

' All the uninitialized arguments work fine in this case
Dim id As Guid
Dim params As DISPPARAMS
Dim lcid As System.UInt32
Dim wFlags As System.UInt16 = System.UInt16.Parse(2.ToString())
Dim result As Object
dsite.Invoke(-709, id, lcid, wFlags, params, result, Nothing, Nothing)

If result Then
Return 1
Else
Return 0
End If

That should give you an idea how to do what you want. IIRC IOleClientSite
has method GetContainer() which I think you need (not the parent COM
object). BTW You can use ildasm on System.Windows.Forms.dll to make

yourself
familiar with the internal classes and implementations.

thanks,
v

"Sunny" <su******@icebergwireless.com> wrote in message
news:ui**************@tk2msftngp13.phx.gbl...
Hi, it seems that I have to guess what property to get, so I'll play with all of them, but that happen always with combination COM/.Net/Outlook :)
The problem is, that I have read some of docs for reflection, and I still have no idea where to start and how to access these private members :(
So any example will be helpful.

Sunny

"Ignacio Machin" <ignacio.machin AT dot.state.fl.us> wrote in message
news:ul****************@TK2MSFTNGP12.phx.gbl...
> Hi Sunny,
>
>
> I think that yes, it's possible to access the private properties of a class > using reflection, I haven't tested it but I also saw the post of Nicholas > and until now all that he said is true ;) , the thing is ( also stated in > the post ) what are you planning to do with it? it;s a private property
and > you have no idea of how it's used or what it means.
>
> Cheers,
>
> --
> Ignacio Machin,
> ignacio.machin AT dot.state.fl.us
> Florida Department Of Transportation
>
> "Sunny" <su******@icebergwireless.com> wrote in message
> news:uO*************@tk2msftngp13.phx.gbl...
> > Hi,
> > I have an old problem which I couldn't solve so far. Now I have found
a
post > > in that group that gave me an idea, but I can not fully understand it. > > The problem is: I'm trying to use a Windows.Forms.UserControl in a COM > > environment, i.e. I want to host that control in a COM host. So far, so > > good, I can host it, but I can not reach the parent COM object from the > > control (Parent property is null :( ).
> > I have stopped the control in the debugger and I found in the watch window > > some properties, like ActiveXInstance
> > {System.Windows.Forms.Control.ActiveXImpl}
> > The problem is that they are private to the base class, so I can not access > > them.
> >
> > Now the question: is it possible somehow to access these base properties > > programmatically. I have found a post which mentions something about
> > reflection (whatever that mean). Can I use a reflection to access these > > properties?
> >
> > Any help will be highly appreciated.
> >
> > Thanks
> > Sunny
> >
> >
>
>


Nov 15 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.