Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / August 2006

Tip: Looking for answers? Try searching our database.

Usercontrol as ActiveX - trouble with events

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Aled Hughes - 20 Jul 2006 16:25 GMT
Hi,
I'm having trouble with a UserControl (written in C# with framework v2.0)
that I've made into an ActiveX control. It seems to be OK except for event
handling.
As a test I use VB6 as the container (I've also tried from C++6 too).

If I create the control in VB6 code as follows:

Dim WithEvents myControl As WinControl1.UserControl1
Private Sub Form_Load()
Set myControl = New UserControl1
End Sub

Private Sub Command1_Click()
' Run a method that invokes the TestEvent() delegate
myControl.Test
End Sub

Private Sub myControl_TestEvent()
MsgBox "Event Fired!"
End Sub

This works absolutely fine - the event gets fired as expected.

However, if I add the control in onto the VB form at design time (the
control has a button on it that fires the event) rather than creating it in
code, I cannot get the event to fire at all. The event delegate in the C#
control code remains at null.

Any idea as to why the event isn't working when the UserControl is hosted
this way?

Cheers,
aled.
Ken Halter - 20 Jul 2006 21:35 GMT
emembrance.htm
> Hi,
> I'm having trouble with a UserControl (written in C# with framework v2.0)
[quoted text clipped - 8 lines]
> Set myControl = New UserControl1
> End Sub

Try....

Set myControl = Controls.Add("WinControl1.UserControl1","WhoCares")

Signature

Ken Halter - MS-MVP-VB (visiting from VB6 world) - http://www.vbsight.com
Please keep all discussions in the groups..
In Loving Memory - http://www.vbsight.com/R

Aled Hughes - 21 Jul 2006 07:52 GMT
I'm testing with a VB6 client (no 'Controls.Add') and really I don't want any
of that VB code at all - all I want is the UserControl on the form and a
"UserControl11_DoStuff()" event handler, just like a button has its Click()
handler.

At design time, when I double-click the UserControl on the form then VB
creates the DoStuff() handler, but at run-time it never gets called.
Ken Halter - 24 Jul 2006 18:17 GMT
> I'm testing with a VB6 client (no 'Controls.Add') and really I don't want
> any
[quoted text clipped - 5 lines]
> At design time, when I double-click the UserControl on the form then VB
> creates the DoStuff() handler, but at run-time it never gets called.

Whether it works or not is besides the point... I guarantee that VB6
supports Controls.Add <g>... and, Set XX = New YY takes no less code than
Set XX = Controls.Add("blah, blah")... plus, VB6 doesn't like controls to be
added to a forms Controls collection without using Controls.Add or Load.
Take yer pick. I have a bare-bones example of the two methods VB6 supports,
Controls.Add and Load, if interested, see:
http://www.vbsight.com/CodeA.htm#AddControls

Signature

Ken Halter - MS-MVP-VB (visiting from VB6 world) - http://www.vbsight.com
Please keep all discussions in the groups..
In Loving Memory - http://www.vbsight.com/Remembrance.htm

Christian Fröschlin - 21 Jul 2006 09:02 GMT
> Hi,
> I'm having trouble with a UserControl (written in C# with framework v2.0)
> that I've made into an ActiveX control. It seems to be OK except for event
> handling.

Try explicitely exposing a dispatch interface like (untested)

[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface TestEventInterface
{
  void TestEvent()
}

and decorating the class raising the event with:

[ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces("<yournamespace>.TestEventInterface")]
Aled Hughes - 21 Jul 2006 14:10 GMT
Yes, I've got that explicit IDispatch interface declared for the user
control's event. Still no luck though!
Here is the entire code for the C# control (which has only a button on it!):

namespace WinControl1
{
    [ComVisible(false)]
    public delegate void TestEventDelegate();

    [Guid("C9CCDB9B-5A41-44b7-A54E-6D6DE0826EF5")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [ComVisible(true)]
    public interface IUserControl1
    {
        [DispId(1)]
        void Test();
    }

    [Guid("DCFF96F9-9F3B-4576-A144-E4CD030614B0")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [ComVisible(true)]
    public interface IUserControl1Events
    {
        [DispId(1)]
        void TestEvent();
    }

    [Guid("F4A79199-9FA1-4810-AE34-F1EAC0437980")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfacesAttribute(typeof(IUserControl1Events))]
    public partial class UserControl1 : UserControl, IUserControl1
    {
        public event TestEventDelegate TestEvent;

        public UserControl1()
        {
            InitializeComponent();
        }

        public void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(".net control: Button Press");
            if (TestEvent == null)
                MessageBox.Show("TestEvent delegate is null");
            else
                TestEvent();
        }
       
        public void Test()
        {
            MessageBox.Show("Test method called");
            if (TestEvent != null)
                TestEvent();
        }
       
        [ComRegisterFunction]
        static void ComRegister(Type t)
        {
            string keyName = @"CLSID\" + t.GUID.ToString("B");
            using (RegistryKey key =
                    Registry.ClassesRoot.OpenSubKey(keyName, true))
            {
                key.CreateSubKey("Control").Close();
                using (RegistryKey subkey = key.CreateSubKey("MiscStatus"))
                {
                    subkey.SetValue("", "131457");
                }
                using (RegistryKey subkey = key.CreateSubKey("TypeLib"))
                {
                    Guid libid = Marshal.GetTypeLibGuidForAssembly(t.Assembly);
                    subkey.SetValue("", libid.ToString("B"));
                }
                using (RegistryKey subkey = key.CreateSubKey("Version"))
                {
                    Version ver = t.Assembly.GetName().Version;
                    string version =
                     string.Format("{0}.{1}",
                                    ver.Major,
                                    ver.Minor);
                    if (version == "0.0") version = "1.0";
                    subkey.SetValue("", version);
                }
            }
        }

        [ComUnregisterFunction]
        static void ComUnregister(Type t)
        {
            // Delete entire CLSID\{clsid} subtree
            string keyName = @"CLSID\" + t.GUID.ToString("B");
            Registry.ClassesRoot.DeleteSubKeyTree(keyName);
        }
       
    }
}
Nick Hall - 24 Jul 2006 12:44 GMT
Hi Aled,

Unfortunately, NET controls are not supported in the VB6 environment.

(See http://support.microsoft.com/default.aspx?scid=KB;EN-US;311334 for more
details.)

I belive the suggested workaround is to host the control inside a WebBrowser
control.

Regards,

Nick Hall

> Hi,
> I'm having trouble with a UserControl (written in C# with framework v2.0)
[quoted text clipped - 31 lines]
> Cheers,
> aled.
Aled Hughes - 26 Jul 2006 11:45 GMT
My understanding was that this applies only to .net framework 1 and that
support had improved for version 2.0. The KB article says it only applies to
.net framework 1.0 and 1.1.

This whole subject area does seem somewhat vague in the MS documentation!

> Hi Aled,
>
[quoted text clipped - 45 lines]
> > Cheers,
> > aled.
Nick Hall - 26 Jul 2006 12:28 GMT
Hi Aled,

Yes, I hadn't noticed that the article only applied to 1.1.  However I have
been unable to find anything that suggests that has changed for 2.0; so I
would tend to believe that the restriction still applies (unless you have
seen something that suggests different..?)

As you say, the documentation is less than impresive on this point.

Regards,

Nick Hall

> My understanding was that this applies only to .net framework 1 and that
> support had improved for version 2.0. The KB article says it only applies
[quoted text clipped - 59 lines]
>> > Cheers,
>> > aled.
Aled Hughes - 26 Jul 2006 17:05 GMT
Hi Nick,
I noticed in the KB article that MFC 7.x is a supported host for .net
ActiveX controls. Well I tried in MFC8 and the same incorrect behaviour
(events not firing) occurs.

As far as I've been able to deduce, MFC passes in its event sink interface
pointer when it uses IQuickActivate on the ActiveX .net user control. The
.net control then does a QueryInterface on the event sink for a number of
other interface IDs, but never does a QI for the event interface itself (i.e.
IID_IUserControl1Events as obtained from the AX control). If I constrast this
with a native ActiveX control, that does QI for the event interface ID. So it
seems to me that the .net control simply doesn't bother checking to see if
the client supports the appropriate event sink.
Strange! I wonder how the 'WithEvents' keyword in VB6 gets events to work?

Aled.

> Hi Aled,
>
[quoted text clipped - 72 lines]
> >> > Cheers,
> >> > aled.
Aled Hughes - 26 Jul 2006 18:37 GMT
I've discovered some more:

I've managed to get events working now in the ActiveX Control Test Container
application and I can get them working too in MFC world.

The problem seems to lie around IQuickActivate - if I prevent this being
used in MFC (using the debugger), all is well and the event hooks up
correctly. MFC falls back to using the IConnectionPoint::Advise system when
IQuickActivate isn't present, and that seems to work fine.

The other important thing I discovered was that setting the DispId of the
event interface in the .net control is important. If I miss off that
attribute I get an exception thrown. So I set [DispID(1)].

So I guess that the fault lies with .net's implementation of IQuickActivate.
I guess in the VB6 world, it too uses IQuickActivate if the control is on a
form, whereas if it created in code with 'WithEvents' keyword, it does it
differently and uses IConnectionPoint which works.

In MFC I won't be able to prevent it using IQuickActivate normally, but even
so it is possible to work around it by manually calling
IConnectionPoint::Advise at an approriate time.
"Peter Huang" [MSFT] - 27 Jul 2006 08:55 GMT
Hi Aled,

Based on my research, so far the VS.NET 2005 did not support write a
UserControl and register for Com Interop and use it as an ActiveX control
in VB6.
But from VC.NET 2005, we have new MFC-Winform Application, you may have a
try.
Using WinForms controls in an MFC dialog
http://www.codeproject.com/managedcpp/mfcdialogwinforms.asp

Using the Windows Forms 2.0 MenuStrip and ToolStrip controls to give your
MFC applications a new look and feel
http://www.codeproject.com/managedcpp/MfcWinFormsOff.asp

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Aled Hughes - 27 Jul 2006 09:21 GMT
Hi Peter,

To be honest, I'm not particularly worried about VB6 support. I was using
VB6 simply as a test bed.

What I am aiming for is getting a WinForm into an existing MFC6 application.
I've seen that it's possible to get a WinForm control into an MFC8 app but I
was hoping to avoid migrating the MFC6 app to MFC8. Hence me thinking down
the route of wrapping the WinForm control in ActiveX. (I was initially hoping
for embedding a WinForms "Form" and having it appear as an MDI child rather
than a WinForm control but this seems a non-starter).

Cheers,
Aled.
"Peter Huang" [MSFT] - 28 Jul 2006 03:14 GMT
Hi Aled,

Because there are some problem to host .NET Control as an ActiveX control
in unmanaged application. there goes the KB per Nick suggested.
So from in MFC8 we add this feature for the customers who needs the feature
to host Winform Control in MFC8.

I understand you may want to use MFC6(VC6.0) to host .NET User Control.
But based on my knowledge, the VC6.0 is out of support lifetime.
Here is a link for your reference.
http://support.microsoft.com/lifecycle/?p1=3003

So if you want to develop application based on VC, why not use vc++2005
directly?
Do you have any concern to use MFC8 as your targeted platform?

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Aled Hughes - 28 Jul 2006 09:43 GMT
Hi Peter,

Ideally it would be good to use MFC8 with the CWinFormsControl support and
avoid the ActiveX stuff altogether. Trouble is that I have an existing
application developed in MFC6 and I don't really want to go through what will
probably be a non-trivial task of migrating it to MFC8 and doing a full
retest. Though, increasingly this looks like it may be the way I have to go.

Another way I thought of is wrapping up the WinForms control in an MFC8
ActiveX control and then using that ActiveX control in MFC6. This sounds like
it could be fraught with difficulties though!

Cheers,
Aled.
"Peter Huang" [MSFT] - 01 Aug 2006 09:00 GMT
Hi Aled,

I do understand your scenario.
But the VC6 is out of support lifetime, even MSPSS did not support MFC6
including using MFC 8 control in MFC 6.
They only support the scenario related with MFC6 is that migration MFC6 to
MFC8.

So for your scenario, I do recommend you try to write code in MFC 8, if you
have existing MFC6 code, you may try to use that in MFC8 scenario which is
the supported scenario so far.

Thanks for your understanding!

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.