Jump to content

Get text (word) under the mouse pointer


Go to solution Solved by PhoenixXL,

Recommended Posts

Malkey,

Using spaces to complete the aim is truly awesome. Brilliant. :)

michaelslamet,

To detect mouse pressed you have to subclass the control, using the native $GUI_EVENT_PRIMARYDOWN caused lag problems.

Here is the final script

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIEdit.au3>
#include <WinAPI.au3>

; Register callback function and obtain handle to _New_WndProc
Global $___hNew_WndProc = DllCallbackRegister("_New_WndProc", "int", "hwnd;uint;wparam;lparam")
; Get pointer to _New_WndProc
Global $___pNew_WndProc = DllCallbackGetPtr($___hNew_WndProc)

Global $hEdit ; Handle of the Edit
Global $___pOld_WndProc ; Old Window Procedure's Address

Example()

Func Example()

    ; Create GUI
    GUICreate("Edit Char From Pos", 400, 200, -1, -1)
    GUICtrlCreateEdit("Kc and Kp are the equilibrium constants of gaseous mixtures." & @CRLF & @CRLF & _
            "However, the difference between the two constants is that Kc is defined by molar concentrations," & @CRLF & @CRLF & _
            "whereas Kp is defined by the partial pressures of the gasses inside a closed system." & @CRLF & @CRLF & _
            "The equilibrium constants do not include the concentrations of single components such as liquids and solid, and they do not have any units.", 2, 2, 394, 170, 0)

    If StringRegExp(GUICtrlRead(-1), "\v+$") = 0 Then GUICtrlSetData(-1, GUICtrlRead(-1) & @CRLF)
    GUICtrlSetData(-1, StringRegExpReplace(GUICtrlRead(-1), "(\V)(\v)", "\1 \2"))

    $hEdit = GUICtrlGetHandle(-1)
    $___pOld_WndProc = _SubClass($hEdit, $___pNew_WndProc) ;store the old WndProc
    OnAutoItExitRegister("OnExit")

    GUISetState(@SW_SHOW)

    Do
        Sleep(10)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()
EndFunc   ;==>Example


;malkey made a better function
Func Hover_WordDetect() ;by malkey
    Local $aCharPos = _GUICtrlEdit_CharFromPos($hEdit, _WinAPI_GetMousePosX(True, $hEdit), _WinAPI_GetMousePosY(True, $hEdit))
    Local Const $sLine = _GUICtrlEdit_GetLine($hEdit, $aCharPos[1])
    $aCharPos[0] -= _GUICtrlEdit_LineIndex($hEdit, $aCharPos[1])
    If StringMid($sLine, $aCharPos[0] + 1, 1) == " " Then Return Null
    Return StringRegExpReplace($sLine, "(?s)^.{0," & $aCharPos[0] & "}(?: |^)([^ ]*).*$", "\1")
EndFunc   ;==>Hover_WordDetect



Func _SubClass($hWnd, $pNew_WindowProc)
    Local $iRes = _WinAPI_SetWindowLong ($hWnd, -4, $pNew_WindowProc)
    If @error Then Return SetError(1, 0, 0)
    If $iRes = 0 Then Return SetError(1, 0, 0)
    Return SetError(0, 0, $iRes)
EndFunc   ;==>_SubClass

;The new window procedure of the edit control.
Func _New_WndProc($hWnd, $iMsg, $wParam, $lParam)

    Switch $iMsg

        Case $WM_LBUTTONDOWN

            Local $Text = Hover_WordDetect()
            If $Text Then ConsoleWrite("Clicked : " & $Text & @CRLF)

        Case $WM_MOUSEMOVE
            ToolTip(Hover_WordDetect())
            Return 0    ;don't post message to the gui

    EndSwitch

    ; Pass to the Original Window Procedure.
    Return _WinAPI_CallWindowProc($___pOld_WndProc, $hWnd, $iMsg, _
            $wParam, $lParam)
EndFunc   ;==>_New_WndProc

Func OnExit();Mem Release

    ;unsubclass the control
    _SubClass($hEdit, $___pOld_WndProc)
    DllCallbackFree($___hNew_WndProc)

EndFunc   ;==>OnExit


;the following functions now don't have any use but for future reference(or backup) I'm posting them
;The no. of pixels to negotiate in case the mouse is over blank space
Func Hover_WordDetect_($XPrecision = -1, $YPrecision = -1) ;by phoenix XL

    Local $aCharPos[2], $iMousePos[2] = [_WinAPI_GetMousePosX(True, $hEdit), _WinAPI_GetMousePosY(True, $hEdit)]

    Static Local $iXPrecision = GetLineDimension($hEdit, 1), $iYPrecision = GetLineDimension($hEdit, 2)

    $aCharPos = _GUICtrlEdit_CharFromPos($hEdit, $iMousePos[0], $iMousePos[1])

    ;lets check if its blank space
    Local $aRealPos = _GUICtrlEdit_PosFromChar($hEdit, $aCharPos[0])
;~  _ArrayDisplay($iMousePos)
;~  _ArrayDisplay($aRealPos)

    If $XPrecision <> -1 Then $iXPrecision = $XPrecision
    If $YPrecision <> -1 Then $iYPrecision = $YPrecision

;~  ConsoleWrite($iXPrecision & @CRLF)
;~  ConsoleWrite($iYPrecision & @CRLF)

    Switch $aRealPos[0]
        Case $iMousePos[0] - $iXPrecision To $iMousePos[0] + $iXPrecision
            ;if we reach here then X-Coord is inside precision
            ;lets check Y-Coord
            Switch $aRealPos[1]
                Case $iMousePos[1] - $iYPrecision To $iMousePos[1] + $iYPrecision ; ==> All good
                Case Else
                    Return ""
            EndSwitch
        Case Else
            Return ""
    EndSwitch

    Local Const $sLine = _GUICtrlEdit_GetLine($hEdit, $aCharPos[1])
    $aCharPos[0] -= _GUICtrlEdit_LineIndex($hEdit, $aCharPos[1])

    Local $aWords = StringSplit($sLine, " "), $iCount = 0
    For $i = 1 To $aWords[0]
        Switch $aCharPos[0]
            Case $iCount To $iCount + StringLen($aWords[$i])

;~              ConsoleWrite($aWords[$i] & @CRLF)
                Return $aWords[$i]

            Case Else

;~              ConsoleWrite("From: " & $iCount & " to: " & $iCount + StringLen($aWords[$i]) & @TAB & $aCharPos[0] & @CRLF)
                $iCount += StringLen($aWords[$i]) + 1
        EndSwitch
    Next

;~  ConsoleWrite("" & @CRLF)
    Return ""

EndFunc   ;==>Hover_WordDetect_

Func GetLineDimension($hEdit, $iDimension) ;$iDimension : 1 - width, 2 - height
    ; Create DC
    $hDC = _WinAPI_GetDC($hEdit)
    $hFont = _SendMessage($hEdit, $WM_GETFONT) ; $WM_GetFont
    $hPrev_Font = _WinAPI_SelectObject($hDC, $hFont)

    Local $tSize = DllStructCreate("int;int")

    DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", "¤", "int", 1, "ptr", DllStructGetPtr($tSize))

    _WinAPI_SelectObject($hDC, $hPrev_Font)
    _WinAPI_ReleaseDC($hEdit, $hDC)

    Return DllStructGetData($tSize, $iDimension)
EndFunc   ;==>GetLineDimension 

Regards :)

Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

rename it to WinAPI.au3

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

No, I meant there might be lag issues when using the following code.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIEdit.au3>
#include <WinAPI.au3>

Global $hEdit ; Handle of the Edit

Example()

Func Example()

    ; Create GUI
    GUICreate("Edit Char From Pos", 400, 200, -1, -1)
    GUICtrlCreateEdit("Kc and Kp are the equilibrium constants of gaseous mixtures." & @CRLF & @CRLF & _
            "However, the difference between the two constants is that Kc is defined by molar concentrations," & @CRLF & @CRLF & _
            "whereas Kp is defined by the partial pressures of the gasses inside a closed system." & @CRLF & @CRLF & _
            "The equilibrium constants do not include the concentrations of single components such as liquids and solid, and they do not have any units.", 2, 2, 394, 170, 0)

    If StringRegExp(GUICtrlRead(-1), "\v+$") = 0 Then GUICtrlSetData(-1, GUICtrlRead(-1) & @CRLF)
    GUICtrlSetData(-1, StringRegExpReplace(GUICtrlRead(-1), "(\V)(\v)", "\1 \2"))

    $hEdit = GUICtrlGetHandle(-1)

    GUISetState(@SW_SHOW)

    Local $s
    Do
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $GUI_EVENT_PRIMARYDOWN
                $s = Hover_WordDetect()
                If $s Then ConsoleWrite("Clicked: " & $s & @CRLF)

            Case $GUI_EVENT_MOUSEMOVE
                ToolTip(Hover_WordDetect())
        EndSwitch

    Until 0

    GUIDelete()
EndFunc   ;==>Example


;malkey made a better function
Func Hover_WordDetect() ;by malkey
    Local $aCharPos = _GUICtrlEdit_CharFromPos($hEdit, _WinAPI_GetMousePosX(True, $hEdit), _WinAPI_GetMousePosY(True, $hEdit))
    Local Const $sLine = _GUICtrlEdit_GetLine($hEdit, $aCharPos[1])
    $aCharPos[0] -= _GUICtrlEdit_LineIndex($hEdit, $aCharPos[1])
    If StringMid($sLine, $aCharPos[0] + 1, 1) == " " Then Return Null
    Return StringRegExpReplace($sLine, "(?s)^.{0," & $aCharPos[0] & "}(?: |^)([^ ]*).*$", "\1")
EndFunc   ;==>Hover_WordDetect

Regards :)

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...