intercepting the GetCustomUI callback in a VSTO3 addin - vb.net

I've got a VSTO3 Word addin that makes use of custom ribbons and taskbars, etc.
Now, Office 2010 comes along and there's this nifty new BACKSTAGE concept, which I'd like to hook into. However, from what I can tell, doing it with VSTO requires Vsto 4, which requires VS2010, which isn't an option.
Soooo. I started looking online and have found all sorts of examples of, essentially, piggybacking the backstage XML onto whatever Ribbon xml I define and returning that as the value of GetCustomUI. All good, except if you're using VSTO3, there doesn't appear to be any way to "hook" into the call chain for GetCustomUI. It's all "automagically" handled for you by the OfficeRibbon and RibbonManage classes.
I know I +COULD+ convert the addin to a shared addin and just implement the IDTExtensibility interfaces directly. I'd lose all the vsto goodness (yeah, that's debatable) but I'd gain access to the GetCustomUI call.
Anyone every tried to get access to GetCustomUI +WHILE+ using VSTO though? Is it even possible?
I thought I could create a wrapper class for RibbonManager, but lo, MS has gone and done what looks to be some supreme violation of encapsulation. The RibbonManager implements the nice and easy IRibbonExtensibility interface, and yet, where that interface is passed around, they actually check the passed object to be sure it's of the actual type RibbonManager! Ugh, so much for any kind of wrapper.

Turns out it's possible, just not easy. You have to override the CreateRibbonExtensibilityObject method on connect, as well as the CreateRibbonObjects, and the RequestService methods.
Then, you have to create an object that wraps the built in VSTO RibbonManager object, and implements iReflect to intercept reflection INVOKE calls and forward them on to the underlying RibbonManager.
Finally, on the interceptor object, you have to also implement IRibbonExtensibility, then code up the GetCustomUI method of that interface.
once you do all that, your GetCustomUI will be called and passed in the full XML of the ribbons you've defined via VSTO, which you can then alter directly (in my case I needed to add backstage support), and then return that xml from the function.
definitely not straightforward, but it works.

If you want to edit XML ribbon at runtime in a VSTO app, I have created a simple solution here: Outlook 2007 ribbon customization in .NET using VS2010; insertBeforeMso dynamic function

Related

Can I use an Outlook Add-In from macro code?

Is it possible to execute an Outlook Add-In or access it's properties from within Outlook's own VBA code? Or are Add-Ins completely isolated from macro development?
I am trying to extend the use of the Skype for Business Add-In (UCAddin.dll).
No they are no isolated.
Just add a new COM Object (maybe a singleton) that is supported by your addin, with the interface you need. Use CreateObject inside the macro code and you have access to your special interface and the internals of your addin...
If it is your own addin, then yes - your code can access the Application.COMAddins collection, find the addin, and use COMAddin.Object property. Your addin in turn has to expose an object in that COMAddin.Object property - to do that, it needs to set the property on the COMAddin object passed as a parameter when processing the IDTExtensbility2.OnConnection callback.
That being said, I don't think Skype addin exposes anything through the COMAddin.Object property.
See Walkthrough: Calling Code in a VSTO Add-in from VBA.
You must know public APIs available in add-ins. Or follow the contract/interface which is available publicly.

Scripting MFC Dialogs via COM

MS Word has a very useful mechanism to wrap up its dialog boxes to use via COM or .Net. You can execute a "Display" method - which does the obvious - and also an "Execute" method which is equivalent to pressing "OK". I have a legacy MFC app which I am attempting to attach a COM object model to for scripting and regression testing, and I would like to do the same thing. It has a number of dialogs that I want to control programmatically from my test harness. It's been years since I really delved into MFC, and I can't find anything useful on t'internet so far.
My guess would be to wrap up the CDialog derived classes, perhaps within an ATL class (ATL is used extensively in the project), but I have a suspicion that there may be a better way.
Worst case scenario, I'll move the dialogs to C# and make them COMVisible (which is probably more strategic), but that's going to be more work.
Any thoughts and help appreciated - obviously this is rather antiquated technology!
All CDialog derived classes in MFC are a subclass of CCmdTarget.
CCmdTarget is the baseclass for MFC COM functionality.
There is a lot of work you have to do under the hood. You should define and IDL file for your interfaces, compile the IDL, and then have the compiled typelibrary be a resource in your program.
There are helper macros for your CCmdTarget derived classes like:
DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART()
END_INTERFACE_PART()
BEGIN_INTERFACE_MAP()
INTERFACE_PART()
END_INTERFACE_MAP()
I would say that if you want to see how MFC does it, use the App Wizard and generate an MFC application that has OLE Automation enabled and then look at the generated code. It will show you what you need to wire up your MFC app for OLE Automation.

Where can I find the descriptin of LibreOffice API for BASIC

I wanted to create a few macros for LibreOffice using BASIC. However I cannot find the API description. It is absent in help as well as in interet. When I try to google it I get masses of examples in C++, Java, Python, but not a single www with BASIC.
For example where from can I get the hierarchy of objects and their methods?
LibreOffice Basic uses essentially the same API as PyUNO and Java. That is, they all use the UNO API. To get started, the OpenOffice development guide helpfully describes the two main ways to step into the object hierarchy, the Global variables ThisComponent and, less commonly, StarDesktop. There also is a specialty variant in LO Base, ThisDatabaseDocument. To get the properties and methods of these objects, execute MsgBox oObject.DBG_properties or .DBG_methods. It often is easier to copy the longer lists that are returned by this method into a text editor for searching. You will find that all, or nearly all, of the methods and properties you reveal will be described in the LibreOffice UNO IDL API. The documentation for the API is not that descriptive, but you will be able to fill in some essential details using that resource Every Object has properties that can be reviewed by .DBG_properties.
The key properties for navigating the object hierarchy are .Parent, .Model, .CurrentController and occasionally .Source. The key methods are getByName() and getByIndex(). It also is helpful that events which trigger macros typically return an event object whose source or parent is the object that initiated the macro, for example, a command button. This object can be accessed by referring to it along with the Sub, i.e., Sub SubName (oEventObject As Variant)....

Can I monitor COM calls to my VisualBasic 6 ActiveX control?

I wrote a little ActiveX control in VisualBasic 6 which is going to be used as a plugin for some 3rd party framework. The framework expects that my control exposes a few properties and methods. It all seems to work well except that one of my properties seems to be ignored.
In C++, I could put debug statement into the reimplementations of IDispatch::GetIDsOfNames and IDispatch::Invoke to see which members the framework attempts to access - maybe the documentation is wrong, and it's expecting a different property name or something.
Is it possible to monitor the accesses to COM properties/methods in Visual Basic 6, too?
The easiest way is to add logging of some form in the methods/properties in question. I don't think you can hook the lower level COM calls though.
For the logging, you can use OutputDebugString().
There's a rather old 'Hardcore Visual Basic' book around that teaches you exactly how to implement IUnknown, IDispatch etc. in VB5/6.

Is it possible to access the My.Application object from a Form or Control object?

I have a solution with several Projects in it. There is a Windows App project (called ImportClient), and a Class Library (Import.Library). The Import.Library has functions to perform data imports (I have other applications in the solution that also need to call it). But the interactive application, I want to be able to pass in some form controls, and have it update the GUI. No problem. But, I also want to execute a DoEvents() so that the loop execution doesn't hang other interaction to the app.
So, ImportClient has a reference to Import.Library. But I can't add a reference to ImportClient to the Import.Library, because the compiler complains about circular reference, etc. I don't know how else to define the My.Application object of ImportClient as a parameter to the data function in ImportLibrary.
(I realize this is a dumb question - problem is, for this project I have a tight timeline, and haven't learned how to do the BackgroundWorker process. If you think I could pick it up quickly, I'm open to some hints about how to update the progress bar on the GUI, and how to pause / cancel the background task.)
Application.DoEvents is a static method, you don't need an instance of Application to call it, so why not simply add a reference to System.Windows.Forms to access it?
I'd thoroughly recommend finding the time to learn about threading and asynchronous operations, Application.DoEvents is not the silver bullet for keeping your UI smooth...