Problem with Windows Media Player ActiveX control in VBA Powerpoint - vba

it's me and my projects for school again. This time I wanted to insert a video into PowerPoint using file path via WMP ActiveX, so I drew one as follows: (uiMode set to "none")
When the slide show starts, I transfer all data from an Excel file to the presentation, including the paths to the video. Then I hide the WMP with Slide85.WMP.uiMode = "invisible".
When the time comes, I want the WMP to appear at the original size that i drawn and the linked video to play, so I used these codes:
Slide85.WMP_TT.uiMode = "none"
Slide85.WMP_TT.URL = "C:\inetpub\wwwroot\TT2.mp4"
Slide85.WMP_TT.Controls.Play
Already muted the video by changing the settings in the Properties tab.
Then the result came out like this:
The video still plays, but only with sound, which is impossible because I muted the control. No visual images is shown from the video, and the control's dimensions changes too.
As of now I cannot think of any causes to this problem. Please help me, I'd be very grateful.

As mentioned on this Microsoft help page, you have to set height and width parameters in code for the player to reserve the space when triggering uiMode="invisible": Player.uiMode
As an alternative, you can draw the size as you have done, then use VBA to hide or show it on the slide with code like this:
Sub HideWMP()
Dim oSlide As Slide
Dim oShape As Shape
For Each oSlide In ActivePresentation.Slides
For Each oShape In oSlide.Shapes
If oShape.Type = msoOLEControlObject Then
oShape.Visible = msoTrue
End If
Next oShape
Next oSlide
End Sub

Related

Bring forward an object by clicking a button in Powerpoint

I have a PPT presentation with some slides. In each slide I have some superposed images and some buttons (see example image).
I would like to "bring to front" an image when the corresponding button is clicked.
I have been triying with animations, but unfortunately there is no animation to run this action.
After some 'investigation' I think that the only way to achieve that is by a macro.
I have absolutely no experience in VBA programming, but after some search I found out the way to 'bring to front' an image of the active slide by doing:
Sub Bring_front()
Dim sld As Slide
Set sld = Application.ActiveWindow.View.Slide
sld.Shapes("NUCLEI").ZOrder msoBringToFront
End Sub`
Then I insert an action (to execute the macro) to the correspoding button and everything works fine!
The problem is that in my real presentation I have many images and buttons (like 10 for slide)... and I would like to create a macro with if/else statements in order to run an statement if a button is clicked.
I have also been searching how to do that but I have not been able to get it.
Is it possible to do something like that?:
Sub Bring_front()
Dim sld As Slide
Set sld = Application.ActiveWindow.View.Slide
if Greenbutton is clicked Then
sld.Shapes("GREEN_IMAGE").ZOrder msoBringToFront
elseif Redbutton is clicked Then
sld.Shapes("RED_IMAGE").ZOrder msoBringToFront
elseif Bluebutton is clicked Then
sld.Shapes("BLUE_IMAGE").ZOrder msoBringToFront
end
End Sub
Can someone help me with this, please?
Thank you in advance!
Maria
It's actually quite simple:
Add a new module in the VBA editor and paste this into it:
Sub MoveToTop(oSh As Shape)
Call oSh.ZOrder(msoBringToFront)
End Sub
Then assign this MoveToTop macro as an action setting on each of the shapes you want to be able to adjust.
That's it.
Well, almost. If you're on a Mac and find that this doesn't work, it's because some things in the Mac version of PPT are broken. In that case, try this, which should work ok in Windows versions of PPT also:
Sub MoveToTop(oSh as Shape)
Dim oSl as Slide
Dim oShTemp as Shape
' oSh.Parent returns a valid reference to the shape's host slide:
Set oSl = ActivePresentation.Slides(oSh.Parent.SlideIndex)
' and oSh.Name works:
MsgBox oSh.Name
' So we use those two bits to get a reference
' to the clicked shape like so
Set oShTemp = oSl.Shapes(oSh.Name)
Call oShTemp.ZOrder(msoBringToFront)
End Sub

Using variables inside .Slides & .Shapes methods in Powerpoint VBA

I am working on an interactive Powerpoint Presentation where the user will click on a thumbnail of photo and be able to view it nearly full screen. I'm having difficulty with .Shapes and .Slides methods.
I want several smaller images to appear on one slide in the presentation. If the user wants to view it very large they just need to click on the image. I would then like the image to appear on it's own newly generated slide as large as it can fit on that slide. When they click the larger image, they will be taken back to the smaller images slide they were viewing. This is easily enough achieved by making a separate full sized image slide for every small image in the show and simply calling the large slide number when the small image is clicked; however it is time consuming and makes the presentation far larger than it needs to be. If a user never clicks to see the enlarged image, then the page with the large image is taking up space. I've opted to execute vba code when an image is clicked on that is supposed to:
copy the image
create a new slide after the last slide in the presentation
paste the image into the new slide
resize the image as large as it can fit on the screen
view the new slide with larger image
send the user back to the slide
they started on.
Code:
Sub ViewFullSize()
Dim pptNewSlide As Slide
' Dim objCurrentSlideIndex As Integer
' objCurrentSlideIndex = ActiveWindow.Selection.SlideRange.SlideIndex
With ActivePresentation
.Slides(2).Shapes("Picture 7").Copy
.Slides(4).Shapes.Paste
End With
Set pptNewSlide = ActivePresentation.Slides.Add(ActivePresentation.Slides.Count + 1, ppLayoutCustom)
ActivePresentation.SlideShowWindow.view.Last
End Sub
This code executes and does what is epected. My issue is, I need the slide numbers and shape numbers to be variables. I don't want to rewrite this snippet of code for 100's of photos that could be clicked on. I've tried to make the current slide a variable like this:
Dim objCurrentSlideIndex As Integer
objCurrentSlideIndex = ActiveWindow.Selection.SlideRange.SlideIndex
With ActivePresentation
.Slides(objCurrentSlideIndex).Shapes("Picture 7").Copy
.Slides(4).Shapes.Paste`
End With
The variable I tried .Slides(objCurrentSlideIndex) causes the whole subroutine not to execute, but doesn't crash the slideshow. I've used Set and a slew of other syntax and can't get it to use a variable instead of a plain number. Is there a way to do this? Can the .Slides() and .Shapes() methods even use variables? I've read several of Microsoft's and PPTools pages, but can find no examples using variables.
Sub ViewFullSize(objCurrentShape As Shape) ' Place shape clicked on into variable.
Dim pptNewSlide As Slide
Dim objCurrentSlideNum As Integer
Dim objLastSlideNum As Integer
' Place current slide number into a variable.
objCurrentSlideNum = ActivePresentation.SlideShowWindow.view.CurrentShowPosition
' Send shape to clipboard for later pasting.
ActivePresentation.Slides(objCurrentSlideNum).Shapes(objCurrentShape.Name).Copy
' Place new blank slide at the end of the presentation.
Set pptNewSlide = ActivePresentation.Slides.Add(ActivePresentation.Slides.Count + 1, ppLayoutCustom)
' Make the new slide the active slide.
ActivePresentation.SlideShowWindow.view.Last
' Place the new slide number into a variable.
objLastSlideNum = ActivePresentation.SlideShowWindow.view.CurrentShowPosition
' Paste the shape image from the clipboard onto the new slide.
ActivePresentation.Slides(objLastSlideNum).Shapes.Paste
End Sub
I stumbled onto a snippet of code that showed when a shape was clicked, it could pass its identifiers directly into the subroutine and be assigned to a variable. In my case (objCurrentShape As Shape). This could then be used with the .Shapes() method that I used to call the shape for copying .Shapes(objCurrentShape.Name).Copy.
The .Slides() method was simpler to assign to a variable (or so I believe) because it was not dependent on which shape was clicked. It's merely the active slide number and was attained with the .View.CurrentShowPosition function.
This code can now be assigned to any number of shapes on a slide and will copy and past that shape to a newly created blank slide at the end of your presentation for further manipulations.
Fully working code!
For anyone interested this is the finished (maybe not gleaned), fully operational code that I have working in Powerpoint 2017.
This was designed to be assigned as a Macro Action to pictures in a slideshow. When there are multiple smaller sized images on a page, they can each be assigned this one macro that will show the image full screen on it's own slide and then send the user right back to the screen they were on that contains the smaller images. It's sort of like a full screen zoom function.
It's documented as well as I can document to allow anyone to follow allong with what's taking place at each step. Edits for proper wording and terminology are welcome if I have stated anything incorrectly.
This is not specific to my machine or paths or anything like that. You can simply copy and paste into a module in powerpoint and start assigning the new macro to any images in your presentation.
Sub ViewFullSize(objCurrentShape As Shape) ' Place shape clicked-on into variable.
' Credit Shyam Pillai # http://www.skphub.com/ppt00040.htm#2 for the method of
' bringing the shape into the macro as a variable allowing easier manipulation.
Dim pptNewSlide As Slide
Dim objCurrentSlideNum As Integer
Dim objLastSlideNum As Integer
Dim objLargeView As Shape
' Place current slide number into a variable.
objCurrentSlideNum = ActivePresentation.SlideShowWindow.view.CurrentShowPosition
' Copy shape to clipboard for later pasting.
ActivePresentation.Slides(objCurrentSlideNum).Shapes(objCurrentShape.Name).Copy
' Place new blank slide at the end of the presentation.
Set pptNewSlide = ActivePresentation.Slides.Add(ActivePresentation.Slides.Count + 1, ppLayoutBlank)
' Make the new slide the active slide.
ActivePresentation.SlideShowWindow.view.Last
' Place the new slide number into a variable.
objLastSlideNum = ActivePresentation.SlideShowWindow.view.CurrentShowPosition
' Paste the shape image from the clipboard onto the new slide.
ActivePresentation.Slides(objLastSlideNum).Shapes.Paste
' Put pasted image into a variable.
Set objLargeView = ActivePresentation.Slides(objLastSlideNum).Shapes(1)
' Full credit for this next section of the code goes to PPTools & David Marcovitz
' # http://www.pptfaq.com/FAQ00352_Batch_Insert_a_folder_full_of_pictures-_one_per_slide.htm
' Thanks for the hard work!
' Manipulate the image using the variable.
With objLargeView
' Set mouse-click action on image to return user back to the slide they came from.
.ActionSettings(ppMouseClick).Action = ppActionLastSlideViewed
' Reposition the image for proper resizing
.Left = 0
.Top = 0
.ScaleHeight 1, msoTrue
.ScaleWidth 1, msoTrue
' Resize the image to full screen while maintaining aspect ratio.
' This is wide screen mode. If you are working with the more
' narrow mode, simply change the 9 to a 3 and the 16 to a 4
' to keep the correct aspect ratio.
If 9 * .Width > 16 * .Height Then
.Width = ActivePresentation.PageSetup.SlideWidth
.Top = 0.5 * (ActivePresentation.PageSetup.SlideHeight - .Height)
Else
.Height = ActivePresentation.PageSetup.SlideHeight
.Left = 0.5 * (ActivePresentation.PageSetup.SlideWidth - .Width)
End If
End With
' From here, the slideshow is now showing the originally clicked-on image
' full screen on its own page waiting for the user to click on it to return
' to the rest of the show. If the slideshow isn't set to kiosk mode, then
' there is the possibility of the user clicking somewhere on the screen out
' of the picture area and it would end the slideshow.
End Sub

MS Word VBA code to align image to top right corner

I was trying to write a VBA macro to align an image to the top right corner of the page and set text wrapping to "Behind Text" and "Fixed Position on Page."
Normally I select the image and do all those settings through dialog boxes. But it gets tedious after a while. I'm wondering if there's a way to do it programmatically. I'm hoping I could open the page header, paste in my header image, and then click a macro button to have the macro align the still-selected image.
I tried recording a macro of my operations, but the macro did not record any of my dialog actions (behind text, fixed page position, etc). So that method provided no solution. I tried it with images inside and outside of page headers, without success.
Is it possible to have some VBA code align the currently selected image object? Ideally, I would open up the page header, paste in my header image, and run a VBA macro to do the four operations above (behind text, fixed position on page, align top to page, align right side to page). I'm hoping someone can show me how or point me to some documentation or examples that show how to do it.
UPDATE
I couldn't post to the forum for some reason, so I worked on the problem for a couple of days and finally pieced together this solution for the next person. I wish I knew where to look in a manual or tutorial for this kind of thing.
But the only way seems to be to cobble solutions together from forums on the net. Here's my contribution! :-)
Sub AlignTopRight()
' Paste an image into Word so it is still selected
' Then invoke this macro to align it to the top right corner
' And to set it behind text, fixed position on the page
Application.ScreenUpdating = False
Dim Shp As Shape
On Error Resume Next
'I'm not sure if this block is required, but it works
Set Shp = Selection.InlineShapes(1)
If Not Shp Is Nothing Then
Set Shp = Selection.InlineShapes(1).ConvertToShape
Else
Set Shp = Selection.ShapeRange.Item(1)
End If
If Not Shp Is Nothing Then
With Shp
.LockAspectRatio = True
' for absolute positioning
'.Left = CentimetersToPoints(5.5)
'.Top = CentimetersToPoints(0.5)
'.Width = CentimetersToPoints(2.5)
'put the image behind text
.WrapFormat.Type = wdWrapBehind
'this was the tricky part, discovering this
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Top = wdShapeTop 'if you say =0, it sets the AbsolutePx in the dialog
.Left = wdShapeRight 'these wdShapeXX objects set the Align field in the dialog
End With
End If
Set Shp = Nothing
Application.ScreenUpdating = True
End Sub
Just discovered this feature to answer my own question. See the answer in the question posting.

Auto Update every picture in a PowerPoint Slideshow

I have a very large and complex PowerPoint with a full size image as the background for every individual slide. I have a directory full of these background pictures, which are all JPEG's. Sometimes I change these photographs, which are made with Photoshop, and when I change them, I save them over the original JPEG in the same directory.
I then have to update them in the PowerPoint. The manual functios to do this is to right-click the photograph, and click replace photo, then pick the new JPEG from the file menu. I want to write a macro in Visual Basic that will go through the entire slideshow, and reload the graphic from the updated JPEGs, without me having to do it manually. I don't know if it is possible, because I don't know if PowerPoint actually remembers the path and filename of each picture that it places.
Is there a picture property which contains the path and filename that was used to paste the picture in the first place? If there is, I could find that property, query it, and use that as the path to reload and thereby update the picture recursively all the way through slide by slide.
Would this be possible?
Is there a picture property which contains the path and filename that was used to paste the picture in the first place?
Not that I'm aware of, but you can create your own, using the Tags property:
http://msdn.microsoft.com/en-us/library/office/ff744290(v=office.15).aspx
You will have to assign a custom tag for each slide, like:
Sub AssignTag()
Dim sld as Slide
Set sld = ActivePresentation.Slides(1)
sld.Tags.Add "img_location", "C:\files\image1.JPG"
End Sub
Once the slide's Tags have been configured, then you can do something like this to update from that location:
Sub UpdateJPGs()
Dim sld As Slide
Dim path As String
For Each sld In ActivePresentation.Slides
path = sld.Tags("img_location")
If Not path = vbNullString Then
On Error Resume Next
sld.Background.Fill.UserPicture path
If Err Then
MsgBox "Unable to update slide #" & sld.SlideNumber
Err.Clear
End If
On Error GoTo 0
End If
Next
End Sub

Programmatically copy shapes with source formatting (PowerPoint 2007)

I need to be able to copy shapes (chart, table, etc.) programmatically from one slide to another in PowerPoint 2007 keeping their original colors. The source and destination slides are in different presentations which have different themes.
These shapes might be complex and include a lot of colors, e.g., charts, tables, etc. The destination slide must maintain its theme, so I cannot simply copy the entire original slide colorScheme.
When copying a shape manually in PowerPoint, I get an option to "Keep Source Formatting". This copies all the original colors of the shape, converting theme colors into absolute RGB values.
What is the simplest way to do this programmatically?
You need to go to the slide and use Application.CommandBars.ExecuteMso
If you don't need to return to the previously selected slide afterwards, you can skip DoEvents and the second call to Application.CommandBars.ExecuteMso
It seemed like the position of the new shape was sometimes a little bit skewed after pasting, so I obtain a reference to the last shape in the Shapes collection of the second slide and copy the position of the original shape.
At least on my machine, without DoEvents, the macro would do nothing when I executed it (but it would work if I stepped through it).
Sub CopySelectedShapeToNextSlide()
Dim oShape As Shape
Dim oSlide As Slide
Dim nextSlide As Slide
Dim newShape As Shape
Set oShape = Application.ActiveWindow.Selection.ShapeRange(1)
Set oSlide = Application.ActiveWindow.Selection.SlideRange(1)
Set nextSlide = oSlide.Parent.Slides(oSlide.SlideIndex + 1)
oShape.Copy
Application.ActiveWindow.View.GotoSlide nextSlide.SlideIndex
Application.CommandBars.ExecuteMso "PasteSourceFormatting"
Set newShape = nextSlide.Shapes(nextSlide.Shapes.Count)
newShape.Left = oShape.Left
newShape.Top = oShape.Top
DoEvents
Application.ActiveWindow.View.GotoSlide oSlide.SlideIndex
Debug.Print newShape.Name
End Sub