【问题标题】:How to get Document-Coordinates from a Mouse Click in an OpenOffice BASIC Macro如何在 OpenOffice BASIC 宏中通过鼠标单击获取文档坐标
【发布时间】:2017-06-05 11:31:56
【问题描述】:

背景:

我想将任何东西(最好是图像、形状)粘贴(如 [CTRL+V])到我单击或用鼠标悬停的位置(使用键激活时)。我不知道如何获取我点击的文档(X、Y)上的位置

(Apache OpenOffice、SDraw-Document、OpenOffice BASIC 宏)

我需要什么:

  • 提示/提示如何从文档上的鼠标单击/鼠标位置获取位置。 (我需要哪个类、监听器、组件)

注意事项: 如果给定的oEvent 给了我单击的文档的 X+Y,则像 com.sun.star.awt.XMouseClickHandler 这样的东西会很完美。 (也许你知道如何“激活”PopupTrigger?(com.sun.star.awt.MouseEvent))

到目前为止我的代码:

我尝试使用提到的XMouseClickHandler 来获取 X+Y。 遗憾的是,X+Y 指的是窗口的相对位置,而不是形状或文本在文档上的实际位置。

执行: My Sub Main 是通过顶部的菜单按钮执行的。 然后单击任意位置将输出(通过 MsgBox)该单击的坐标。

唯一的问题:坐标是相对于窗口的角,而不是文档的角。

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

我的参考资料:

到目前为止,我的所有信息都来自官方参考资料/文档,因为我的所有搜索都没有发现任何有用的信息。

提前致谢。

【问题讨论】:

  • edit您的问题显示the code you have so far。您应该至少包含您遇到问题的代码的大纲(但最好是minimal reproducible example),然后我们可以尝试帮助解决具体问题。您还应该阅读How to Ask
  • 这与here提出的问题基本相同吗?
  • @JimK 是的,但该线程没有给出答案(我不应该将其包含在问题中,对吗?)
  • @TobySpeight 感谢您的建议,我已经编辑了问题。希望现在好多了。如果没有,请告诉我您在哪里需要更多信息。
  • 由于 OpenOffice 论坛的帖子密切相关,提一下就好了;但无论如何,由于您的编辑,问题现在更好了。

标签: position mouse copy-paste basic openoffice-basic


【解决方案1】:

我终于找到了一种方法来获取鼠标点击的精确坐标(相对于文档)。 我设法从底部的状态栏获取信息,它通常显示坐标(对我来说以厘米为单位)。

这是我现在用来获取位置 (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 的窗口的每个 ApplicationContext。

如果需要其他值,这是迭代 ThisDesktop 的起点。 ThisComponent.CurrentController.Frame.ComponentWindow.AccessibleContext

未来的改进

我“知道”GetAccessibleChild()-Function 的索引,因为我检查了调试器。当然有更好的方法可以到达o3,你不应该期望每个人都拥有相同的 AccessibleContext。

【讨论】:

    【解决方案2】:

    事实证明,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,加上来自 Andrew Pitonyak's Macro Document 的清单 5.84 中的一些代码。

    【讨论】:

    • 感谢您将鼠标点击的坐标与可见区域的坐标相加的想法。
    • 也许我不理解这里的算法,但是这将如何有效地工作?当我测试它时,形状有时在我的光标上方,有时在下方。此外,它是否不取决于缩放和方向以及其他因素,并且对实际鼠标坐标永远不会 100% 可靠? (抱歉,第一条评论有点错误)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多