momsoft
Posts: 79
Joined: 2004-06-16
|
I have received so much support on this forum that I wanted to share the solution I have found to a very annoying problem caused by the new AutoSave feature introduced in Office 2016 in case it is of interest to other users.
The scenario is as follows; my add-in, PowerTOC, creates table of contents and agenda slides for presentations. The generation of these slides can take potentially a few seconds and involves deleting and recreating slides. On the other hand, it is very important to update the slides whenever the presentation changes in case the presentation is used on a system that has not the add-in installed.
So far, I have simply used the BeforeSave event to update the presentation, just before the save operation.
But on presentations that have the AutoSave feature turned on, this strategy is no longer viable because PowerPoint will trigger the BeforeSave every few seconds. It is very easy to prevent this behavior by simply checking the Presentation.AutoSaveOn property inside the event handler (see below).
But this does not solve the problem, because the user is forced to update the TOCs and agendas manually.
The other alternative is to use the BeforeClose event. This is only called when the user has finished working with the presentation so it is a good candidate. The problem is that changing a presentation inside the BeforeClose event causes a loop, see https://docs.microsoft.com/en-us/office/vba/library-reference/concepts/how-autosave-impacts-addins-and-macros.
To make things worse, it seems that the AutoSaveOn property gets turned off when modifying the presentation on the OnBeforeClose event.
After many tries, the solution I have found involves using three events, an auxiliary function and a new global variable to store the presentation being closed.
Ausiliary function
function CheckAutoSave(Pres: _Presentation) : boolean;
var
varPres : OleVariant;
begin
result := false;
if self.HostMajorVersion < 16 then exit;
varPres := Pres;
try
if varPres.AutoSaveOn then
result := true;
except
// This code could potentitally cause an exception if a future implementation removes the AutoSaveOn property
end;
end;
OnBeforeSave
if not CheckAutoSave(Pres) and (closingPresentation = '') then
UpdateTOCs;
OnBeforeClose
if CheckAutoSave(Pres) and (closingPresentation <> Pres.FullName) then begin
closingPresentation := Pres.FullName;
UpdateTOCs;
end;
OnCloseFinal
closingPresentation := '';
So, at the end it was not very difficult but it took me some time to figure it out. I hope it helps. Note that this solution applies to other Office products, not only PowerPoint.
NOTE: It is possible to completely remove the OnBeforeSave event handler to simplify the solution, but I wanted to maintain the old behaviour for presentations that have not the AutoSave feature enabled. |
|
Andrei Smolin
Add-in Express team
Posts: 19098
Joined: 2006-05-11
|
Thank you, Manuel!
Andrei Smolin
Add-in Express Team Leader |
|