Carlet 읽기 -winapi 이용
#include <WinAPI.au3>
#include <SendMessage.au3>
#include <GuiEdit.au3>
; ====== 메시지 상수 정의 ======
;~ Global Const $EM_GETSEL = 0x00B0
;~ Global Const $EM_LINEFROMCHAR = 0x00C9
;~ Global Const $EM_LINEINDEX = 0x00BB
;~ Global Const $EM_LINELENGTH = 0x00C1
; ====== 핫키 등록 (Ctrl+Shift+R : 캐럿 텍스트 읽기) ======
HotKeySet("^+r", "ReadCaretText")
ConsoleWrite("아무 편집창에서나 커서를 원하는 위치에 두신 후 Ctrl+Shift+R을 눌러주세요." & @CRLF)
ConsoleWrite("종료하려면 Ctrl+Shift+X를 누르세요." & @CRLF)
HotKeySet("^+x", "_Exit")
While 1
Sleep(100)
WEnd
Func _Exit()
Exit
EndFunc
; ====== 캐럿 위치 텍스트 읽기 메인 함수 ======
Func ReadCaretText()
; 1. 현재 활성(최상위) 윈도우 핸들
Local $hWin = WinGetHandle("[ACTIVE]")
If @error Or $hWin = 0 Then
MsgBox(16, "오류", "활성 윈도우를 찾을 수 없습니다.")
Return
EndIf
; 2. 캐럿(키보드 포커스)이 위치한 실제 컨트롤 핸들 구하기 (다른 프로세스도 지원)
Local $hEdit = _GetFocusedControlHandle()
If $hEdit = 0 Then
MsgBox(16, "오류", "포커스된 컨트롤을 찾을 수 없습니다.")
Return
EndIf
; 3. 현재 캐럿(커서) 위치 가져오기 - EM_GETSEL
Local $iResult = _SendMessage($hEdit, $EM_GETSEL, 0, 0, 0, "int", "int", "int")
Local $iCaretPos = BitAND($iResult, 0xFFFF) ; LOWORD 추출 = 캐럿 위치
; 4. 캐럿이 위치한 줄 번호 확인
Local $iLineIndex = _SendMessage($hEdit, $EM_LINEFROMCHAR, $iCaretPos, 0)
; 5. 해당 줄의 시작 문자 위치(offset) 확인
Local $iLineStart = _SendMessage($hEdit, $EM_LINEINDEX, $iLineIndex, 0)
; 6. 해당 줄의 길이 확인
Local $iLineLength = _SendMessage($hEdit, $EM_LINELENGTH, $iLineStart, 0)
; 7. 전체 텍스트를 가져와서 해당 줄만 추출
Local $sFullText = ControlGetText($hWin, "", $hEdit)
Local $sLineText = StringMid($sFullText, $iLineStart + 1, $iLineLength)
; 8. 현재 단어도 함께 추출
Local $sWord = GetWordAtPosition($sFullText, $iCaretPos)
; 결과 출력
ConsoleWrite("=== 캐럿 위치 정보 ===" & @CRLF)
ConsoleWrite("윈도우 핸들: " & $hWin & @CRLF)
ConsoleWrite("컨트롤 핸들: " & $hEdit & @CRLF)
ConsoleWrite("줄 번호: " & ($iLineIndex + 1) & @CRLF)
ConsoleWrite("캐럿 위치(전체 기준): " & $iCaretPos & @CRLF)
ConsoleWrite("현재 줄 텍스트: " & $sLineText & @CRLF)
ConsoleWrite("현재 단어: " & $sWord & @CRLF)
ConsoleWrite("=====================" & @CRLF & @CRLF)
; 툴팁으로도 표시
ToolTip("줄: " & $sLineText & @CRLF & "단어: " & $sWord, MouseGetPos(0), MouseGetPos(1) - 60)
Sleep(2000)
ToolTip("")
EndFunc
; ====== 캐럿(키보드 포커스)이 위치한 실제 컨트롤 핸들 구하기 ======
; GetGUIThreadInfo API는 다른 프로세스의 스레드 정보도 가져올 수 있어서
; 활성 프로그램이 메모장이 아니어도 동작합니다.
Func _GetFocusedControlHandle()
Local $hActive = _WinAPI_GetForegroundWindow()
If @error Or $hActive = 0 Then Return 0
Local $aCall = DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hActive, "ptr", 0)
If @error Then Return 0
Local $iThreadId = $aCall[0]
Local $tGUI = DllStructCreate( _
"dword cbSize;" & _
"dword flags;" & _
"hwnd hwndActive;" & _
"hwnd hwndFocus;" & _
"hwnd hwndCapture;" & _
"hwnd hwndMenuOwner;" & _
"hwnd hwndMoveSize;" & _
"hwnd hwndCaret;" & _
"long left;long top;long right;long bottom")
DllStructSetData($tGUI, "cbSize", DllStructGetSize($tGUI))
Local $aResult = DllCall("user32.dll", "bool", "GetGUIThreadInfo", _
"dword", $iThreadId, "ptr", DllStructGetPtr($tGUI))
If @error Or Not $aResult[0] Then Return 0
Local $hFocus = DllStructGetData($tGUI, "hwndFocus")
If $hFocus = 0 Then $hFocus = $hActive ; 포커스 정보가 없으면 활성 윈도우 자체를 사용
Return $hFocus
EndFunc
; ====== 특정 위치의 단어 추출 함수 ======
Func GetWordAtPosition($sText, $iPos)
Local $iStart = $iPos
Local $iEnd = $iPos
While $iStart > 0
Local $sChar = StringMid($sText, $iStart, 1)
If $sChar = " " Or $sChar = @CR Or $sChar = @LF Or $sChar = @TAB Then
ExitLoop
EndIf
$iStart -= 1
WEnd
While $iEnd < StringLen($sText)
Local $sChar = StringMid($sText, $iEnd + 1, 1)
If $sChar = " " Or $sChar = @CR Or $sChar = @LF Or $sChar = @TAB Then
ExitLoop
EndIf
$iEnd += 1
WEnd
Return StringMid($sText, $iStart + 1, $iEnd - $iStart)
EndFunc