PowerPoint VBA - SlideRange position on a screen - vba

I am creating a PPT Add-In and I am struggling to find the answer whether it is possible to determine the SlideRange position on a screen.
I would like to have a userform to be opened in a particular position (for example left = 10, top = 10 starting from left-top corner of the SlideRange). Unfortunatelly its position is based on a screen resolution. As the resolution can be changed and the PPT view type may be modified I am unable to establish the accurate position of SlideRange.
Is it possible to do with VBA?
Thanks in advance!
MJ

SlideRange has no particular position ... it's a collection of slides, and it's unclear what units you're using when you want to position the form at 10,10. But in normal full screen view, you can get the slide show window coordinates in points like so:
With SlideShowWindows(1)
Debug.Print .Left
Debug.Print .Top
Debug.Print .Height
Debug.Print .Width
End With
To get the results in screen pixels you have to use a Win API call to get the screen DPI (dots per inch).
Inches = Points / 72
Pixels = Inches * DPI

<< Do you know if it is possible to catch mouse events in PPT?
Only if the mouseclick changes the selection, and as you know, that's NOT all the time.
There's probably some way of doing it via the Win API but nothing like this is built into PPT itself.

Related

How to determine a control size in twips?

I'm developing VB.net application in MS Visual Studio 2019 (community Edition) in which I programatically paste an image from the clipboard into a Richtextbox.
I need to add an option to force that image to completely fill the control's visible area.
Examining the richtext which results from pasting the image, and then again after I've manually dragged the image to resize it to fill the control, it looks like all I need to do is change the picwgoal and pichgoal rtf tags for the image to the dimensions of the control.
The problem is that picwgoal and pichgoal are in twips.
So my question is: Is there a reliable way to dynamically calculate a control's dimensions in twips from it's pixel width and height, such that it will work when the app runs in various resolutions/scaling ?
I understand that the TwipsPerPixelX method is obsolete and not compatable with 64 bit processes.
Thanks in advance.
..Think I've worked it out myself
..Think I've worked it out myself
assuming a point is always 1/72 inches and a point is 20 twips..
Dim g = Me.CreateGraphics()
Dim RTBxTwips = (RTB.Width * 72 / g.DpiX) * 20
Dim RTByTwips = (RTB.Height * 72 / g.DpiY) * 20
g.Dispose()
..seems to give results equal to the picwgoal and pichgoal tags for an image resized to the controls visible area

Rectangular selection of shape in visio using vba

Is it possible to select shapes in Visio by specifying the coordinates of a selection rectangle? If so, how does one do this?
I need to select and delete any shape in a specific location on a Visio page.
I would like to be able to specify the coordinates of a lower left corner and an upper right corner on the page and have vba tell me the id's or handles or something that would allow me to delete these shapes as I need to place a new shape in that particular location. I am looking for something like
shapes = MyVisioPage.SelectByRectangularCrossingBox(lowerleftX,lowerleftY,upperrightX,upperrightY)
You could actually draw a rectangle with those coordinates and then use Shape.SpatialNeighbors to find out all shapes in that rectangle.. Something like this (VBA):
Function SelectByRectangularCrossingBox(page, _
lowerleftX, lowerleftY, upperrightX, upperrightY) As Selection
scopeId = page.Application.BeginUndoScope("try")
Set rc = page.DrawRectangle(lowerleftX, lowerleftY, upperrightX, upperrightY)
Set SelectByRectangularCrossingBox = rc.SpatialNeighbors(visSpatialContain, 0.01, 0)
page.Application.EndUndoScope scopId, False
End Function
The code is wrapped around with BeginUndoScope/EndUndoScope to cancel changes.

VBA for Word - position text boxes based on page

After adding a large number (150?) of callouts (simple text boxes in the margin, with no borders) to a Word 2010 .docx file with mirrored odd/even pages, I needed to adjust some text. This shortened the document enough to remove a page, and therefore all the odd pages following the adjustment became even, and the even became odd. The text boxes did not move, and now they all fall off the edge of the paper, where it is difficult even to find them all due to the text outside the bounds of the paper not being shown in the document, let alone to move them to their correct positions in the opposite margin. Moreover, I may need to adjust text again and the problem could recur.
I'm looking for an automated way, using VBA (in which I am decidedly a rank novice, though an expert programmer), to record some macro to say, "Center all existing text boxes in the wide margin, and make the width consistent." Something like,
As a text box, if I find myself on an odd page, make the left edge of the text box 0.5" from the left edge of the page; if I am found on an even page, make the left edge of the text box at the right margin + 0.5". My height should be consistent, and my height can stay what it was already.
I need to know in what units to express the Top and Width values, how to determine if I am on an odd/even page, and how to find all the text boxes.
Can anyone help?
Sub AdjustTextBoxes()
Dim myTextBox As Shape
Dim PageNumber As Integer
For Each myTextBox In ActiveDocument.Shapes
If myTextBox.Type = msoTextBox Then
myTextBox.Select
PageNumber = Selection.Information(wdActiveEndPageNumber)
'Mod returns the remainder (rounded up) of the division.
'No remainder is even. Any remainder is an odd page.
If PageNumber Mod 2 = 1 Then
With myTextBox 'Odd numbered pages
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.Left = InchesToPoints(0.5)
End With
Else
'Because wdRelativeHorizontalPositonPage measures from the left
'edge of the page the positioning for text boxes on even pages
'is not based on the distance from the right margin.
'So below .Left = 8.5" (page width) - (1" (textbox with) + .5" (distance
'from the right edge of the page). The measurement for .left below
'will need to be altered based on the position from the right edge
'of the page and the width of your text boxes and pages.
With myTextBox 'Even numbered pages
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.Left = InchesToPoints(7)
End With
End If
End If
Next
End Sub

How to move a rotated shape to a specific location in excel 2010 using vba

I've written some VBA code that automatically creates a chart. One of the axes on this chart doesn't use normal labels but a graphic. I've stored the graphic as an image and I use the .Copy and .Paste methods to get a copy of this image onto the chart.
Here is where it gets confusing. I need to rotate the image to get it aligned with the axis (using the .rotation property). But when I set the .top and .left properties the shape doesn't end up where I would expect. In fact setting the properties to 0 and 0 doesn't do what I would expect either. I've tried changing the order of the way I set the properties on the image object but it only appears in a different (wrong) location.
I'm sure I'm missing some vital aspect of how VBA/Excel is placing the object relative to what I'm setting the top and left properties to. Basically my goal is to make the image on the left side of the chart with the same width as the plot area's height (since the image is rotated I theorize this will make it the same size).
This code does not work:
Sheets(ImageSheet).Shapes("agreement").Copy
c.Chart.Paste
c.Chart.Shapes(1).Rotation=270
c.Chart.Shapes(1).width = c.Chart.PlotArea.height
c.Chart.shapes(1).left = 5
c.Chart.Shapes(1).top = c.Chart.PlotArea.top
I've also tried this code
c.chart.Shapes(1).top = c.chart.PlotArea.top + c.Chart.PlotArea.height
because I thought maybe it was calculating the "top" as the upper-left corner of the image object when it is not rotated (rotating 270 degrees makes this point in a place where it should align with the bottom of the plot area). But that doesn't do what I expected either.
The image is a skinny rectangle that acts as a label for the axis. The chart will end up being laid out like this: http://imgur.com/NrSXR and the axis label image would be something like this http://imgur.com/08EWU
What am I missing here?
Is it possible for you to align your chart into a position where the shape could rest align/on a cell?
IF YES then here is a suggestion:-
You could position shape into a cell. Then adjust the size to what you need. And rotate.
Then change its bring forward property be shown on the Chart.
Next Group Chart and the Shape
PS: I recorded a macro. However it's best if you could show us what your the exact picture (=how your sheeet/chart/image should look like) of your question.
I ended up rotating and resizing the image before copying and pasting to the chart and then positioning it. I had to use the IncrementLeft and IncrementTop methods rather than setting the left and top properties directly because that did not have the desired effect.
When doing the paste into the chart the object always ended up in the upper left hand-corner so I could increment to the left by the small amount I wanted as a margin I wanted there and increment the top by the value of PlotArea.top to align it with the plot area.
I was also surprised that when creating the copy of my image it retained the "name" i referred to it as when I copied it to the new sheet and chart. This was especially useful for positioning the image once it was on the chart.
I also needed execute this code at the very end of my procedure, after everything else had been positioned and aligned, or when I positioned the data labels for one of my series they wouldn't appear correctly.
Here is the code that I ended up using:
'make a copy of the label image and refer to it with a variable for convenience
Sheets(ImageSheet).Shapes("maturity").Copy
i = Sheets(ImageSheet).Shapes.Count
Sheets(ImageSheet).Paste
Dim axisImage As Shape
Set axisImage = Sheets(ImageSheet).Shapes(i + 1)
'rotate and resize the image
With axisImage
.Rotation = 270
.width = c.Chart.PlotArea.height
End With
'cut and paste the new image to the chart
axisImage.Cut
c.Chart.Paste
'position it in the chart using IncrementTop and IncrementLeft because setting the properties directly does not have the desired effect
c.Chart.Shapes("maturity").IncrementTop c.Chart.PlotArea.top
c.Chart.Shapes("maturity").IncrementLeft c.Chart.PlotArea.left - c.Chart.Shapes("maturity").height

Scrollable image in userform

I have a word doc with a bunch of ActiveX Control buttons or whatever on it, and each time a button is clicked, a corresponding image needs to be displayed in a popup box.
I have a userform called ImageForm, and this is what I'm doing right now:
Sub Button_Clicked()
ImageForm.Picture = LoadPicture("appropriate_image_path")
ImageForm.Show
End Sub
Each of these images has a width of 8.5 inches, but their heights can vary anywhere from like 3 to 20 inches (they're snippets of a pdf). So I've set the width of the userform to a little more than 8.5 inches, and that looks fine. But I need to be able to scroll vertically through the image in the userform, since some of the images could be taller than a user's monitor.
I'm completely stuck on this. What I've tried so far is adding a frame to the form, then adding an image control inside the form, and setting the "ScrollBars" property of the frame to vertical. Then instead of using "ImageForm.Picture = ..." I use "ImageForm.ImageControl.Picture = ..." But it doesn't work.
Any insight here would be greatly appreciated. Hopefully this question is clear enough, I've only been using VBA for a month or so now. (I miss Java so, so much)
Thanks!
Here is a neat little trick based on one of my posts
The idea is to ensure that the image control is in frame control and the image control doesn't have a border. Also the image control's PictureSizeMode is set to fmPictureSizeModeClip so that we can scroll the image
SNAPSHOT (DESIGN TIME)
SNAPSHOT (RUN TIME)
CODE
Private Sub UserForm_Initialize()
With Frame1
'~~> This will create a vertical scrollbar
.ScrollBars = fmScrollBarsVertical
'~~> Change the values of 2 as Per your requirements
.ScrollHeight = .InsideHeight * 2
.ScrollWidth = .InsideWidth * 9
End With
With Image1
.Picture = LoadPicture("C:\Users\Public\Pictures\Sample Pictures\Desert.jpg")
.BorderStyle = fmBorderStyleNone
.PictureSizeMode = fmPictureSizeModeClip
End With
End Sub