Ribbonevents, comvisible and VBA

৭৫টি ভিউ
প্রথম অপঠিত মেসেজটিতে চলে আসুন

Frank Schoolderman

পড়া হয়নি,
৩ আগ, ২০২২, ১১:১৬:৪১ AM৩/৮/২২
প্রাপক Excel-DNA
Hiya,

I have a question regarding the ComVisible(true) attribute for the RibbonEvents.
Is there a way to exclude this class from the tlb? The reason for this is that i do want the ribbon (so I need ComVisible), but i do not want this class to be seen in the Object Browser of the VBA

Thanks in advance,
Frank


adix

পড়া হয়নি,
২৮ আগ, ২০২২, ২:৪২:২৫ PM২৮/৮/২২
প্রাপক Excel-DNA
Not sure .. if still relevant but i guess you use TlbExp.exe to create the tlb (at least i used this in the past within the PostBuildEvent's)
a TLB is a compiled version of a idl  (text) file 

Within the windows 10 SDK .. there is .\oleview.exe which allows you to open a TLB and generate a idl
this text file could be modified (remove the interfaces which you don't like to expose)

Now you you need midl to compile again a TLB ( MIDL is likewise part of the Windows SDK )
search for 22621.1.220506-1250.ni_release_WindowsSDK.iso

It took me a while in the past to find the correct syntax (and to locate cl.exe) but it worked with the x86 version of midl
Honestly .. a lot of work - but i used this to hide userforms from my dll.
In case you have only classes .. you can "selective" enable  ComVisible per class or module (in VB .NET with <ComClass(ClassId, InterfaceId, EventsId)>)

adix

পড়া হয়নি,
৪ সেপ, ২০২২, ৭:৪৮:৪২ AM৪/৯/২২
প্রাপক Excel-DNA
Okay - "only" / primary the Ribbon UI handling.
The used objectname is still visible - but you can use a certain technique to "not" expose the function names (at least)
But once the tlb is linked in VBA the class "RibbonMenu" is still visible - so you goal is not fully achieved.

With the below technique you can hide the functions and once you use a certain project prefix .. the names are unique and you can run multiple projects with the same technique.

The TLB will just contain:
  coclass RibbonMenu
    {
        [default] dispinterface _RibbonMenu;
        dispinterface _Object;
        dispinterface _IDTExtensibility2;
        dispinterface IRibbonExtensibility;
    };

Within your core AddinClass .. you can:

Public Class AddInEvents
    Implements IExcelAddIn
    ..
    Public Sub AutoOpen() Implements IExcelAddIn.AutoOpen
        ComServer.DllRegisterServer()
        ..
        ' Ribbon setup
        Menu.MenuHandler = New RibbonMenu
        ..
    End Sub

    Public Sub AutoClose() Implements IExcelAddIn.AutoClose
        ..
        Menu.MenuHandler = Nothing
        ..
        ComServer.DllUnregisterServer()
    End Sub
End Class

Now you need a combined class (which contains at least):

Friend Module Menu
    Public RibbonUI As CustomUI.IRibbonUI
    Public MenuHandler As RibbonMenu
   
    '... optional add here functions in order to all internal functions to refesh selected controls
End Module

<ComVisible(True)>
Public Class RibbonMenu
    Inherits CustomUI.ExcelRibbon

    Private Const gAppId As String = "2DF4D6A2DBA2"
    Public ReadOnly Property AppId() As String
        Get
            Return gAppId
        End Get
    End Property

    Public Overrides Function GetCustomUI(RibbonID As String) As String
        Dim sUI As String =
          "<?xml version='1.0' encoding='utf-8'?>" + vbCrLf +
          "<customUI xmlns='http://schemas.microsoft.com/office/2009/07/customui' onLoad='Ribbon_axCore_" & gAppId & "_OnRibbonLoad'>" + vbCrLf +
          " <ribbon startFromScratch='false'>" + vbCrLf + .. <- define here your Ribbon UI
         Return sUI
    End Function

    Public Sub Ribbon_axCore_2DF4D6A2DBA2_OnRibbonLoad(oRibbon As CustomUI.IRibbonUI)
        Menu.RibbonUI = oRibbon
    End Sub
   
    '.. here all remaining needed Ribbon Functions like _OnAction, _GetContent or GetImage (from a included ResImage)

    '#Disable Warning BC42105
    Public Function Ribbon_axCore_2DF4D6A2DBA2_GetImage(control As CustomUI.IRibbonControl)
        Dim ResImage As String = ExtractResImage(control.Tag, DefaultResName)
        Try
            Dim obj As Object = My.Resources.ResourceManager.GetObject(ResImage, My.Resources.Culture)
            If obj Is Nothing Then obj = My.Resources.ResourceManager.GetObject(DefaultResName, My.Resources.Culture)
            If obj IsNot Nothing Then
                Return CType(obj, System.Drawing.Bitmap)
            End If
        Catch ex As Exception
        End Try
        Return Nothing
    End Function
    '#Enable Warning BC42105
End Class
সকলকে উত্তর দিন
লেখককে লিখে পাঠান
ফরওয়ার্ড করুন
0টি নতুন মেসেজ