VBA processing of PowerPoint objects on copy/paste but not on insertion

I have a need to 'do stuff' with certain on-slide objects when they are copy/pasted into a deck and I am currently doing this as follows:

1. Setting up the application event WindowSelectionChange
2. When the event fires, checking to see if the object has my custom Tag property set
3. If it doesn't, do 'the stuff' with the selected object and then tag it to make sure it's only processed once

This all works really well but I want to differentiate objects that have been selected as a result of being inserted by the user from the PowerPoint UI e.g. Insert / Shape versus those that have been selected as the user pastes them from another source to the slide.

Anyone have any bright ideas?
LVL 15
Jamie GarrochSenior Technical Consultant at BrightCarbonAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gowflowCommented:
could you post your window selection change code ?
or whatever code you have there ..

gowflow
Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
Basically, it's like this:

' This event gets fired through user interactions when:
' 1. A different existing object within a presentation is selected
' 2. A new object is created e.g. via Insert / Shape
' 3. An existing object from another presentation is pasted to the active presentation
' Question : how to differentiate #2 and #3?
Private Sub PPTEvent_WindowSelectionChange(ByVal oSel As Selection)
  With oSel
    If .Type = ppSelectionShapes Then
      If .ShapeRange.count = 1 Then
        If ShapeHasTag (.ShapeRange(1)) Then DoStuff Else AddTag .ShapeRange(1)
      End If
    End If
  End With
End Sub

Open in new window


The function ShapeHasTag returns true if it finds my specific tag while the function AddTag, well, adds my specific tag. The DoStuff sub changes properties of the object.

The problem isn't with any of this code though. The problem is that I can't differentiate the WindowSelectionChange when a shape is selected as a result of it being inserted by the user versus pasted by the user.
gowflowCommented:
ok I tried to simulate something but hv not done dev on powerpoint and noticed that you need to create either a module of a userform to get events as unlike Excel you do not have a basic form or model that have predefined events.

Could you post your presentation file or at least indicate where this code is lying as could not see events in Powerpoint. ?

I have an idea on how to be able to differentiate between what you ask but need to test it practically reason for my request.

gowflow
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
PowerPoint application events require class module and standard module code to set them up. I wrote an article about that here : http://www.experts-exchange.com/articles/17410/Initializing-PowerPoint-Events-with-VBA-and-Ribbon-XML.html
gowflowCommented:
ok great article Bravo !!
so to sum it up you used in your current Presentation file
instead of this:
Public WithEvents App As Application

You used this ?
Public WithEvents PPTEvent As Application

pls confirm order to move ahead.
gowflow
Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
In a class module called cEventClass:

Public WithEvents PPTEvent As Application

Open in new window


In a standard module:

Public cPPTObject As New cEventClass
Public Sub InitApp
  Set cPPTObject.PPTEvent = Application  
End Sub

Open in new window


Events are then initialised by calling InitApp
gowflowCommented:
I thought I could get away with the CutCopyMode property of the application but seems Powerpoint is too restrictive and don't use this property and also noticed you had posted a question on the Clipboard content and you alone answered it .... :) I even tried to declare a public variable oExcel as Excel.Application and put in the the class module but even if you press Cut or Copy the value of oExcel.Application.CutCopyMode still return 0 as the Coppy/Cut is being done in the Powerpoint environement and not the Excel one. I tried to lookup the net to see if any way to trap the content of the clipboard in Powerpoint but was not successful.

Sorry but seems you are a lonely in this Powerpoint world !!!!

Attached is the small sample I tried to build to find a way thru but no unfortunately no luck. Sorry. (You need to change the extention from .ppt to .pptm even EE don't allow attaching this type as not listed !!!! :(

gowflow
test.ppt
Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
Thank you very much for trying all of those ideas gowflow :-)

You're right that (a) PowerPoint VBA is very different from Excel and (b) that there are many many many fewer developers in the PowerPoint domain. Regarding your last point, I have been dealing with EE admin staff since November 2014 in an attempt to get them to add the macro-enabled extensions for the PowerPoint files. At one stage they even said it was complete, but in fact, no.
regmigrantCommented:
you two are way ahead of my coding skills but having read you article on initializing events I wondered if you could trap the 'insert' from the ribbon control and tag the shape there so when its picked up again later without a tag you 'know' its pasted
Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
If you mean trap a specific UI event that's not exposed in the application events such as the Insert Shape event click then I'm not sure if/how this is is possible?
regmigrantCommented:
I meant intercept the event when the insert button is pressed and do some pre/post processing:-
https://www.add-in-express.com/creating-addins-blog/2012/02/27/how-an-office-add-in-intercepts-clicking-a-built-in-control/

I'm only putting it forward because you seemed to reach an impasse :)
Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
That's a very interesting article regmigrant. The snippet of code indicating that one can tap into the MSO control event is very exciting:

private void ribbonCommandFileSave_OnAction(object sender,  IRibbonControl control, bool pressed,  ADXCancelEventArgs e)
{
    MessageBox.Show("You've invoked the Ribbon command FileSave ");
    e.Cancel = true;

Open in new window


But I could not initially make this work in VBA.

Here's what I tried:

1. Added a <commands> section to the ribbon UI XML to "repurpose" commands as per this MSDN article. I used this simple example as a test:
<customUI onLoad="onLoadTest" xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <commands> 
    <command idMso="FileSave" onAction="mySave" /> 
  </commands>
</customUI>

Open in new window

2. Added a sub procedure to my pptm file as follows:
Sub mySave()
  MsgBox "Test"
End Sub

Open in new window

3. When opening the PPTM file and clicking the save button nothing happens. This is good because it's not saving the file and means the repurpose command is partially working. But, my my sub is not being executed because no message is seen.
4. I tried with a different repurpose-specific callback signature is stated in this MSDN article but still no message:
Sub mySave(control As IRibbonControl, ByRef CancelDefault)
  MsgBox control.Id
End Sub

Open in new window

5. Then a light bulb moment. My security is set to disable unsigned macros so I signed the project and bingo, it works!

So, this is the solution form my original question to trap the paste operation:

XML part:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <commands> 
    <command idMso="Paste" onAction="RepurposePaste" /> 
  </commands>
</customUI>

Open in new window


VBA part:

Sub RepurposePaste(control As IRibbonControl, ByRef CancelDefault)
  ' Do things required after detecting paste
  
  ' Allow the paste to continue
  CancelDefault = False
End Sub

Open in new window

Thank you for the pointer in the right direction.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
regmigrantCommented:
Thanks Jamie, I'm glad you got what you needed. I think your outline of progress is great - you should consider penning an article on Ribbon Fiddling :)

Just one follow up - does the 'repurpose paste' also fire when 'right clicking, pasting' rather than from the ribbon?
Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
My comment is the only one which actually includes the required code to address the original question but I wouldn't have discovered how to write it without the preceding comment from regmigrant
Jamie GarrochSenior Technical Consultant at BrightCarbonAuthor Commented:
Hi regmigrant. I'm just back in the office after a week out so sorry for the delayed response. I did already write an article based on my repurposing experiences :-)

Intercepting Office Ribbon Control Events with VBA using "Repurposing" Commands
http://www.experts-exchange.com/articles/21499/Intercepting-Office-Ribbon-Control-Events-with-VBA-using-Repurposing-Commands.html

I also have others on the ribbon fiddling ;-)

As for your question, the repurposing works for the paste command using the idMso "Paste", regardless of the UI trigger. So the following methods work:

Clicking the top part of the Paste split button
Pressing Ctrl+V

But, the lower part of the Paste split button and right click (and Alt combinations such as Alt+H+V+H) are actually sub menus containing context sensitive buttons that are not using the same idMso so they will not fire unless you add a new repurposing command and corresponding idMso to the XML. Below are all the button IDs I found for PowerPoint 2010 that contain the word "Paste" and although I tried PasteSourceFormatting and PasteDestinationTheme, I couldn't get the right click paste buttons to fire:

PowerPoint 2010 control names containing the word "paste"
I did however manage to get the PasteSpecialDialog to fire.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft PowerPoint

From novice to tech pro — start learning today.