none
Multiple Interfaces in ComSourceInterfaces are being ignored except the first one RRS feed

  • Question

  • Apparently, passing multiple interfaces on ComSourceInterfaces are being ignored except for the first one.

    I've included a sample to reproduce this issue.

    [Guid("7c0fbf13-6534-4337-964e-9d95f42e256a"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IAEvents
        {
            [DispId(1)]
            void OnEventA();
        }
    
        [Guid("66b41f14-b295-4f3b-9be4-4a7827cb3473"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IBEvents
        {
            [DispId(2)]
            void OnEventB();
        }
    
        [Guid("128a14ef-dd20-4f4e-ab36-533465537ebe"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IApp
        {
            [DispId(1)]
            void Fire();
        }
    
        [ComVisible(true)]
        [Guid("06a56072-de58-4941-ab7e-40209bf52320"), ClassInterface(ClassInterfaceType.None)]
        [ProgId("MyAppTest")]
        [ComSourceInterfaces(typeof (IAEvents), typeof (IBEvents))]
        public class App : IApp
        {
            public delegate void VoidEvent();
    
    
            private VoidEvent _onEventA;
    
            public event VoidEvent OnEventA
            {
                [MethodImpl(MethodImplOptions.Synchronized)]
                add { this._onEventA += value; }
                [MethodImpl(MethodImplOptions.Synchronized)]
                remove { this._onEventA -= value; }
            }
    
            private VoidEvent _onEventB;
    
            public event VoidEvent OnEventB
            {
                [MethodImpl(MethodImplOptions.Synchronized)]
                add { this._onEventB += value; }
                [MethodImpl(MethodImplOptions.Synchronized)]
                remove { this._onEventB -= value; }
            }
    
            public void Fire()
            {
                VoidEvent a = _onEventA;
                if (a != null)
                {
                    a();
                }
    
                VoidEvent b = _onEventB;
                if (b != null)
                {
                    b();
                }
            }
        }

    The event OnEventB isn't handled outside the COM object.

    This client thml page test allows to test this issue.

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
    	<head>
    		<title></title>
    	</head>
    	<body>
    		
    		<input type="button" onclick="raise();" value="raise"/>
    		
    		<OBJECT name="App" id="App" classid="clsid:06a56072-de58-4941-ab7e-40209bf52320" VIEWASTEXT>
    			<SPAN STYLE="color:red">
    							ActiveX control failed to load!</SPAN>
    		</OBJECT>
    		
    
    
    		<script>		
    			
    			function App::OnEventA(){
    				alert('A');
    			}
    			
    			function App::OnEventB(){
    				alert('B');
    			}
    		
    			function raise() {
    					try
    					{
    						App.Fire();
    					}
    					catch ( ex )
    					{
    						alert("Error: " + ex.message);
    					} 
    			}
    
    		</script>
    	</body>
    </html>

    Friday, July 6, 2012 5:05 PM

Answers

  • Next, a COM object can only have one interface that inherits IDispatch interface. For C++ COM objects you can use techniques as wriiten in here, but I don't think they're applicable to C# programs.
    Monday, July 9, 2012 10:36 AM
    Answerer

All replies

  • Hi Joao,

    Welcome to the MSDN Forum.

    Do you mean if you put the IBevents on the first position, the event A didn't get fired?

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, July 9, 2012 9:57 AM
    Moderator
  • Just one quick question... In the following line:

    [DispId(1)]
           
    void Fire();

    I think the DispId for this one collided with that for IAEvents. When DispId collusion occurs, the behaviour is specified in this article.

    When DispId collisions occur, the import process assigns DispIds to members of the coclass's default interface and none to the conflicting class members. However, the import process always assigns DispIds to members of the interface.


    Monday, July 9, 2012 10:08 AM
    Answerer
  • @Mike Exactly. If I change the order of ComSourceInterfaces to IBEvents first, the A event don't get fired and B event gets fired. If I relocate all events to the first interface, both events get fired.

    Thanks for the replies.


    Monday, July 9, 2012 10:16 AM
  • @cheong00 that can be truth, but even if I change the DispId of Fire() to [DispId(3)], the issue still ocourrs.
    Monday, July 9, 2012 10:17 AM
  • Next, a COM object can only have one interface that inherits IDispatch interface. For C++ COM objects you can use techniques as wriiten in here, but I don't think they're applicable to C# programs.
    Monday, July 9, 2012 10:36 AM
    Answerer
  • Thanks. That should probably be it.

    Would't make much sence to allow multiple intefaces on ComSourceInterfaces this way....

    Wednesday, July 11, 2012 7:46 AM