LocationOnScreen (absolute X/Y in pixels) for selected text in Write, how to?

Hi, I am looking for a method that returns the absolute screen coordinates of the selected text in the Write editor. I’ve read some threads about positioning dialog boxes near a sheet cell, but the methods that handle sheet objects don’t work in the Write document. Is there any way to extract LocationOnScreen from selected text or even a table cell, but in the Write editor?
I would appreciate any leads or suggestions on this matter.

Greetings with a smile
Racho

Hi there

Try these:

This returns the X/Y coordinates of the selected text on the document window

Sub GetSelectedTextCoordinates()

    Dim oDoc As Object
    Dim oViewCursor As Object
    Dim oTextRange As Object
    Dim oWindow As Object
    Dim oPos As New com.sun.star.awt.Point

    ' Get the current document
    oDoc = ThisComponent

    ' Get the view cursor
    oViewCursor = oDoc.CurrentController.getViewCursor()

    ' Get the text range of the selected text
    oTextRange = oViewCursor.getStart()

    ' Get the window of the current controller
    oWindow = oDoc.CurrentController.Frame.ContainerWindow

    ' Get the screen position of the selected text
    oPos = oDoc.CurrentController.getViewCursor().getPosition()

    ' Display the coordinates
    MsgBox "X: " & oPos.X & ", Y: " & oPos.Y

End Sub

This returns the screen coordinates of the selected text

Sub GetSelectedTextScreenCoordinates()

    Dim oDoc As Object
    Dim oViewCursor As Object
    Dim oTextRange As Object
    Dim oWindow As Object
    Dim oPos As New com.sun.star.awt.Point
    Dim oScreenPos As New com.sun.star.awt.Point

    ' Get the current document
    oDoc = ThisComponent

    ' Get the view cursor
    oViewCursor = oDoc.CurrentController.getViewCursor()

    ' Get the text range of the selected text
    oTextRange = oViewCursor.getStart()

    ' Get the window of the current controller
    oWindow = oDoc.CurrentController.Frame.ContainerWindow

    ' Get the position of the selected text in the document window
    oPos = oViewCursor.getPosition()

    ' Calculate the absolute screen coordinates
    oScreenPos.X = oWindow.getPosSize().X + oPos.X
    oScreenPos.Y = oWindow.getPosSize().Y + oPos.Y

    ' Display the screen coordinates
    MsgBox "Screen X: " & oScreenPos.X & ", Screen Y: " & oScreenPos.Y

End Sub

Thank you for your suggestions! I have reworked it in various ways, but the resulting X/Y does not meet the two assumptions I stated in the topic. It is not absolutely related to the whole screen and it is not in pixels. And these are the basic conditions for the solution I am looking for.

If you’r OS is Windows you can always use Windows API functions with LibreOffice Basic.
With the functions below you can retrieve and manipulate almost everything that happens on your screen.

REM  *****  BASIC  *****
Option VBASupport 1

Private Declare Function GetCursorPos Lib "user32" ( _
  ByRef lpPoint As POINT) As Long

Private Declare Function GetWindowRect Lib "user32" ( _
  ByVal hWnd As Long, ByRef lpRect As RECT) As Long
  
Private Declare Function GetSystemMetrics32 Lib "User32" _
    Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long
    
Private Declare Function GetDeviceCaps Lib "gdi32" ( _
  ByVal hDC As Long, ByVal nIndex As Long) As Long
  
Private Declare Function GetDC Lib "user32" ( _
  ByVal hWnd As Long) As Long

Private Declare Function ReleaseDC Lib "user32" ( _
  ByVal hWnd As Long, ByVal hDC As Long) As Long

Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY = 90
Private Const TwipsPerInch = 1440

Type POINT
  X As Long
  Y As Long
End Type

Type RECT
  Left As Long
  Top As Long
  Right As Long
  Bottom As Long
End Type
  
Const LOGPIXELSX = 88
Const LOGPIXELSY = 90 
Const TwipsPerInch = 1440

Sub ScreenRes()

    Dim w As Long, h As Long
    w = GetSystemMetrics32(0) ' width in points
    h = GetSystemMetrics32(1) ' height in points
    MsgBox w &  " " & h
    Dim Pixels As POINT
    Pixels = TwipsToPixels(w, h)
    MsgBox Pixels.X & " " & Pixels.Y
    
End Sub

Function TwipsToPixels(ByVal X As Long, ByVal Y As Long) As POINT

  Dim ScreenDC As Long
  Dim Pixels As POINT
  ScreenDC = GetDC(0)

  ' Convert twips to pixels
  Pixels.X = X / TwipsPerInch * GetDeviceCaps(ScreenDC, LOGPIXELSX)
  Pixels.Y = Y / TwipsPerInch * GetDeviceCaps(ScreenDC, LOGPIXELSY)

  ReleaseDC 0, ScreenDC
  
  TwipsToPixels = Pixels
  
End Function

Unfortunately, I have no experience with non-MS operating systems or non-PC devices.

Thx! It’s greate tip. But I am working on another method without VBA and independent of OS. I will post it in this topic when it will be work. Your sugestion may help in testing (I am working on MS WIN).

How about this:

*****  BASIC  *****
REM EDIT:
REM Option VBASupport 1 
REM Only the Round function needs VBA Support in the code

Sub GetDocumentSelectedTextCoordinates()

	Dim oDoc As Object
	Dim oViewCursor As Object
	Dim oTextRange As Object
	Dim oWindow As Object
	Dim oPos As New com.sun.star.awt.Point
	
	' Get the current document
	oDoc = ThisComponent
	textSelected = oDoc.CurrentSelection.getByIndex(0).getString()

	If textSelected = "" Then
		MsgBox "No text selected"
		Exit Sub
	End If

	' Get the view cursor
	oViewCursor = oDoc.CurrentController.getViewCursor()

	' Get the text range of the selected text
	oTextRange = oViewCursor.getStart()

	' Get the window of the current controller
	oWindow = oDoc.CurrentController.Frame.ContainerWindow

	' Get the screen position of the selected text
	oPos = oDoc.CurrentController.getViewCursor().getPosition()

	Dim locationX, locationY
	locationX = (oPos.X / TwipsPerPixelX())
	locationY = (oPos.Y / TwipsPerPixelY())
	MsgBox "X:" & Round(locationX) & " Y:" & Round(locationY)
    
	REM Rule of thumb:
	REM The number of pixels cannot be expressed as a fraction of a pixel.
	REM All calculations that result in a fractional pixel are rounded to
	REM the nearest full pixel.

End Sub

Function Round(m, Optional n)
	' Round a number "m" to "n" decimal places
	' If "n" isn't supplied, round to zero decimal places
	If IsMissing(n) Then n = 0
	Round = Int(m*10^n + .5)/10^n
End Function

I assume you know that Declaring API calls in VBA7 are different from what StarBasic accepts, i.e. StarBasic does not accept the Declare PtrSafe Function, nor the LongPtr variable. However, more information can be found here

Next great tip! In LO API are this variables: LibreOffice: com::sun::star::util::MeasureUnit Constant Group Reference

I wish you luck with your project. I would still like to point out that you have a better chance of success with this and your possible future projects if you clarify the difference between a constant and a variable. Namely, the page you refer to with your link does not say anything about variables, only constants.