Jump to content

Get text (word) under the mouse pointer


Go to solution Solved by PhoenixXL,

Recommended Posts

Posted (edited)

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.

Posted

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.

Posted

rename it to WinAPI.au3

 

Working great, thanks! By saying "To detect mouse pressed you have to subclass the control, using the native $GUI_EVENT_PRIMARYDOWN caused lag problems.", did you mean _IsPressed("01") caused a lag?

Posted

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.

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
  • Recently Browsing   0 members

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