如何通过在 OpenOffice BASIC 宏中单击鼠标获取文档坐标
How to get Document-Coordinates from a Mouse Click in an OpenOffice BASIC Macro
背景:
我想在我用鼠标单击或悬停(使用按键激活时)的位置粘贴(如 [CTRL+V])任何内容(最好是图像、形状)。我不知道如何获取我单击的文档 (X, Y) 上的位置。
(Apache OpenOffice、SDraw-Document、OpenOffice BASIC 宏)
我需要的:
- Hint/Tip 如何从文档上的鼠标单击/鼠标位置获取位置。 (我需要哪个class,监听器,组件)
备注:
如果给定的 oEvent
给了我文档的 X+Y,我点击的地方,像 com.sun.star.awt.XMouseClickHandler
这样的东西将是完美的。
(也许你知道如何"activate" PopupTrigger
?(com.sun.star.awt.MouseEvent
))
到目前为止我的代码:
我尝试使用提到的 XMouseClickHandler
来获得 X+Y。
遗憾的是,X+Y 指的是 window 的相对位置,而不是形状或文本在文档中的实际位置。
执行: 我的 Sub Main
通过顶部的菜单按钮执行。
然后点击任意位置将输出(通过 MsgBox)该点击的坐标。
唯一问题:坐标是相对于window的角,而不是文档的角。
Global gListener As Object
Sub Main
gListener = CreateUnoListener("Listener_","com.sun.star.awt.XMouseClickHandler")
ThisComponent.CurrentController.addMouseClickHandler(gListener)
End Sub
Sub Listener_mousePressed(oMouseEvent) As Boolean
ThisComponent.CurrentController.removeMouseClickHandler(gListener)
Msg = "Position: "
Msg = Msg & oMouseEvent.X & "/" & oMouseEvent.Y
MsgBox(Msg)
REM :: I want something like:
REM :: Msg = "Position: " & oMouseEvent.PositionOnDocument.X
REM :: Msg = Msg & "/" & oMouseEvent.PositionOnDocument.Y
REM :: MsgBox(Msg)
End Sub
我的参考资料:
到目前为止,我所有的信息都来自官方references/docs,因为我所有的搜索都没有找到任何有用的信息。
- Class-List: http://api.libreoffice.org/docs/idl/ref/annotated.html Here you can see docs for the used classes (com.sun.star.awt.XMouseClickHandler, com.sun.star.awt.MouseEvent)
- 关于监听器的信息:https://help.libreoffice.org/3.6/Basic/CreateUnoListener_Function_Runtime
提前致谢。
原来 DrawingDocumentDrawView 服务有一个叫 VisibleArea
的成员帮忙。从鼠标位置减去(实际上是加上,因为它们的符号相反)这些坐标以获得相对于文档的位置。
这里是一个在鼠标点击的位置创建一个矩形的例子。
Sub Listener_mousePressed(oMouseEvent) As Boolean
ThisComponent.CurrentController.removeMouseClickHandler(gListener)
xpos = (oMouseEvent.X + ThisComponent.VisibleArea.X / 25.4) / 100
ypos = (oMouseEvent.Y + ThisComponent.VisibleArea.Y / 25.4) / 100
Msg = "Position: " & xpos & "/" & ypos
MsgBox(Msg)
InsertProcessShape(xpos, ypos)
End Sub
Sub InsertProcessShape(xpos, ypos)
Dim oDoc As Object
Dim oDrawPage As Object
Dim oShape As Object
Dim shapeGeometry(0) as new com.sun.star.beans.PropertyValue
Dim oSize As new com.sun.star.awt.Size
oSize.width = 3000
oSize.height = 1000
oDoc = ThisComponent
odrawPage = oDoc.DrawPages(0)
oShape = oDoc.createInstance("com.sun.star.drawing.CustomShape")
shapeGeometry(0).Name = "Type"
shapeGeometry(0).Value = "flowchart-process"
oDrawPage.add(oShape)
oShape.CustomShapeGeometry = shapeGeometry
oShape.Size = oSize
' Position the object
IN_TO_CM = 2540 ' converts 1/1000 cm to inches
Dim aPosition As New com.sun.star.awt.Point
aPosition.X = xpos * IN_TO_CM
aPosition.Y = ypos * IN_TO_CM
oShape.setposition(aPosition)
End Sub
为了解决这个问题,我使用了 xray。公式可能需要微调。但是当我测试它时,矩形的左上角似乎大致位于鼠标单击的位置,正如预期的那样。
InsertProcessShape
来自 https://forum.openoffice.org/en/forum/viewtopic.php?f=45&t=46682, plus some code from Listing 5.84 of Andrew Pitonyak's Macro Document.
我终于找到了一种方法来获得鼠标点击的精确坐标(相对于文档)。
我设法从底部的 StatusBar 获取信息,它通常显示坐标(对我来说以厘米为单位)。
这是我现在用来获取位置 (X/Y) 的函数:
REM // Warning: If there is currently a selection, the returning Point will instead show the coordinates of the selection!
Sub GetMousePositionOnDocument as com.sun.star.awt.Point
Dim aPosition As New com.sun.star.awt.Point
Dim o1, o2, o3, o4, o5, o6
REM // First get AccessibleContext of the Window of the active Frame of the Application
o1 = StarDesktop.ActiveFrame.ContainerWindow.AccessibleContext
REM // 7th AC of o1 is the StatusBar at the bottom;
o2 = o1.GetAccessibleChild(6).AccessibleContext
REM // 2nd AC of o2 is the Position + Size of the Selection (e.g: "10,95 / 14,980,00 x 0,00")
o3 = o2.GetAccessibleChild(1)
o4 = o3.GetText()
REM // Taking out only the coordinates from o4
REM // TODO: Check for negatives (longer)
o5 = LEFT(o4, 4)
o6 = MID(o4, 8, 5)
aPosition.X = o5
aPosition.Y = o6
REM // Return
GetMousePositionOnDocument = aPosition
End Sub
注意:这个函数是在我之前的 Listener_mousePressed
里面调用的。
希望这对其他人也有用。
我是怎么找到它的?
我花了很多时间在调试器中手动检查 ThisComponent 和 StarDesktop 的 Window(s) 的每个 ApplicationContext。
如果需要其他值,这是遍历 ThisDesktop 的起点。
ThisComponent.CurrentController.Frame.ComponentWindow.AccessibleContext
未来的改进
我 "know" GetAccessibleChild()-函数的索引,因为我检查了调试器。当然有更好的方法可以达到 o3
,您不应该期望每个人都拥有相同的 AccessibleContext。
背景:
我想在我用鼠标单击或悬停(使用按键激活时)的位置粘贴(如 [CTRL+V])任何内容(最好是图像、形状)。我不知道如何获取我单击的文档 (X, Y) 上的位置。
(Apache OpenOffice、SDraw-Document、OpenOffice BASIC 宏)
我需要的:
- Hint/Tip 如何从文档上的鼠标单击/鼠标位置获取位置。 (我需要哪个class,监听器,组件)
备注:
如果给定的 oEvent
给了我文档的 X+Y,我点击的地方,像 com.sun.star.awt.XMouseClickHandler
这样的东西将是完美的。
(也许你知道如何"activate" PopupTrigger
?(com.sun.star.awt.MouseEvent
))
到目前为止我的代码:
我尝试使用提到的 XMouseClickHandler
来获得 X+Y。
遗憾的是,X+Y 指的是 window 的相对位置,而不是形状或文本在文档中的实际位置。
执行: 我的 Sub Main
通过顶部的菜单按钮执行。
然后点击任意位置将输出(通过 MsgBox)该点击的坐标。
唯一问题:坐标是相对于window的角,而不是文档的角。
Global gListener As Object
Sub Main
gListener = CreateUnoListener("Listener_","com.sun.star.awt.XMouseClickHandler")
ThisComponent.CurrentController.addMouseClickHandler(gListener)
End Sub
Sub Listener_mousePressed(oMouseEvent) As Boolean
ThisComponent.CurrentController.removeMouseClickHandler(gListener)
Msg = "Position: "
Msg = Msg & oMouseEvent.X & "/" & oMouseEvent.Y
MsgBox(Msg)
REM :: I want something like:
REM :: Msg = "Position: " & oMouseEvent.PositionOnDocument.X
REM :: Msg = Msg & "/" & oMouseEvent.PositionOnDocument.Y
REM :: MsgBox(Msg)
End Sub
我的参考资料:
到目前为止,我所有的信息都来自官方references/docs,因为我所有的搜索都没有找到任何有用的信息。
- Class-List: http://api.libreoffice.org/docs/idl/ref/annotated.html Here you can see docs for the used classes (com.sun.star.awt.XMouseClickHandler, com.sun.star.awt.MouseEvent)
- 关于监听器的信息:https://help.libreoffice.org/3.6/Basic/CreateUnoListener_Function_Runtime
提前致谢。
原来 DrawingDocumentDrawView 服务有一个叫 VisibleArea
的成员帮忙。从鼠标位置减去(实际上是加上,因为它们的符号相反)这些坐标以获得相对于文档的位置。
这里是一个在鼠标点击的位置创建一个矩形的例子。
Sub Listener_mousePressed(oMouseEvent) As Boolean
ThisComponent.CurrentController.removeMouseClickHandler(gListener)
xpos = (oMouseEvent.X + ThisComponent.VisibleArea.X / 25.4) / 100
ypos = (oMouseEvent.Y + ThisComponent.VisibleArea.Y / 25.4) / 100
Msg = "Position: " & xpos & "/" & ypos
MsgBox(Msg)
InsertProcessShape(xpos, ypos)
End Sub
Sub InsertProcessShape(xpos, ypos)
Dim oDoc As Object
Dim oDrawPage As Object
Dim oShape As Object
Dim shapeGeometry(0) as new com.sun.star.beans.PropertyValue
Dim oSize As new com.sun.star.awt.Size
oSize.width = 3000
oSize.height = 1000
oDoc = ThisComponent
odrawPage = oDoc.DrawPages(0)
oShape = oDoc.createInstance("com.sun.star.drawing.CustomShape")
shapeGeometry(0).Name = "Type"
shapeGeometry(0).Value = "flowchart-process"
oDrawPage.add(oShape)
oShape.CustomShapeGeometry = shapeGeometry
oShape.Size = oSize
' Position the object
IN_TO_CM = 2540 ' converts 1/1000 cm to inches
Dim aPosition As New com.sun.star.awt.Point
aPosition.X = xpos * IN_TO_CM
aPosition.Y = ypos * IN_TO_CM
oShape.setposition(aPosition)
End Sub
为了解决这个问题,我使用了 xray。公式可能需要微调。但是当我测试它时,矩形的左上角似乎大致位于鼠标单击的位置,正如预期的那样。
InsertProcessShape
来自 https://forum.openoffice.org/en/forum/viewtopic.php?f=45&t=46682, plus some code from Listing 5.84 of Andrew Pitonyak's Macro Document.
我终于找到了一种方法来获得鼠标点击的精确坐标(相对于文档)。 我设法从底部的 StatusBar 获取信息,它通常显示坐标(对我来说以厘米为单位)。
这是我现在用来获取位置 (X/Y) 的函数:
REM // Warning: If there is currently a selection, the returning Point will instead show the coordinates of the selection!
Sub GetMousePositionOnDocument as com.sun.star.awt.Point
Dim aPosition As New com.sun.star.awt.Point
Dim o1, o2, o3, o4, o5, o6
REM // First get AccessibleContext of the Window of the active Frame of the Application
o1 = StarDesktop.ActiveFrame.ContainerWindow.AccessibleContext
REM // 7th AC of o1 is the StatusBar at the bottom;
o2 = o1.GetAccessibleChild(6).AccessibleContext
REM // 2nd AC of o2 is the Position + Size of the Selection (e.g: "10,95 / 14,980,00 x 0,00")
o3 = o2.GetAccessibleChild(1)
o4 = o3.GetText()
REM // Taking out only the coordinates from o4
REM // TODO: Check for negatives (longer)
o5 = LEFT(o4, 4)
o6 = MID(o4, 8, 5)
aPosition.X = o5
aPosition.Y = o6
REM // Return
GetMousePositionOnDocument = aPosition
End Sub
注意:这个函数是在我之前的 Listener_mousePressed
里面调用的。
希望这对其他人也有用。
我是怎么找到它的?
我花了很多时间在调试器中手动检查 ThisComponent 和 StarDesktop 的 Window(s) 的每个 ApplicationContext。
如果需要其他值,这是遍历 ThisDesktop 的起点。
ThisComponent.CurrentController.Frame.ComponentWindow.AccessibleContext
未来的改进
我 "know" GetAccessibleChild()-函数的索引,因为我检查了调试器。当然有更好的方法可以达到 o3
,您不应该期望每个人都拥有相同的 AccessibleContext。