PDA

View Full Version : How to calculate distance of cursor from edge of SCREEN



johndavidson
07-25-2016, 12:32 AM
Both of the following return the screen position of the cursor:


MsgBox Selection.Information(wdVerticalPositionRelativeToTextBoundary)
MsgBox Selection.Information(Word.WdInformation.wdVerticalPositionRelativeToTextBo undary)

This is fine unless there are, for example, some endnotes on the screen in, say, Print or Web view. The text boundary among the endnotes or in the main text following is then calculated relative to the start and end of the endnotes area, not to the top of the screen.

Is there a way of calculating the position of the text cursor relative to the top of the screen in Print view when there are endnotes somewhere on the screen? What is needed is a What is needed is a 'Selection.Information.wdVerticalPositionRelativeToScreenEdge', but that does not exist

This is required after doing various searches and text manipulations to reposition the on-screen text and cursor in the same place as it was before starting.

This is the routine I'm using:


Sub rePosCursor(Optional rePos As Boolean)
' Save (=True)/Restore (=False) cursor and screen position using screen-text metrics


' Public vPosPub As Long
' Public sStartPub As Long
' Public sEndPub As Long

Dim vInt As Integer

' Test code - 'Text Boundary' means edge of pane, not screen, so endnotes restart at 0 even if in the middle of a screen,
' and likewise the main text following the endnotes. This includes Print and Web view
' So this routine does not work when in endnotes or when the cursor is below endnotes in Print or Web View
' wdVerticalPositionRelativeToPage gives the position relative to the edge of the document page, so that is of no use here
' What is needed is a 'wdVerticalPositionRelativeToScreenEdge', but that does not exist ...
' MsgBox Selection.Information(wdVerticalPositionRelativeToTextBoundary)
' MsgBox Selection.Information(Word.WdInformation.wdVerticalPositionRelativeToTextBo undary)

If rePos = True Then
vPosPub = Selection.Information(wdVerticalPositionRelativeToTextBoundary)
sStartPub = Selection.Start
sEndPub = Selection.End
Else
' Now try and put the text back the way it was in the place it was on screen
' The surest way to do this is not to use FindAwordAddAuto, but one of the other FindWordAdd routine
' that don't need to move the position of the cursor to find a tag character.
' Later. No need to do this when using the range object
' Keep code in case it is useful

Selection.Start = sStartPub
Selection.End = sEndPub ' This locates the line with the selection at the top of the Word text screen
Selection.MoveRight Unit:=wdCharacter, count:=1 ' This brings the cursor onto the screen after various text searches etc.

' Try & calculate where vPos would be in terms of lines from the top of the page
' 17.3" notebook is 0 to 425 high
' 125% has 35 lines/ 12.14 Line Height at 12pt
' 135% has 32 lines/ 13.28 Line Height at 12 pt; likewise 140%
' 145% has 30 lines/ 14.17 Line Height at 12 pt
' 150% has 29 lines/ 14.65 Line Height at 12pt
' As a compromise, an average line height of 14 works quite well.

If vPosPub > 12 Then ' Is it the first line?
vInt = (vPosPub) / 20 ' Calculate the no. of lines from the top of the page
Selection.MoveUp Unit:=wdLine, count:=vInt ' Move the cursor up accordingly
Selection.Start = sStartPub ' And reselect the text
Selection.End = sEndPub ' This seems to work most of the time
End If
End If
End Sub



Thanks

gmaxey
07-25-2016, 04:23 AM
Are you simply trying to get back where you were when you started a process?


Sub ScratchMacro()
'A basic Word macro coded by Greg Maxey
Dim oRng As Range
Set oRng = Selection.Range.Duplicate
ActiveDocument.Range.Select
Selection.Collapse wdCollapseEnd
ActiveWindow.ScrollIntoView Selection.Range
oRng.Select
lbl_Exit:
Exit Sub
End Sub

johndavidson
07-25-2016, 05:48 AM
Thanks Greg. What I am trying to achieve is for the text on screen to be repositioned in exactly the same place as it was when the macro was run, whatever is done to the rest of the document by the macro and at whatever location in the document. That way, the user can hit a hotkey or click a toolbar button or menu item to do whatever function was wanted and just keep going, without having to visually look for where the text and cursor has got to. There are several ways of getting the original text back onto the screen when the macro has been selecting and working on off-screen text (bookmarks, scrolling down x lines etc.) and yours is indeed a neat way of doing it, but it doesn't locate the text in exactly the same place on the screen as it was before.

In Print or Web view, my routine works as long as there are no endnotes or footnotes in the middle of the screen of text, so it is pretty limited.

It could perhaps be done by first locating the text just before the block of endnotes and using that as a reference point for the on-screen position of the endnotes. But there may also be other blocks of endnotes on the same screen, so one would have to find and calculate their sizes as well. Far too much effort for minimal gain, and I wondered if there was an easier way. We need the equivalent of wdVerticalPositionRelativeToScreenEdge - which doesn't actually exist.

Paul_Hossler
07-25-2016, 05:51 AM
VERY simple way



Sub SameAsShiftF5
Application.GoBack
End Sub

johndavidson
07-25-2016, 07:05 AM
That's cool, but GoBack doesn't position the text in the same place on the screen as it was when the macro was first run. And if (as is the case), the macro has been doing some significant messing around inside the text (range selections etc.) in off-screen areas of the document, GoBack doesn't necessarily go back to the place the user started from.