11

Is there a way to get IntelliSense in own built COM classes in VBA?

E.g. in the example below I would like to get "Number" showing up, whenever I press on the dot (or ctrl+space for shortcut): enter image description here

I suppose, if this is somehow resolved, I would also get some info concerning the public functions of the objects here:

enter image description here

Thus, what are the suggestions?

Suggestion 1:

enter image description here

Vityata
  • 42,633
  • 8
  • 55
  • 100
  • The question there is `how` and in my case it does not display at all. – Vityata Dec 15 '16 at 11:14
  • 1
    Goto the Object Browser in VBA, and right click in the members pane and choose "Show hidden Members". You should then be able to see all the members in Object Browser, and you'll get Intellisense in the Code Panes. – ThunderFrame Dec 15 '16 at 11:30
  • Thanks, I did it, but it did not work. (See updated question for screenshot) – Vityata Dec 15 '16 at 11:34
  • 3
    Not enough attributes. It is not in general a great idea to expose a class, inherited members like GetType(), MemberwiseClone() are not useful and drags in a dependency on a type library for .NET framework classes. So the default [ClassInterface] is ClassInterfaceType.AutoDispatch. Which supports only late binding (slow) and no IntelliSense. You are asking for ClassInterfaceType.AutoDual. Exposing an interface is better, hides the inherited members and is the COM-way and allows ClassInterfaceType.None – Hans Passant Dec 15 '16 at 11:47
  • I see. So I should always make interfaces for intelliSense. Can you give me a sample of how would a simple class with one function look like, if I wanted to have an intelliSense for it? – Vityata Dec 15 '16 at 11:52

1 Answers1

6

Simple example could look like this.

c# class library named IntellisenseDemo code

using System;
using System.Runtime.InteropServices;

namespace IntellisenseDemo
{
    [ComVisible(true)]
    [Guid("41B3F5BC-A52B-4AED-90A0-F48BC8A391F1")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IIntellisenseDemo
    {
        int Number { get; set; }
        string TestString(string name);
    }

    [ComVisible(true)]
    [Guid("20EBC3AF-22C6-47CE-B70C-7EBBA12D0A29")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("IntellisenseDemo.Demo")]
    public class Demo : IIntellisenseDemo
    {
        public int Number { get; set; }
        public string TestString(string name)
        {
            throw new NotImplementedException();
        }
    }
}

Note: [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] indicates that an interface is exposed to COM as a dispinterface, which enables late binding only.

[ClassInterface(ClassInterfaceType.None)] means the CLR does not expose a class interface for this type. COM clients can call the members of this class using the methods from the IIntellisenseDemo interface.

regasm

C:\Windows\Microsoft.NET\Framework\v4.0.30319>regasm C:\Temp\IntellisenseDemo.dll /tlb: C:\Temp\IntellisenseDemo.tlb

VBA

enter image description here

enter image description here

enter image description here

Daniel Dušek
  • 13,683
  • 5
  • 36
  • 51
  • It looks like something interesting, I will check it later. But just from first look - is there a way to make it without interfaces and withEvents? Something simple? – Vityata Dec 15 '16 at 11:48
  • Thanks, it works well. Just a few more questions, concerning your code, if possible. Where did does: [ComVisible(true)] [Guid("41B3F5BC-A52B-4AED-90A0-F48BC8A391F1")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] came from? Did you use some shortcut for its creation? Is ComVisible(true) really needed, considering that I check "Make assembly COM-Visible in the Assembly information? – Vityata Dec 15 '16 at 12:53
  • Attributes have been added manually, so no shortcut, simple handwriting. Explicitly using the `[ComVisible(true)]` attribute is not necessary, it serves more like a marker. You can delete this attribute and it should still be working because managed type is COM-visible by default. – Daniel Dušek Dec 15 '16 at 13:08
  • 1
    And the GUID? Did you also wrote this manually? This is what I made from your code, removing the stuff I do not understand and it works: https://github.com/Vitosh/C-Sharp-Stuff/tree/master/IntSense Thanks once again! :) – Vityata Dec 15 '16 at 13:13
  • About GUID-Problem see e.g. [this answer.](http://stackoverflow.com/questions/1067538/why-is-guid-attribute-needed-in-the-first-place). You are welcome! :) – Daniel Dušek Dec 15 '16 at 13:21
  • So you simply created some random GUID? – Vityata Dec 15 '16 at 13:24
  • 1
    Yes just use the `Tools->Create GUID` in Visual Studio and let create new Guid. – Daniel Dušek Dec 15 '16 at 13:27
  • I see. I was a bit in doubt, because I know the GUID in the Assembly Information, which is automatically generated. – Vityata Dec 15 '16 at 13:34