Как получить ссылку при наведении на нё мышью

Russian main discussion
Post Reply
  • Author
  • Message
Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Как получить ссылку при наведении на нё мышью

Post by Andrey_A_A »

Подскажите, есть ли возможность получить внешним приложением ссылку, на которую наведён курсор мыши?
В частности, интересует реализация на Autoit
В простом Edit находится позиция через _GUICtrlEdit_CharFromPos
В простом RichEdit через _GUICtrlRichEdit_GetCharPosFromXY
в AkelPad ни то и ни другое не работает...

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Andrey_A_A

In AkelEdit you can use AEM_CHARFROMPOS or EM_CHARFROMPOS message.
Description and example of AEM_CHARFROMPOS are in AkelEdit.h.
About EM_CHARFROMPOS you can read here: https://msdn.microsoft.com/en-us/librar ... s.85).aspx

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

KDJ, у меня есть функция получения ссылки из AkelPad

Code: Select all

' Функция получения ссылки под курсором или позиции
 ' cpCnt: 0 - ссылка, 1 - начало позиции, 2 - конец позиции 3 - массив со ссылкой, начальной позиции и конечной
Function GetLinkUnderCaret(cpCnt)
  With AkelPad Res = ""
    If vbX64 Then : cc = 24 : vv = 48 : Else : cc = 12 : vv = 24 : End If
    lpCaret = .MemAlloc(cc)
    If Len(lpCaret) > 0 Then
      hWE = .GetEditWnd : .SendMessage hWE, 3130, 5, lpCaret : lpRange = .MemAlloc(vv)
      Call .SetClipboardText(hWE)
      If Len(lpRange) > 0 And .SendMessage(hWE, 3149, lpCaret, lpRange) Then
        cpMin = .SendMessage(hWE, 3136, 0, lpRange)
        cpMax = .SendMessage(hWE, 3136, 0, lpRange + cc)
        Select Case cpCnt
          Case 0 Res = .GetTextRange(cpMin, cpMax)
          Case 1 Res = cpMin
          Case 2 Res = cpMax
          Case 3 Res = Array(.GetTextRange(cpMin, cpMax), cpMin, cpMax)
        End Select
      End If
      .MemFree(lpRange)
    End If
    .MemFree(lpCaret)
  End With : GetLinkUnderCaret = Res
End Function
Мне нужна функция для получение позиции (слова/ссылки), когда я передаю ей координаты мыши X, Y

В RichEdit в Autoit есть функции - они нормально работают в RichEdit, в AkelPad нет - у него свой класс...
Хотелось бы разобраться, что где подправить...

Code: Select all

Func _GUICtrlRichEdit_GetCharPosFromXY($hWnd, $iX, $iY)
	Local $aiRect = _GUICtrlRichEdit_GetRECT($hWnd)
	If $iX < $aiRect[0] Or $iX > $aiRect[2] Or $iY < $aiRect[1] Or $iY > $aiRect[3] Then Return -1
	Local $tPointL = DllStructCreate("LONG x; LONG y;")
	DllStructSetData($tPointL, 1, $iX)
	DllStructSetData($tPointL, 2, $iY)
	Local $iRet = _SendMessage($hWnd, $EM_CHARFROMPOS, 0, $tPointL, 0, "wparam", "struct*")
	If Not $iRet Then Return SetError(-1, 0, 0)
	Return $iRet
EndFunc

Func _GUICtrlRichEdit_GetRECT($hWnd)
	Local $tRECT = DllStructCreate($tagRECT)
	_SendMessage($hWnd, $EM_GETRECT, 0, $tRECT, 0, "wparam", "struct*")
	Local $aiRect[4]
	$aiRect[0] = DllStructGetData($tRECT, "Left")
	$aiRect[1] = DllStructGetData($tRECT, "Top")
	$aiRect[2] = DllStructGetData($tRECT, "Right")
	$aiRect[3] = DllStructGetData($tRECT, "Bottom")
	Return $aiRect
EndFunc
Кстати, эта функция возвращает номер 1-й видимой строки и не важно какие X и Y заданы...
-----------
Для обычного Edit достаточно

Code: Select all

Func _GUICtrlEdit_CharFromPos($hWnd, $iX, $iY)
	If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
	Local $aReturn[2]
	Local $iRet = _SendMessage($hWnd, $EM_CHARFROMPOS, 0, _WinAPI_MakeLong($iX, $iY))
	$aReturn[0] = _WinAPI_LoWord($iRet)
	$aReturn[1] = _WinAPI_HiWord($iRet)
	Return $aReturn
EndFunc

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Andrey_A_A

In JScript:

Code: Select all

WScript.Echo("AEM_CHARFROMPOS: " + AEM_CHARFROMPOS() + "\n" + "EM_CHARFROMPOS: " + EM_CHARFROMPOS());

function AEM_CHARFROMPOS()
{
  var oSys     = AkelPad.SystemFunction();
  var lpPoint  = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
  var lpIndex  = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var hWndEdit = AkelPad.GetEditWnd();
  var nOffset;

  oSys.Call("User32::GetCursorPos", lpPoint);
  oSys.Call("User32::ScreenToClient", hWndEdit, lpPoint);

  if (AkelPad.SendMessage(hWndEdit, 3175 /*AEM_CHARFROMPOS*/, lpPoint, lpIndex) == 0 /*AEPC_ERROR*/)
    nOffset = -1;
  else
    nOffset = AkelPad.SendMessage(hWndEdit, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);

  AkelPad.MemFree(lpPoint);
  AkelPad.MemFree(lpIndex);

  return nOffset;
}

function EM_CHARFROMPOS()
{
  var oSys     = AkelPad.SystemFunction();
  var lpPoint  = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
  var hWndEdit = AkelPad.GetEditWnd();
  var nOffset;

  oSys.Call("User32::GetCursorPos", lpPoint);
  oSys.Call("User32::ScreenToClient", hWndEdit, lpPoint);

  nOffset = AkelPad.SendMessage(hWndEdit, 0x00D7 /*EM_CHARFROMPOS*/, 0, lpPoint);

  AkelPad.MemFree(lpPoint);

  return nOffset;
}

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

KDJ, спасибо, в AkelPad это работает, но к сожалению при внешнем вызове результата нет. Надеюсь найдётся решение... Может кто знает как это выглядет на Autoit

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Andrey_A_A wrote:

Code: Select all

Func _GUICtrlRichEdit_GetCharPosFromXY($hWnd, $iX, $iY)
	Local $aiRect = _GUICtrlRichEdit_GetRECT($hWnd)
	If $iX < $aiRect[0] Or $iX > $aiRect[2] Or $iY < $aiRect[1] Or $iY > $aiRect[3] Then Return -1
	Local $tPointL = DllStructCreate("LONG x; LONG y;")
	DllStructSetData($tPointL, 1, $iX)
	DllStructSetData($tPointL, 2, $iY)
	Local $iRet = _SendMessage($hWnd, $EM_CHARFROMPOS, 0, $tPointL, 0, "wparam", "struct*")
	If Not $iRet Then Return SetError(-1, 0, 0)
	Return $iRet
EndFunc
I do not know AutoIt but it seems to me that this is the solution.
You just have to pass to this function the handle to AkelEdit control ($hWnd).
You need to find the handle to this control.
Default class name for AkelEdit is "AkelEditW".
If you set in AkelPad the manual parameter RichEditClass to 1, class name will be "RichEdit20W".
Post Reply