Embedding UserControl in Internet Explorer

P

Peter Bromley

Hi,

I have an outstanding issue with my control which I would like help with
if anybody can help, thanks.

I need to control the size of my UserControl which is embedded within
Internet Explorer pages. My control is able to determine minimum and
maximum sizes (based on sizes and positions of dynamically determined
child controls).

But, when embedded in an IE web page, my control is sized long before it
is fully constructed.

As far as I can tell the control size is set through the SetExtent
method of the COM IOleObject interface exposed by private .NET forms
classes. But this is called before even the Load event is fired for my
control or any of its child controls. So overloading OnSizeChanged is of
no used to me as it occurs far too early in the lifetime of my control.

I have also attempted to control the size in the Layout event but that
has no effect on the container size within the Web page layout, only the
control size within that container.

What I need to do is resize the control in a way which affects the web
page layout, but after IE appears to have finished laying out the page.

Is there a way I can do this from within my control? I don't want to
force additional JScript on the web clients of my control.


Very much TIA,

Peter Bromley
--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
J

Jeffrey Tan[MSFT]

We are currently doing research on this issue, we will reply to you ASAP.
Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi,

Currently we are finding some experience people to handle this issue, we
will reply to you ASAP. Thanks for your understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
A

Amy Luu[MSFT]

Hi Peter,

Would you be able to post a sample that shows your control is sized long
before it is fully constructed in Internet explorer?

thanks a lot!
Amy

This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Bromley

Amy said:
Hi Peter,

Would you be able to post a sample that shows your control is sized long
before it is fully constructed in Internet explorer?
Not easily, i have a lot of code to pare down. I will try, though, and
post something Monday.

But for now a walkthrough,

From my control's point of view, the following things happen:

Constructor,
Layout event (from OnSizeChanged internally - arising from
ActiveXImpl.SetExtent)
Load event (here I load my child controls)
Layout event

The trouble for me is that the Minimum and Maximum sizes for my control
depend on the child controls I load dynamically (ie I load different
ones depending on properties set from the html OBJECT tag).

It doesn't seem that the ActiveXImpl.GetExtent function is called at all
- but that can't be right. I have looked using ildasm and it seems that
GetExtent just returns the control's Size. So if I can ensure the Size
is satisfactory to me by the time either GetExtent or SetExtent is called...

What I was hoping was that
a) I could get my loading done before the first Layout event and before
GetExtent/SetExtent are called.
b) I could tell IE that the size it had arranged was incorrect and
negotiate a new size.

Hoping,

thanks a lot!
Amy

This posting is provided "AS IS" with no warranties, and confers no rights.

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
Y

Yan-Hong Huang[MSFT]

Hi Peter,

Based on our testing and discussion, could you please try the following
code If you know the size you want to change?

this.ClientSize= new System.Drawing.Size(400, 500);

We test it and it works fine on our side. Please test it and reply here to
let us know whether it works for you. We look forward to your response.

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Bromley

Yan-Hong Huang said:
Hi Peter,

Based on our testing and discussion, could you please try the following
code If you know the size you want to change?

this.ClientSize= new System.Drawing.Size(400, 500);

We test it and it works fine on our side. Please test it and reply here to
let us know whether it works for you. We look forward to your response.

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.

Well, different things happen when I set ClientSize as opposed to
setting Size but I still do not get the size I want.


If I have a Usercontrol which knowns its size at construction or even on
the first Layout event (by setting ClientSize), IE will honour that size.

BTW: that first Layout event happens before the Load event!

But, when the UserControl has child controls, IE disregards the
ClientSize I set and follows up with a call to
IOleInPlaceObject.SetObjectRects and resizes the control back to the
original height and width set in the OBJECT tag. Damn.

The interaction between the OLE calls and the .NET load/layout events is
not simple, as many of my child controls still haven't had Load events
fired by the time IE does an activation

To recap the order of things now:

1. ctor
2. properties set from PARAM tags
3. Layout event (from IOleObject.SetExtent)
4. Load event (here I create my first child - other descendants created
in ctor and/or Load events of descendants as many are dynamically
determined from settings files).
5. Layout event (from IOleObject.DoVerb - activation) - descendants
partly constructed
6. Layout event (from IOleInPlaceObject.SetObjectRects) - descendants
fully constructed but IE resetting Bounds back to OBJECT width/height

I have tried accessing the IOleInPlaceSite of the client site and
calling OnPosRectChange but this has no effect on Internet Explorer

I am still working on a postable simple UserControl to exhibit my problems.

Peter

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
Y

Yan-Hong Huang[MSFT]

Hi Peter,

We look forward to your repro UserControl sample. At the same time, we will
also perform research to dig into it.

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Bromley

We look forward to your repro UserControl sample. At the same time, we will
also perform research to dig into it.

OK here is the example code. There are quite a few things to be done to
make the UserControl load properly within IE. I am hoping you have
already done most of these things and that you will just copy my example
code into your embedded object.
<OBJECT id="ExampleView1"
classid="CLSID:12144051-306A-44f0-AD62-AC52523EF9F6" VIEWASTEXT
width="100" height="100">
Did not load Example object
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace System::ComponentModel;
using namespace System::Runtime::InteropServices;

namespace Eg
{
[ComVisible(true), Guid(S"12144051-306A-44f0-AD62-AC52523EF9F6")]
public __sealed __gc class Example:
public UserControl
{
public: Example(void)
{
System::Diagnostics::Debugger::Break();
InitializeComponent();
}

public: [Browsable(false), ReadOnly(true)]
__property System::Drawing::Size get_MinimumSize(void)
{
int size = (mChild ? (mChildLoaded ? 300 : 200) : 0);
return System::Drawing::Size(size, size);
}

private: Void mChild_Load(Object* sender, EventArgs* e)
{ mChildLoaded = true; }
private: Control* mChild;
private: bool mChildLoaded;

// Designer-controlled members
private:
System::ComponentModel::Container* components;
void InitializeComponent(void)
{
//
// Example
//
this->BackColor = System::Drawing::Color::Yellow;
this->Name = S"Example";
this->Load += new System::EventHandler(this, Example_Load);
this->Layout += new System::Windows::Forms::LayoutEventHandler(this,
Example_Layout);

}

private: System::Void Example_Load(System::Object* sender,
System::EventArgs* e)
{
if (DesignMode) return;

UserControl* child = new UserControl();
mChild = child;
child->Anchor = (AnchorStyles)(AnchorStyles::Top
| AnchorStyles::Bottom
| AnchorStyles::Left
| AnchorStyles::Right);
child->BackColor = Color::Green;
child->Location = Point(0, 0);
child->Size = System::Drawing::Size(ClientRectangle.Width,
ClientRectangle.Height);
child->Load += new EventHandler(this, mChild_Load);
Controls->Add(child);
}
private: System::Void Example_Layout(System::Object* sender,
System::Windows::Forms::LayoutEventArgs* e)
{
if (DesignMode) return;

System::Drawing::Size size = Size;
System::Drawing::Size minSize = MinimumSize;
size.Width = Math::Max(size.Width, minSize.Width);
size.Height = Math::Max(size.Height, minSize.Height);

if (size != ClientSize)
ClientSize = size;
}
};
}
<<<<<<<<<

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
Y

Yan-Hong Huang[MSFT]

Hi Peter,

Thanks for the update. We will look into it and reply here with our finding
as soon as possible.

Have a good day.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
A

Amy Luu[MSFT]

Hi Peter,

Two scenarios I am seeing here:
1. The flickering of the control when it loads(the control is being resized
base on the code inside of your app, then IE redraws it again base on the
width and height specified in the Object tag)
2. The size of the control displayed in IE is NOT the size you specified
inside the control BUT the Object tag.

The behavior is expected, if you need the size to be different than what's
on the Object tag, you can expose a method inside of your control to do
resizing and calling it from script after the control is loaded. This
gives web developers using your control the options if they want your
control to resize automatically or they like to display the size they want.

thanks a lot!
Amy

This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Bromley

Two scenarios I am seeing here:
1. The flickering of the control when it loads(the control is being resized
base on the code inside of your app, then IE redraws it again base on the
width and height specified in the Object tag)

Yes, but only if it has the child control within it! Take the child
control out and IE will allow the control to change it's ClientSize.
2. The size of the control displayed in IE is NOT the size you specified
inside the control BUT the Object tag.

The behavior is expected, if you need the size to be different than what's
on the Object tag, you can expose a method inside of your control to do
resizing and calling it from script after the control is loaded. This
gives web developers using your control the options if they want your
control to resize automatically or they like to display the size they want.

Hmmm. My problem is that I have been directed to create a control that
does not require client-side scripting to initialise. I had already
offered this solution to my supervisor but it has been rejected as "not
self-initialising". It is possible that my control will support
scripting in future, but that will be a business decision out of my control.

Also you say "if they want your control to resize automatically" but I
cannot get this to happen at all due to the timing of calls as already
described.

Additionally, I would like my control to be able to completely size
itself in certain cases, ie leave the width and height unspecified in
the OBJECT tag and have the control indicate the size it wants to be.
But what happens here is that the default size of the control (150, 150
if I dont specify otherwise) is the size used by IE.

So my initial question still stands. Is there an interface or mechanism
I can use to change the control size once it is initialised and IE has
performed it's page layout -- other than client side scripts?

Thanks you your effort and analysis to date.

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
Y

Yan-Hong Huang[MSFT]

Hi Peter,

Based on Amy's reply, the control needs to expose a function to control its
size. I will contact him again on your scenario to see whether we can find
any workaround for this issue.

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Bromley

Yan-Hong Huang said:
Hi Peter,

Based on Amy's reply, the control needs to expose a function to control its
size. I will contact him again on your scenario to see whether we can find
any workaround for this issue.

Thanks, and if I can just emphasize three things.

1. If I do not specify a size in the OBJECT tag, IE will still end up
setting the control size to be the size it was after it's constructor
was called (basically the .NET default size of 150x150).

2. If a control has no child controls, IE will accept my changes to the
control's size (via setting ClientSize), but if a control has child
controls - which my control must - IE reverts the size back to the
original size.

3. The OLE relationship between IE and .NET controls does not seem to be
designed to allow the control to dynamically initialise itself before IE
sets the container size, since IE asks for the control size before
setting the control properties (from the OBJECT PARAMETER tags), and
before .NET calls the control's (and its childrens') Load events.

These may not be bugs but they sure affect me as if they are.

Thanks again for the effort and analysis. A decision has been made here
that the web page designers will be informed that they must verify the
size specified in the OBJECT tag is suitable. Not so onerous, I suppose.

Cheers,

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
P

Peter Bromley

Hi, again,

I have another question which someone may be able to answer.

My control has child controls which are standard controls (scroll bars,
buttons, etc). Now, because my control is embedded in Internet Explorer,
these child controls are not drawn using the XP themed appearance; they
are drawn using the older Classic.

How can I get the XP themed appearance for these child controls?

I can't use an application manifest because the application is IE.
InitCommonControlsEx returns false.
The buttons etc have FlatStyle set to System. The scroll bars do not
have a FlatStyle property.

I can't think of, or find, any other mechanism to achieve this.

Peter

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
Y

Yan-Hong Huang[MSFT]

Hi Peter,

Could you please open a new thread for the new question? Currently we are
involving support team on it and it is better for us to focus on one
question first. Opening the new question in a new thread could help you get
quicker response.

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Bromley

Yan-Hong Huang said:
Hi Peter,

Could you please open a new thread for the new question? Currently we are
involving support team on it and it is better for us to focus on one
question first. Opening the new question in a new thread could help you get
quicker response.

Sure, sorry. Should have realised.

The new thread is "Forcing XP Themed scroll bars within Internet
Explorer-hosted UserControl"

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
P

Peter Bromley

Amy said:
Hi Peter,

To use Windows XP theme, we need to follow this articles.
HOWTO: Use Windows XP Visual Styles with .NET Windows Forms
http://support.microsoft.com/default.aspx?scid=kb;en-us;303636&Product=VBB

If we only set flatstyle=system, the user control hosted in Internet
Explorer does
not pick up theming since iexplore.exe does not have a comctl 6 manifest.
You could
write the code to manage the activation context yourself in the user
control, but
for this to work, THE CONTROL WOULD REQUIRE UNMANAGED CODE PERMISSION,
since you
will have to p/invoke the activation context API. I have attached some
sample code that could be used to do this, including a ThemingScope class
which wraps the
activation context API.

There is a problem when set flatstyle=system, if first click the button,
the onclick event does not fire. It works fine after that. To workaround,
we can use mouseUp event instead of onclick. This should pretty much have
the same effect while it does not exhibit the problem.
OK, lets narrow this down. Specifically, what matters to me most at the
moment are scroll bars - which do not have flatstyle.

Will the theming activation context code work to make scroll bars have
XP theming?

I have read as much as I can digest from msdn and MSKB regarding XP
theming, UXTheme, and related topics, but now you have pointed this API
out, I will research that too.

Thanks,

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
P

Peter Bromley

OK, lets narrow this down. Specifically, what matters to me most at the
moment are scroll bars - which do not have flatstyle.

Will the theming activation context code work to make scroll bars have
XP theming?

I have read as much as I can digest from msdn and MSKB regarding XP
theming, UXTheme, and related topics, but now you have pointed this API
out, I will research that too.

Great - I have tested the activation context code out and it works a treat.

Thanks ever so much,

Peter

--
If you wish to reply to me directly, my addres is spam proofed as:

pbromley at adi dot co dot nz

Or if you prefer - (e-mail address removed) :)
 
Y

Yan-Hong Huang[MSFT]

Hi Peter,

It seems that the problem has been resolved by Amy's reply in this thread.
:)

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top