How can I subscribe to an Open event of a Word Backstage using a Ribbon (Visual Designer) object? - ms-word

I want to add a button to the Word Backstage. That button is supposed to be enabled/disabled only when one or more Word documents are open in Word.
Is there some event I can use to set the state of my Backstage controls the moment the Backstage is displayed?
NB: As a workaround, I could subscribe to the DocumentOpen event, but not to a DocumentClose event, as it doesn't exist. So that solution isn't safe to use.

The backstage UI provide the onShow callback which you may find helpful.
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
<backstage onShow="Backstage_OnShow">
<tab idMso="TabSave">
...
Also you may find the onHide callback helpful:
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
<backstage onHide="onHide" onShow="onShow">
...
</backstage>
</customUI>
The callback should have the following signature:
public void Backstage_OnShow(object contextObject) {
}
You can use the IRibbonUI.Invalidate method to get your callbacks invoked. For example, if an add-in writer implements the getEnabled callback procedure for a button, the function is called once, the state loads, and then if the state needs to be updated, the cached state is used instead of recalling the procedure. This process remains in place until the add-in signals that the cached values are invalid by using the Invalidate method, at which time, the callback procedure is again called and the return response is cached. The add-in can then force an immediate update of the UI by calling the Refresh method.
Read more about that in the Dynamically Changing the Visibility of Groups and Controls in the Office 2010 Backstage View article.

Related

word object model - active document event when clicking on FILE

I'm developing an MS Word add-in. In newer MS Word editions, there is the "FILE" option in the menu bar which opens an interface where you can select a recent document to open, open a new one, or an existing one. I am trying to find a way, through which I can know WHEN the user "leaves" the current document he is editing clicking on the FILE menu of Word. I cannot seem to find such an event. Is there a way to achieve this ?
The WindowDeactivate does not fulfill this purpose.
The reason I want to do this, is because for a custom spellchecker I'm writing, I'm highlighting the wrong words in an transparent (click through as well) form. So when the user in a recent version of Word clicks the FILE menu, the highlights are still there, as seen in the screenshot
TL:DR; is there a way to detect in MS Word when the user clicks the FILE option in the menu and the current document is not visible? I'm using add-in-express, so all the relevant word object model API is available.
I wonder how can I solve this, any help is appreciated.
edit: screenshot
Yes, you can detect and then execute code both when the File menu is clicked (displaying the Backstage View) and when the View's return arrow is clicked to remove the Backstage View and display the document. To do this use the onShow and onHide attributes with callbacks via a custom XML ribbon in your VSTO project (this will not work with a ribbon made with the Visual Designer).
Reference material can be found here:
Performing Actions When the Backstage View is First Displayed or Hidden
As this article uses VBA to expand on the concepts involved, I built a sample project demonstrating how onShow works using C# and Word 2016 (the documentation was written for Office 2010, but onShow and onHide will work in later versions of Word).
Solution Tree
Custom XML Ribbon (BackstageRibbon.xml)
Note that the <backstage> node, which activates the onShow attribute for the callback, follows the <ribbon> node in the XML.
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"
onLoad="Ribbon_Load">
<ribbon>
<!--Ribbon XML goes here-->
</ribbon>
<backstage onShow="onShow">
</backstage>
</customUI>
Ribbon Code (BackstageRibbon.cs)
A bunch of this code is boilerplate, however public void onShow is the callback that executes your code based on the onShow attribute in the ribbon's custom XML. Also, public string GetCustomUI is where the C# is told to find the XML.
namespace Backstage_Events
{
[ComVisible(true)]
public class BackstageRibbon : Office.IRibbonExtensibility
{
private Office.IRibbonUI ribbon;
public BackstageRibbon()
{
}
#region IRibbonExtensibility Members
public string GetCustomUI(string ribbonID)
{
return GetResourceText("Backstage_Events.BackstageRibbon.xml");
}
#endregion
#region Ribbon Callbacks
//Create callback methods here. For more information about adding callback methods, visit https://go.microsoft.com/fwlink/?LinkID=271226
public void Ribbon_Load(Office.IRibbonUI ribbonUI)
{
this.ribbon = ribbonUI;
}
public void onShow(object contextObject)
{
//Code to be executed before Backstage View displays goes here
MessageBox.Show("Backstage Display Event Triggered!");
}
#endregion
Helpers //Region
}
}
ThisAddin.cs
You will also need to add:
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new BackstageRibbon();
}
after the ThisAddIn_Startup and ThisAddIn_Shutdown private voids in the ThisAddin.cs class to instantiate the custom ribbon.
Word will fire the Application.DocumentOpen event - you can see it live in OfficeSpy (I am its author - click Application button, go to the Events tab, look at the log at the bottom of the window).

How to use children editor on a list component's dialog on AEM?

I am trying to enable children editor on a list component's dialog to allow users to add custom component into it, like the carousel component from core.
I use AEM 6.5, and the sling:resourceSuperType is list from core.
My .context.xml of the component is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
cq:isContainer="{Boolean}true"
jcr:primaryType="cq:Component"
jcr:title="List"
sling:resourceSuperType="core/wcm/components/list/v2/list"
componentGroup="MyContent"
teaserDelegate="thisPackage/components/content/teaser/v1/teaser" />
The HTML file of the list component, which is named "list.html" is as follow:
<sly data-sly-use.list="com.thisPackage.aem.dna.core.models.v1.List"
data-sly-use.template="core/wcm/components/commons/v1/templates.html">
<sly data-sly-resource="${resource.path # resourceType='wcm/foundation/components/parsys/newpar', appendPath='/*', decorationTagName='div', cssClassName='new section aem-Grid-newComponent'}"
data-sly-test="${wcmmode.edit || wcmmode.preview}">
</sly>
</sly>
I could open the component's dialog on edit mode. however, if I add new components to the new children editor on dialog and try to close the dialog. I can't close the dialog.
The error message is:
org.apache.sling.api.resource.PersistenceException: Unable to commit changes to session
I followed the example in "github.com/adobe/aem-core-wcm-components/issues/696", and move editConfig from carousel to my list component. But, it didn't solve the issue.
What can I do?
This is not working because the servlet which is responsible for updating data is of resourceType = core/wcm/components/carousel/v1/carousel
You can see in the network call that XHR request is sent to the server which has url like :
http://localhost:4202/content/we-retail/language-masters/en/jcr:content/root/responsivegrid/carousel.container.html
As you can see a selector container is sent and underlaying servlet :
https://github.com/adobe/aem-core-wcm-components/blob/master/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/servlets/ContainerServlet.java
is listening to only core component resource-type.
In your case it is custom component, hence resource type does not match and hence you get the error.
Two things are possible:
1: Quick and easy is to just use sling:resourceSuperType = core/wcm/components/carousel/v1/carousel
Create custom clientlibs same as this:
/apps/core/wcm/components/commons/editor/dialog/childreneditor/v1/childreneditor/clientlibs
but change var POST_SUFFIX = ".container.html"; to your own selector
and then create your own servlet (registered to your own defined selector) same as the core component.
Hope it helps!
This is a bug on AEM 6.5, and the team is working on it.
https://github.com/adobe/aem-core-wcm-components/issues/985

How to re-direct events from one control to another control in PowerBuilder?

A button control can trigger event of a datawindow control with TriggerEvent() function.
The button control in my code was set as child object of DataWindow control with SetParent win32 API function. SetParent external function moves button from window to datawindow control but after SetParent the code that was already written for Clicked event is not working anymore. That is why i need to redirect the clicked event of button to buttonclicked event of datawindow.
There is good example of redirecting event by using win32 API calls. here is the link http://bitmatic.com/c/redirecting-mousewheel-events-to-another-control i need to do the same thing in PowerBuilder.
Can someone see that code or help me to redirect events the way i want?
You're doing things the hard way. Find the name of the datawindow control (e.g. dw_1), and from the command button just issue dw_1.event buttonclicked ( args ).
Better yet, move the code to a function in the parent object. Controls are navigation objects, they really shouldn't have too much code in them (IMHO), but fire off methods on the parent object.

How do i notify eclipse that an element was created

what is the standard way in eclipse to notify a view that an elment was added. In my cases i have one view in which items are created (tree viewer). Once that is done all other interrested parties shall be informed.
In another case all interrested views shall be informed if the data in an editor was changed. Should this be the save of an completly new object than this new item shall be added to a view.
What is the best way to do this without implmenting my own listener mechanism?
In your viewer's content provider there is a method:
public void inputChanged(Viewer viewer, Object oldInput, Object newInput);
According to the documentation:
Notifies this content provider that the given viewer's input has been
switched to a different element.
A typical use for this method is registering the content provider as a
listener to changes on the new input (using model-specific means), and
deregistering the viewer from the old input. In response to these
change notifications, the content provider should update the viewer
(see the add, remove, update and refresh methods on the viewers).
You can use this method to notify other classes that your input has changed. (i.e. - an element was added .. )

Handle File->New in Word 2007

I am writing a VSTO addin for Word 2007. When the user selects File->New, (or selects it from the quick access toolbar) I need to display a custom form instead of the standard new document dialog. How do I do this? I don't see an application event I can handle and I can't seem to find the buttont to add an event handler too.
Ok, just found it. You need to create a Ribbon xml and then add commands for those buttons. In this case the ribbon xml is
<commands>
<command idMso="FileNew" onAction="FileNewOverride"/>
<command idMso="FileNewDefault" onAction="FileNewOverride"/>
</commands>
and the code behind is
public void FileNewOverride(Office.IRibbonControl control, ref bool cancelDefault)
{
//do something
}
This how-to on MSDN shows you how to do it http://msdn.microsoft.com/en-us/office/dd361753.aspx