Тема: Как получить текущие координаты курсора в простр. модели

Возникла необходимость отрисовки "резиновых" или направляющих линий при указании курсором в пространстве модели очередной точки при интерактивном черчении (домеры), но (английский не проходил) в хелпе так и не смог найти каким образом в VBA определять текущие координаты курсора. Кто знает, подскажите как, или где искать.

Re: Как получить текущие координаты курсора в простр. модели

Из Хехлпа

Sub Example_GetPoint()
    ' This example returns a point entered by the user.
    Dim returnPnt As Variant
    ' Return a point using a prompt
    returnPnt = ThisDrawing.Utility.GetPoint(, "Enter a point: ")
    MsgBox "The WCS of the point is: " & returnPnt(0) & ", " & returnPnt(1) & ", " & returnPnt(2) & vbCrLf & _
            "(Enter the next value without prompting.)", , "GetPoint Example"
    ' Return a point, no prompt
    returnPnt = ThisDrawing.Utility.GetPoint
    MsgBox "The WCS of the point is: " & returnPnt(0) & ", " & returnPnt(1) & ", " & returnPnt(2), , "GetPoint Example"
    ' Return a point using a base point and a prompt
    Dim basePnt(0 To 2) As Double
    basePnt(0) = 2#: basePnt(1) = 2#: basePnt(2) = 0#
    returnPnt = ThisDrawing.Utility.GetPoint(basePnt, "Enter a point: ")
    MsgBox "The WCS of the point is: " & returnPnt(0) & ", " & returnPnt(1) & ", " & returnPnt(2)
    ' Create a line from the base point and the last point entered
    Dim lineObj As AcadLine
    Set lineObj = ThisDrawing.ModelSpace.AddLine(basePnt, returnPnt)
    ZoomAll
End Sub

Re: Как получить текущие координаты курсора в простр. модели

Спасибо, Gogi, за желание помочь, но вопрос, видимо, был не так понят. Необходимо программе знать текущие координаты курсора (то есть то, что слева внизу в окошке координат) до клика по клавише. Например, в VB это свойство рисунка CurretX и CurrentY.

Re: Как получить текущие координаты курсора в простр. модели

> Saor
Нужно получить текущие координаты курсора по HWND окна документа, преобразовать их в WCS, а потом (если нужно - в UCS). Как это делается в VBA - не в курсе (на ObjectARX - очень просто), но направление указано точно!

Re: Как получить текущие координаты курсора в простр. модели

Есть API-функция: GetCursorPos, которая возвращает текущую позицию курсора. Но координаты эти - в пикселях, и как их перевести в координаты WCS неизвестно.
Тема эта уже обсуждалась как-то на форуме, но решение насколько мне помнится, так и не было найдено.

Re: Как получить текущие координаты курсора в простр. модели

> LeonidSN
Предположительно:
1) При помощи GetCursorPos получить экранные координаты курсора.
2) По HWND активного документа найти размер клиентской области - GetClientRect
3) Преобразовать координаты из экранных в клиентские для активного документа - ScreenToClient
4) Из системной переменной VIEWSIZE - размер по Y экранной области в UCS
5) Из системной переменной VIEWCTR - центр экранной области в UCS
6) Из системной переменной SCREENSIZE - соотношение размеров по X и Y (хотя это наверное можно получить и из пункта 2)
Вроде бы вполне достаточно для перевода экранных координат в координаты в UCS, но возможно учтены не все нюансы.

Re: Как получить текущие координаты курсора в простр. модели

Еще один вариант. Начиная с AutoCAD 2004 acad.exe экспортирует функцию:
int acedTransScreenToWorld(int view,long const *screen_pt,double *world_pt)
Которая преобразует координаты из экранных в WCS. Только описывать ее нужно как "?acedTransScreenToWorld@@YAHHPBJPAN@Z"
Так как я не специалист в VBA, то как это делается не подскажу.

Re: Как получить текущие координаты курсора в простр. модели

> Александр Ривилис
Вот реализация предложенного вами варианта с некоторыми уточнениями. Спасибо за подсказу.

Option Explicit
Type POINTAPI
    X   As Long
    Y   As Long
End Type
Type rect
     Left As Long
     Top As Long
     Right As Long
     Bottom As Long
End Type
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Public Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
Public Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As rect) As Long
Sub CursorPos()
'получение экранных координат курсора
    Dim retValue As Long
    Dim CursorLoc As POINTAPI
    retValue = GetCursorPos(CursorLoc)
'дескриптор активного окна
    Dim vHWND As Long
    If Documents.Count = 0 Then
        MsgBox "There are no open documents!"
        Exit Sub
    End If
    vHWND = ActiveDocument.hwnd
    ''размер клиентской области (в писелях)
    '    Dim vRect As rect
    '    retValue = GetClientRect(ByVal vHWND, vRect)
'размер клиентской области (в писелях)
'этот размер с точки зрения AutoCAD насколько отличается
'от размера с точки зрения Windows.
'В итоге, автокадовсий подход дает более точный результат
    Dim vRect As rect
    Dim SizeOfScreen As Variant
    SizeOfScreen = ThisDrawing.GetVariable("SCREENSIZE")
    vRect.Right = SizeOfScreen(0)
    vRect.Bottom = SizeOfScreen(1)
'перевод экранных координат в клиентские
    retValue = ScreenToClient(ByVal vHWND, CursorLoc)
'высота вида (клиентской области)в USC:
    Dim HeightScreen As Long
    HeightScreen = ThisDrawing.GetVariable("VIEWSIZE")
'ширина вида (клиентского экрана)в USC:
    Dim WidthScreen As Long
    WidthScreen = HeightScreen * vRect.Right / vRect.Bottom
'положение центра клиентской области в USC:
    Dim СenterScreen As Variant
    СenterScreen = ThisDrawing.GetVariable("VIEWCTR")
'положение левого нижнего угла клиентской области в USC:
    Dim X0 As Double
    Dim Y0 As Double
    X0 = СenterScreen(0) - WidthScreen / 2
    Y0 = СenterScreen(1) - HeightScreen / 2
'масштабный коэффициент для пересчета координат из пикселей в единицы чертежа
    Dim K_Coord_ScreenToWCS As Single
    K_Coord_ScreenToWCS = HeightScreen / vRect.Bottom
'позиция курсора в USC:
    Dim X_CursorPos As Double
    Dim YCursorPos As Double
    X_CursorPos = X0 + K_Coord_ScreenToWCS * CursorLoc.X
    YCursorPos = Y0 + (HeightScreen - K_Coord_ScreenToWCS * CursorLoc.Y)
    MsgBox "X = " & X_CursorPos & vbCrLf & "Y = " & YCursorPos
End Sub

Re: Как получить текущие координаты курсора в простр. модели

> LeonidSN
Ну вот. Совместными усилиями решили и эту "нерешаемую" задачу. smile А то я уже думал писать arx-файл, который бы вызывался из VBA. Те функции из acad.exe, которые я предлогал использовать имеют формат вызова не STDCALL и, поэтому, IMHO, из VBA их напрямую вызвать нельзя - только написать "обертки" с использованием ObjectARX. В VB.NET - можно и напрямую.
Интересно, всегда ли Ваша функция возвращает правильное значение (например, в случае с несколькими видами)?

Re: Как получить текущие координаты курсора в простр. модели

> Александр Ривилис
Насчет правильного значения, у меня пока только предварительное впечатление. В любом случае, метод требует тщательной проверки. Есть расхождения между размерами клиентской области полученной средствами Windows(GetClientRect) и размерами видового экрана полученными средствами AutoCAD(ThisDrawing.GetVariable("SCREENSIZE")
).
А о расширении до работы с несколькими видами я не думал.

Re: Как получить текущие координаты курсора в простр. модели

Александр Ривилис и LeonidSN, огромное спасибо!
После первой подсказки на все свободное время закопался в учебники, а сейчас попробую протестировать предложенные решения. Не думал, что решается так сложно. По наивности думал, что данная проблема в AutoCAD и Excel скрывается от чайников специально