PDA

View Full Version : [SOLVED:] Events handlers not firing on new presentations in Windows 7



neilt17
06-06-2017, 12:52 AM
In an add-in I am writing, I have some ribbon controls which are designed to be activated when text has focus - and otherwise to be inactive. I use the WindowSelectionChange event to trigger reloading of the relevant controls. Unfortunately this does not work for all combinations of Office/Windows.

For Office 2016 on Windows 10, or Office 2010 on Windows 10, this works fine.

For Office 2016 or Office 2013 on Windows 7, I am not getting the WindowSelectionChange event when opening PowerPoint and creating a presentation. In fact, I don't get any event on a reference to an Application object defined with WithEvents after the NewPresentation event. My tests indicate that the relevant variable is still there - and hasn't been reset after the NewPresentation event - just that it no longer gets these events.

Note, if I open an existing presentation, then the events fire as expected, and also having opened an existing presentation and then creating a new presentation that also works as expected.

Any suggestions?

Below details of my tests:

MainModule:




Option Explicit


Public gb_oAppEvents As CApplicationEvents
Public gb_stTestVariable As String


Public gb_boolContextSet As Boolean


Public gb_oMyRibbon As IRibbonUI


Sub RibbonUI_onLoad(Ribbon As IRibbonUI)

MsgBox "RibbonUI_onLoad run"

If gb_oAppEvents Is Nothing Then
Set gb_oAppEvents = New CApplicationEvents
End If

Set gb_oAppEvents.App = Application
Set gb_oMyRibbon = Ribbon

' Check if variable retained:
' (We fined that it is always retained for all versions).
gb_stTestVariable = "Variable set on load"

' Set something on the gb_oAppEvents object for testing:
gb_oAppEvents.stVariableSet = "An Application Events variable was set when the ribbom loaded."

End Sub


Sub NormalControl()

Dim stAppEventsVar As String
stAppEventsVar = ""

' The global app events does not go away - this works after the ribbon has
' been loaded at any point:

If Not gb_oAppEvents Is Nothing Then
stAppEventsVar = vbCrLf & vbCrLf & "The value of the test " & _
"variable on the gb_oAppEvents object is: " & gb_oAppEvents.stVariableSet
End If


MsgBox "You clicked a normal control. The value of the test variable is: " & _
gb_stTestVariable & stAppEventsVar
End Sub


Sub ContextSensitiveControl()
MsgBox "You clicked a context sensitive control"
End Sub


Sub ContextSensitiveAlwaysTrue()
MsgBox "You clicked on the always true context sensitive control"

' We don't lose the object containing the ribbon reference - this
' never gets triggered:
If gb_oAppEvents Is Nothing Then
Set gb_oAppEvents = New CApplicationEvents
MsgBox "Oh dear - we would have lost the ribbon as well!"
End If

' The application object does not go away:
If gb_oAppEvents Is Nothing Then
MsgBox "The application object went away"
Else
MsgBox "The application object did not go away - reset it anyway!"
End If
' reset app property - but this doesn't help - the reference application
' object does not respond to events.
Set gb_oAppEvents.App = Application

End Sub


Sub GetEnabled(Control As IRibbonControl, ByRef returnedVal)


' On Windows 7 this doesn't work - because the App_WindowSelectionChange
' event never gets called - so gb_boolContextSet is never changed.
' It works fine in Windows 10 it seems.
' In all cases this is always called when the ribbon is invalidated.
If Control.Id = "idContextSensitiveControl" Then
returnedVal = gb_boolContextSet
End If

' This works fine:
If Control.Id = "idContextSensitiveAlwaysTrue" Then
returnedVal = True
End If

End Sub



CApplicationEvents Class:



Option Explicit


Private p_stVariableSet As String


Public WithEvents App As Application


Public Property Get stVariableSet() As String
stVariableSet = p_stVariableSet
End Property


Public Property Let stVariableSet(value As String)
p_stVariableSet = value
End Property


Public Sub App_WindowSelectionChange(ByVal Sel As Selection)


' For new presentations - where no existing document is open - this is not
' called on the Office 2016/Windows 7 install. However, if an existing document
' has been opened, before creating a new presentation, then it is called.
' For Office 2016 or 2010/Windows 10, this is called in all situations - i.e.
' for new presentations following opening of PowerPoint as well.

MsgBox "The selection changed."

' This activates/de-activates ribbon controls.
If Application.ActiveWindow.Selection.Type <> ppSelectionText Then
MainModule.gb_boolContextSet = False
Else
MainModule.gb_boolContextSet = True
End If

Dim oRibbon As IRibbonUI
Set oRibbon = MainModule.gb_oMyRibbon

oRibbon.InvalidateControl "idContextSensitiveControl"


End Sub


Private Sub App_NewPresentation(ByVal Pres As Presentation)

' This gets triggered on both Windows 7 and Windows 10 installs

MsgBox "New Presentation"

' This is the last event that seems to get triggered in Windows 7 on first opening
' of PowerPoint and creating a new presentation.


MainModule.gb_boolContextSet = True

If MainModule.gb_oMyRibbon Is Nothing Then
MsgBox "The ribbon isn't recorded."
Else
Dim oRibbon As IRibbonUI
Set oRibbon = MainModule.gb_oMyRibbon
oRibbon.InvalidateControl "idContextSensitiveControl"
End If

End Sub




Private Sub App_AfterNewPresentation(ByVal Pres As Presentation)


' This gets triggered on the Windows 10 install, but not the Windows 7 one.
MsgBox "After New Presentation"

If MainModule.gb_oMyRibbon Is Nothing Then
MsgBox "The ribbon isn't recorded."
Else
Dim oRibbon As IRibbonUI
Set oRibbon = MainModule.gb_oMyRibbon
oRibbon.InvalidateControl "idContextSensitiveControl"
End If


End Sub


This is the ribbon XML:



<customUI onLoad="RibbonUI_onLoad" xmlns="not-allowed-to-post-links">
<ribbon startFromScratch="false">
<tabs>
<tab idMso="TabHome">
<group id="idRibbonVarCheck" label="Ribbon Var Check">
<button id="idNormalControl"
label="Normal"
imageMso="ClipArtInsert"
size="normal"
onAction="NormalControl"/>
<button id="idContextSensitiveControl"
label="Context Sensitive"
imageMso="MailMergeGoToPreviousRecord"
size="normal"
onAction="ContextSensitiveControl"
getEnabled="GetEnabled"/>
<button id="idContextSensitiveAlwaysTrue"
label="Context True"
imageMso="MailMergeGoToPreviousRecord"
size="normal"
onAction="ContextSensitiveAlwaysTrue"
getEnabled="GetEnabled"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>

John Wilson
06-06-2017, 02:43 AM
Seems to work OK here in Windows 7 Office 365

I have attached the file i made from your code and a video of enable working https://www.screencast.com/t/D3rEfPok

neilt17
06-06-2017, 05:28 AM
Brilliant - thank you very much for looking at this - it prompted me to look for an alternative reason - and I think I've found it:

If "Show the Start screen when this application starts" is checked (see File -> Options -> General) then the problem I described occurs, if it is unchecked then it goes away.

neilt17
06-06-2017, 05:39 AM
I found a discussion on this issue...

neilt17
06-06-2017, 05:40 AM
See:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/25511298-fc9d-4737-b4c7-7795e25a9f7b/events-not-fired-in-powerpoint-as-expected-when-a-new-presentation-is-opened-first?forum=officegeneral

John Wilson
06-06-2017, 06:28 AM
Interesting but I'm not seeing that.

I would suggest though that you DON'T use onLoad to instantiate gb_oAppEvents but do it with an Auto_Open Sub which will run when the AddIn loads. (probably earlier)


Sub Auto_Open()
Set gb_oAppEvents.EV = Application
End Sub

neilt17
06-09-2017, 03:34 AM
Great, thank you - Auto_Open() is working consistently across my various installations of office.